Blueprint "event begin play" called before C++ parent's "event begin play"?

  1. Create a custom game mode class in C++ (derive from AGameMode)
  2. Implement Begin Play for this class and print a test string
  3. Create a blueprint subclassing the C++, set this as the default game mode for your map.
  4. In the blueprint implement the ‘begin play’ node and right click, ‘add call to parent’ to add a ‘parent:begin play’ node.
  5. Hook the ‘parent:begin play’ node to a print string node printing a dummy string

When you play the level you’ll find that the print string of the blueprint’s “event begin play” gets called before the print string in the parent C++ class’s “begin play” which seems wrong.

Is this a bug or expected behavior? Does Parent:Begin Play in a blueprint only work if the parent is also a blueprint?

Hi VSZ,

I tried to reproduce this issue, and the results I saw were different from what you described. Let me tell you what I did, and if you can point out where you are doing things differently, that would help.

  • Create a new code project using the First Person template.

  • Build the project in Visual Studio.

  • Open the project in the Editor.

  • Add a new code class to the project derived from GameMode.

  • Close the Editor.

  • Override BeginPlay() in the new code class with the following code:

    if (GEngine)
    {
    GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT(“Code Begin Play”));
    }

  • Open the project in the Editor.

  • Create a Blueprint from my custom GameMode class.

  • In the Blueprint Event Graph, set an Event Begin Play node and connect it to a Print String node.

  • Set the new Blueprint as the project’s GameMode.

  • Start PIE.

What I was seeing is that the message from the code class is displayed, but the Event Begin Play node in the Event Graph was apparently not being triggered.

If you could also answer a few additional questions, that would be helpful.

  • What version of the Engine are you using?
  • Are you using the binary version installed by the Launcher, or did you build the Engine from source code?
  • Does this happen in a brand new project as well, or only in your own project?

Tim

  • I’m currently using 4.5.1 although I think I tried it on 4.6 preview as well, it’s been a while so I don’t recollect to be honest
  • I was using the binary version
  • I haven’t tried reproducing it in a brand new project yet. Don’t think I have the time to test in the next few days but I’ll try to get back with a repro in the coming week or so.

Not sure if you see different results when you right click and add the call to parent: begin play?

I just took another look at this issue using the binary 4.5.1 Editor (I had previously been using 4.6.1), and I ended up seeing the same results that I was seeing previously. When you get a chance, would you be able to provide the code you are using in the BeginPlay function of your base class and a screenshot of how you have your GameMode Blueprint set up?

Hi Tim, my project has changed quite a bit since I posted this bug and I don’t think I have an exact copy of the code I used to reproduce this earlier. I will try setting up the same behavior again and post back my results. Apologies for the late reply, I’ve been swamped with some other work lately.

Hi VSZ,

I completely understand about being swamped. If you happen to run into this issue again, or are able to narrow it down further, please let us know about any additional information you may come across. I will be marking this issue as resolved for tracking purposes, but please feel free to re-open it at any time.

Tim

Hi Tim,

I have the same problem. The Blueprint BeginPlay function is called before its C++ parent.
30366-

30368-pie_view.jpg

I am using 4.7 Preview 8.

Timbo

Hi Timbo,

Thank you for the additional information you provided. With your assistance, I was able to reproduce this issue. I submitted a report about this to have it investigated further (UE-10138).

Tim

Thanks Tim

Hey Guys,

The blueprint implementation of BeginPlay (AActor::ReceiveBeginPlay) is called from native code in AActor::BeginPlay().

If you want to call Blueprint implementation after the custom native code:

void AQATestActor::BeginPlay()
{
	TestNumber = 3.f;
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Cyan, FString::SanitizeFloat(TestNumber));

	Super::BeginPlay();
}

Cheers,
M

Hey Guys,

The blueprint implementation of BeginPlay (AActor::ReceiveBeginPlay) is called from native code in AActor::BeginPlay().

If you want to call Blueprint implementation after the custom native code:

void AQATestActor::BeginPlay()
{
	TestNumber = 3.f;
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Cyan, FString::SanitizeFloat(TestNumber));

	Super::BeginPlay();
}

Cheers,
M

Thanks for this answer! Perfect timing, as I am just about to start implementing something that this issue would have affected. :slight_smile:

So the “Parent: Begin Play” blueprint node is actually a no-op in this case?

To me it seems that this behavior is a bit counter-intuitive and feels like going against what is standard in object-oriented programming (execution starts from the child’s overriding implementation, which is then responsible for calling the parent’s implementation). Of course, this is how it has to be in this case, but I think it would be good to document this behavior somewhere? Maybe here:

Exposing Gameplay Elements to Blueprints Visual Scripting in Unreal Engine | Unreal Engine Documentation → BlueprintNativeEvent

“Parent: Begin Play” blueprint node calls the Super if the parent blueprint.
It has to do only with blueprints

https://answers.unrealengine.com/questions/77597/child-tick-event-cancels-parent-tick-event.html

Hi Plosnita,

You are correct. The Parent: Begin Play node calls the Begin Play event of a parent Blueprint. The Begin Play function for a code class parent is always called.

Tim

IMO, in the scenario of BeginPlay, taking the parent CPP class as the blueprint’s actual class is more reasonable, and easy to understand. I think UE has some internal mechanical especially code generated by UHT.