Explaining components initialization functions flow..

I set up a component that debugs all the constructor/functions and I found that when I place an actor blueprint that has this component in an empty world and hit the PIE button (Standalone) I get this log:


UAPLogExecutionOrderComponent(Constructor) [Default__APLogExecutionOrderComponent] :
PostInitProperties [Default__APLogExecutionOrderComponent] :


- Game Engine Initialized.
- Starting Game.

UAPLogExecutionOrderComponent(Constructor) [APLogExecutionOrder_GEN_VARIABLE] :
PostInitProperties [APLogExecutionOrder_GEN_VARIABLE] :
UAPLogExecutionOrderComponent(Constructor) [APLogExecutionOrder] :
PostInitProperties [APLogExecutionOrder] :
PostLoad [APLogExecutionOrder_GEN_VARIABLE] :
PostLoad [APLogExecutionOrder] :


OnRegister [APLogExecutionOrder] :
OnUnregister [APLogExecutionOrder] :
OnComponentDestroyed [APLogExecutionOrder] :
UAPLogExecutionOrderComponent(Constructor) [APLogExecutionOrder] :
PostInitProperties [APLogExecutionOrder] :
PostLoad [APLogExecutionOrder] :
OnComponentCreated [APLogExecutionOrder] :
OnRegister [APLogExecutionOrder] :
OnUnregister [APLogExecutionOrder] :
OnRegister [APLogExecutionOrder] :
InitializeComponent [APLogExecutionOrder] :

TickComponent [APLogExecutionOrder] :
TickComponent [APLogExecutionOrder] :
TickComponent [APLogExecutionOrder] :
etc...



First of all the [Default__APLogExecutionOrderComponent] instance is created, what is this exactly? Is the master copy of the component?

Then after the engine is initialized a [APLogExecutionOrder_GEN_VARIABLE] is created. What is this GEN_VARIABLE instance exactly?
Then a [APLogExecutionOrder] instance is created (I think this is the one that will be attached to the actor).

Then you can see a lot of register/unregister/Destruction and ANOTHER construction of [APLogExecutionOrder] :S. Why? I don’t understand this flow… very confusing and I can’t find documentation about component functions flow exactly…

Anyone can explain me all those questions please?

When you create a BP class you usually get:

Archetype Class - this is a “skeleton” of your C++ Class + Generated Code (Unreal’s Reflection System)
Default Object - this is the “generated class” the engine creates every time you run it, there’s always a “Class Default Object” or “CDO”; This is where you’ll see “GEN_VARIABLE” thingies.
Instanced Object - this will “spawn” in game world and copy default values from CDO once created (expose on spawn stuff, etc).

So the code you’ve created there is actually running on at least three places at same time.
You can easily check which “version” of your object you’re dealing with using something like:



MyObject->HasAnyFlags( RF_ClassDefaultObject | RF_ArchetypeObject );


If that is *true *that means the code isn’t running on an actual instance of an object spawned in the game world.

2 Likes

Wow thank you! Now all makes more sense.

But, what about this part?


OnRegister [APLogExecutionOrder] :
OnUnregister [APLogExecutionOrder] :
OnComponentDestroyed [APLogExecutionOrder] :
UAPLogExecutionOrderComponent(Constructor) [APLogExecutionOrder] :
PostInitProperties [APLogExecutionOrder] :
PostLoad [APLogExecutionOrder] :
OnComponentCreated [APLogExecutionOrder] :
OnRegister [APLogExecutionOrder] :
OnUnregister [APLogExecutionOrder] :
OnRegister [APLogExecutionOrder] :
InitializeComponent [APLogExecutionOrder] :





Why the register/unregister/destruction and another construction and again onregister/unregister/onregister before the initializeComponent? (I assume that this is the Instanced Object) I will have to check the flags.

Also, just one more thing:

Since you can create instances of objects outside any game world, you can as well query its package to check if:



MyObject->GetOutermost()->ContainsMap();


or:



MyObject->GetWorld() && MyObject->GetWorld()->IsGameWorld();


What about my last post Bruno Xavier? Why the destruction and reconstruction ? Thank you :smiley:

The Editor create/destroy objects when initializing Worlds… Some object might be created, but is referenced by nothing then it’s GCed.
And Editor might initialize Worlds multiple times, depends on the tools you’re using to place actors, edit an asset, etc.

Usually you will see PostLoad() called only once on every Editor startup, but PostInitProperties() will be called on Editor launch and also execute every time you click the “Play()” button and on packaged game.
(because the ‘CDO’ will always be created on Editor launch and its Constructor is executed every time for each class)

2 Likes

Aha, but why the constructor is called multiple times? I though that the constructor is ONLY called in editor/game startup to create the CDO (GEN_VARIABLE) but as you can see here is called more than one time… why? I don’t understand then what exactly is the CDO if the constructor is called for every instanced object…

Every instances will have Constructor and Construction Script called, yes.

Didn’t see it mentioned, but is the “content browser preview” construction of classes sent to the general log as well? Or is that editor preview created by some different method?

If your Blueprint Class is a regular, common, Blueprint… then what you see on Content Browser are “packages” containing the “Class Default Object”.
Their Constructors are called during that little %0-100% loading splashscreen before the Editor opens in full.
(yes they will run the Constructor function and output those logs too)

However it’s possible to create assets containing UObjects that are not Blueprint Generated Classes in anyway, so that may vary by a lot, depends on the class.

1 Like

Then, if the constructor is always called for each instance, which is the purpose of the CDO exactly ?

And, Constructor and construction script?
What is the construction script in a component and in an actor in c++?

sorry but trying to understand it all…:stuck_out_tongue:

Without a CDO there is no way for the engine to create instances of the Class.
Your C++ Class is precompiled into that generated Class, then spawned instances are copies of it.
When you package a game, your C++ code doesn’t exist anymore; so a precompiled CDO is needed for each Class where instances will copy default values from.

Epic added to Blueprints that special graph that executes when new class instance spawned (trying to emulate C++ Class Constructor).

Internally Unreal executes a call to that graph once “SpawnActor” routine was successful for that instance;
Behind the scenes that graph is a Function Graph. Function Graphs are Objects auto generated and attached to your Blueprint Class that don’t really exist in the C++ version of your Class… So you can add functions to Blueprints using the Blueprint Editor while your C++ Class has no idea at all that such function exist on the Generated Class (Blueprint Object).

1 Like