When to use OnRegister versus other Component lifecycle functions (Also Actor Lifecycle)

I haven’t been able to find a clear explanation of an actor component’s lifecycle. Knowing which functions to override would really help understand where to do things correctly.

OnRegister seems to get called even when you modify an actor a little in the editor, like moving it, or changing a few properties. I noticed some negative side effects of doing things in OnRegister, like if I create other components in OnRegister, my actor might have all of those copies of components become part of its instance in the level.

There are other functions like Initialize. I noticed Movement components use this to find the component to control. This gets run if bWantsToInitialize is set.

Then there’s BeginPlay. I sometimes used to just move things to BeginPlay if I noticed it caused issues in OnRegister.

However if you don’t put things in OnRegister, it sometimes looks wrong when you place the actor or component in the world, until the game starts.

For example, if I have a property defining some collision radius in my actor, if I put code in BeginPlay to update a collision sphere’s radius, it’s hard to visualize in the editor what that collision’s radius is.

Then there’s also the ConstructionScript which seems to work similarly to OnRegister.

I’m just not 100% sure when to use what. Sometimes things like OnRegister and the construction script run when I don’t expect it and it breaks my objects in the level, but doing everything in BeginPlay makes it hard to see things correctly updated when I’m using the editor.

This comment describes some of the functions called during initialization and when/if they will be called in editor or not: https://github.com/EpicGames/UnrealEngine/blob/c3caf7b6bf12ae4c8e09b606f10a09776b4d1f38/Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h#L101

For things like visualization components OnRegister can also be used it seems. According to Components | Unreal Engine Documentation the trick is to remember the created component #if WITH_EDITORONLY_DATA UPROPERTY(...) ... #endif and check that against nullptr before creating a new one to avoid adding multiple instances.

I have to agree though that it’s not trivial to find the appropriate initialization function simply because there are so many different ones and each one is called or not called in different situations and some can occur repeatedly.

1 Like

The Unreal Engine Game Framework: From int main() to BeginPlay

1 Like

Oh that visualization component doc looks good to know. I’ve also had instances of UObjects becoming permanently a part of an instance of an actor in a level since I did some creation in OnRegister. And every time OnRegister was called, it created a new instance while keeping an old instance. And since my UPROPERTY that kept track of those instances was a Set, my set just kept growing. And that wasn’t even a visualization component. I basically realized I should definitely not be doing something like that in OnRegister but BeginPlay or InitializeComponent seemed good. The only fix was to delete my object and create a new one after I fixed the C++ code. It’s actually not obvious from the docs when OnRegister is called, so even moving an object with transform gizmo’s seems to call OnRegister.

The from main() to BeginPlay video was very useful too. I watched it long ago actually. I don’t remember if it goes into what happens in the editor, I may have to give that another watch.

BeginPlay is almost always the worst place to do actor/component self-initialization. This becomes more of an issue in Multiplayer or games where you have customised the gameplay frameworks’ “match-based” workflow.

OnRegister for components that need to initialize themselves, and use PostInitializeComponents at the actor level is the best mixture I find.

5 Likes