Function to call after all actor's "begin play"

I need to call something after all actors of my level were completely initiated (after the call of BeginPlay of each one), to do some final verifications and check some overlaps. But the docs about the UE4 lifecycle are very not detailed at all and I have no idea how to do that. I don’t know if I can use the game mode for this, because I don’t even know if the BeginPlay of the game mode is fired before or after the other actors.

Is it possible to do that? If yes, how can I do?

Please, I can’t use solutions like “use the delay node”, it seems a very bad practice.

Doesn’t matter if Blueprint or C++, I can work with both.

We use GetStreamingLevel and IsLevelVisible in a blueprint delay loop, wait for all pending streaming levels to return true, then call our own callback.

The LoadStreamLevel node itself is a latent action that will execute it’s “completed” node when the level is done streaming.

There are some delegates on the ULevelStreaming base object itself you could investigate.

Each level’s OnBeginPlay should fire after all of the actor’s loaded with it are initialized (this includes if you are not using streaming at all, or any initial-loaded child levels that will be BeginPlay-ed before the persistent level)

Adding networking (clients, dedicated server, etc) will add some complexity to the initialization timing, and you’ll need to deal with the startup and connecting player pawns and controllers carefully.

1 Like

Uhmm, I think the level’s OnBeginPlay worked (I’m not using networking nor level streaming, my setup is very simple). It’s not the best because I have to replicate the same code on all my levels, but I can encapsulate all I need inside a function and just call it, so it’s not a big deal. Thank you.

I know the original poster already came up with a solution, but for anyone else that stumbles upon needing a way to do this, another possible way to do this in code is to perform what you need to do once on the first tick. It’s not as clean as placing it within something analogous to UE3’s PostBeginPlay( ) but it would work.

in constructor:
bDidMyFirstTickStuff = false;

Tick(float delta)
{
     if (false == bDidMyFirstTickStuff)
     {
          do my first tick stuff
          bDidMyFirstTickStuff = true;
          possibly disable tick if no longer needed
     }
}

Can also subscribe to UWorld->OnWorldBeginPlay in your actor/component begin play where you need to be notified . Looking through source code for UWorld::BeginPlay this is called after all actor’s BeginPlays are called. Actor BeginPlay is dispatched down the chain from the AGameMode->StartPlay call.

See also Unreal Engine Actor Lifecycle | Unreal Engine 5.0 Documentation

and Order of events while starting the game | Unreal Engine Community Wiki

e.g. within an actor or component:

GetWorld()->OnWorldBeginPlay.AddUObject(this, &ThisClass::Init);
4 Likes

There’s a blueprint node, and C++ functionality (GetWorldTimerManager()), to call a event/function next tick.

I’m not 100% sure that skipping till the next tick will allow all other actors to BeginPlay() but it fixed the issue for me.

My issue was that a level default actor was spawning a class that accessed the game state in its own BeginPlay(). It failed to get the game state, I think because it was spawned prior to the game state being created. Waiting that one tick, fixed it. [Now realized this was something else, but the next tick trick might still work for you]