Blueprint BeginPlay gets called before C++ parent BeginPlay

Hello,

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:

  1. Create blank C++ project.

  2. Create C++ class called A.

  3. Create C++ class called B that derives from A.

  4. Create BP class called C that derives from B.

  5. Properly generate implementations for the BeginPlay functions for each C++ class, and add a call to Super::BeginPlay at the start of each BeginPlay.

  6. After the Super::BeginPlay calls, add a UE_LOG message or OnScreenDebugMessage to see the order of execution for BeginPlays.

  7. Also add a UE_LOG message or OnScreenDebugMessage in the constructor of each of these classes to see the order of execution for constructors.

Results:

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?

Thank you.

Sounds right. Blueprint events are just one-off generated function calls, they don’t really have inheritance (despite the “super” calls). You shouldn’t really treat them like normal C++ objects. You will never be able to get the C, B, A order. Instead you should just do : A -> B, then C (called by B).

Let C++ set everything, then ask BP if it wants to override those settings (call this method from the child after the super calls).