AActor construction order crashes game

I have two actors in a level. One relies on the other one being initialized first. When I start a PIE session, I see that the constructor for Actor1 is called AND BeginPlay() for Actor1 is called before the same happens for Actor2. My game crashes because Actor1 tries to access memory in Actor2, which hasn’t been initialized yet.

How do I get around this? I understand the object lifecyle as described here: Actor Lifecycle | Unreal Engine Documentation

But I was expecting the engine to construct all objects in order, then call BeginPlay() on all actors in order, as well - so that I can get around problems like the one described above. What do I need to do instead?

You could try doing basic checks against the object and calling LoadObject otherwise.

// Check if the Actor is a null reference
if(Actor2 == nullptr) {
    // Call LoadObject to load the object into the game
    Actor2 = LoadObject<AActor>(nullptr, TEXT("/Path/To/Asset/ActorName.ActorName");
}

// If LoadObject was not enough to initialize the actor do it manually
if(!Actor2->IsActorInitialized()) {
    Actor2->PreInitializeComponents();
    Actor2->InitializeComponents();
    Actor2->PostInitializeComponents();
}

// Object should now be loaded and accessible.
Actor2->DoStuff();

Due to the initalizeComponents functions being part of the RouteActorInitialize routine used for seamless travel this methodology might interfere with the seamless travel functionality.

Thanks, checking against null sounds like a solution. I’d still love to find an approach that allows me to control the order in which objects are constructed/called, since the “check-against-null-and-do-lazy-instantiation” way sounds backwards for the situation I’m dealing with:

In my scene, I have a “manager” object that does a bunch of logic and can be polled for information, and I have components (attached to arbitrary actors) that talk to that manager to register themselves and get information. Those components are constructed first, and find a manager that isn’t initialized yet/ Now: of course the component could init the manager object when it first tries to access it. But it feels like the wrong way to do this. The manager is supposed to “own” the components, not the other way around.

I’m used to engine object initialization where all objects are pooled, all constructed, and then all objects in the pool call a function like BeginPlay() etc. That would solve the problem here, because the components, which do access the scene manager in BeginPlay() already, could rely on the fact that it’s been instantiated already. Doesn’t a pattern like this exist in Unreal Engine 4?

I have just analyzed ULevel::RouteActorInitialize() and perhaps you can but its a bit whack. The function begins by iterating through all actors and calling PreInitializeComponents(), the PreInitalizeComponents function is virtual void which allows you to override its functionality. So you could initialize the required actor in the override of the actor that requires it. This ensures it is initialized before RouteActorInitialize() continues calling Actor->DispatchBeginPlay().

I also highly recommend disabling ‘allow Tick before BeginPlay()’ in each of your levels its world settings as most programmers expect Tick(float DeltaSeconds) only to be called after BeginPlay() has finished.

Here is the complete RouteActorInitialize() function as of version 4.18.2

Gonna mark the original answer as correct, even if it’s not the perfect solution. Thanks everybody.

Thanks for checking!