First of all, I realize a duplicate post actually exists, but it has no answers that satisfy me and it dates back to 2014, therefore I am posting this question.
The BeginPlay event gets called in an odd fashion. The Blueprint’s BeginPlay actually gets called before the C++ parent’s BeginPlay, which is not what you would expect from an OOP point of view. The constructors are called in the expected order.
How to reproduce:
Create blank C++ project.
Create C++ class called A.
Create C++ class called B that derives from A.
Create BP class called C that derives from B.
Properly generate implementations for the BeginPlay functions for each C++ class, and add a call to Super::BeginPlay at the start of each BeginPlay.
After the Super::BeginPlay calls, add a UE_LOG message or OnScreenDebugMessage to see the order of execution for BeginPlays.
Also add a UE_LOG message or OnScreenDebugMessage in the constructor of each of these classes to see the order of execution for constructors.
Constructors will be called in this order: A, B, C
This is the expected result as the parent gets called first.
BeginPlay’s will be called in this order: C, A, B
This is not the expected result as the child gets called first, but then the rest are executed from parent to child. If we put the print messages before Super::BeginPlay calls, we get: B, A, C
No matter how we place the Super calls, we can never get A, B, C as the order of execution.
Why is this important?
Currently, it is impossible for us to make C properly override values from B and set them in BeginPlay. For example, imagine that class A sets the max walk speed of CharacterMovementComponent to 600 in BeginPlay. We can let B override that and set max walk speed to 300 in BeginPlay. But now, C can never override B or A. Is this intended behavior, and how can be overcome this issue?