BeginPlay/PostInitComponents for a component

Hi,

I hope there is somebody who can help me out with this.

Is there a “virtual UActorComponent::PostInitComponents()” which is being called for a component after all other components have been initialized ? Or is there a “virtual UActorComponent::BeginPlay()” which is being called for a component after the game has started ?

Those methods exist afaik only for the actor. There are no related component-methods?

What would be the correct way to initialize an own component after the game has started (and all other components have been initialized), without having to implement an own actor?

Thanks

Edit: Any reason why a pull request would not be accepted, if one implements this? I could try it…

Not sure i understand your qustion, do you want to create a new component for the actor at runtime?
Or are you looking to create a new component derived from a excisting component class?

AActor::PostInitializeComponents Override Hierarchy
I don`t think components have the same method but there are some PostInit methods for propertys and so 4th.
UActorComponent::PostInitProperties

There are no Component methods for PostInitComponents or BeginPlay. (PostInitComponents wouldn’t make sense anyway).

Your component is owned by an actor anyway right? (It has to be if you want to use it anywhere). Why not just create a custom function in your Component called ‘InitValues’ or similar, then during PostInitComponents in the actor, call ‘InitValues’ on the Component? That makes the most sense to me. You could do the same for BeginPlay if you wanted to.

EDIT: I’m wrong :wink:

Not if you want a standalone component to be used by many actors, such as a healthbar component or the likes.
The function I think you’re looking for is InitializeComponent(), which you can override in your custom component. Remember to tick the “Auto activate” tickbox in the components menu, also note that InitializeComponent() triggers in the editor also, so make sure you guard in-game pointer-variables.

4 Likes

Right, but it sounds like OP specifically wants to do initialization which has to come after all other components on the owning actor have had InitializeComponent() called. Presumably the component is making some assumption about the existence of another component, and needs it to be initialized before it can initialize itself.

OP, what’s your use case for this? I don’t think there is anything in place for what you’re asking, but maybe there’s a better way of going about things that wouldn’t require this.

Could possibly combine it with an interface if lots of actors are going to use it.

Hello,

sorry for the late reply. There were email notification issues.

To the topic:

I think that it would be more clean to have a corresponding UActorComponent::Foo method for each important AActor::Foo method being implemented and called at exactly the same time in code.
For AActor::BeginPlay there seems to be for example an UActorComponent::InitializeComponent.

The header says:

/**
 * Starts gameplay for this component.
 * Requires component to be registered, and bWantsInitializeComponent to be TRUE.
 */

So I would expect for example that every world-actor already exists during UActorComponent::InitializeComponent so that I am able to reference it.
Or I would like to spawn dependent actors in this method. Or like to initialize UMG Widgets.

Unfortunately I have always crashes If I am trying to do something of the above.

“Auto activate” is the same as setting “bWantsInitializeComponent” to be TRUE ?
If that is correct, I have afaik everything done to initialize the component correctly.

Some other notes:

I think UActorComponent::PostInitializeComponents would be more than nice to have, because there can be components which calculate properties from
properties which can reside in other components. Then the best place would be indeed UActorComponent::PostInitializeComponents.
As I do not want to always implement own actors or implement derived engine-components only for this functionality I wonder why they do not just exist in the component interface?

Is it because of performance reasons ? You could use something like UActorComponent::bWantPostInitializeComponents to avoid unnecessary calling.
It is because of some design guidelines ?

(E.g. forbid this functionality in order to force more intelligent derived actor implementations ? If this is the case, I think that it should be in the hand of the middleware user if he wants to use a flat list of combinable components defining an actor-type or deriving from an own actor-hierachy. I have used both and I think it stronly depends on the application/use-case)

I have now implemented and passed-through above methods for the components and have no problems at all :slight_smile:

Thanks for your opinions/clarifications

I have to agree I find the initialization process rather confusing, and have struggled with working out how to do similar things.
For me, the ideal solution would be something along the lines of the prerequisite system that exists for tick functions. Being able to specify “Call my InitializeComponent method before component instance X/component named Y/all components of class Z”, and having a similar system for actor initialization/BeginPlay too, would make things a lot easier I think.

Adding my 2 cents to this thread. I was just going through similar steps where I needed a component to have a reference to another component on the same actor, and I’m forced to do my reference initialization in the Tick method (if something == null then go get it).

I agree this pattern isn’t the best and can be quite brittle. I’m now moving towards letting the owning Actor pass references around once the components have been initialized.

Also when looking into this I’ve been advised that components do have a set overhead and we shouldn’t go overboard with encapsulation of functionality :slight_smile:

this works for me :slight_smile:

header:


virtual void InitializeComponent() override;

body:


//constuctor
USomeComponent::USomeComponent()
{
	bWantsInitializeComponent = true;
}

void USomeComponentComponent::InitializeComponent()
{
	Super::InitializeComponent();
	// your code
}

all hail component-centric code!

How does that solve the problem discussed? It’s a timing issue where the order of components being initialized isn’t guaranteed :slight_smile: So if one component needs to get a reference to another component, you cannot be sure the other component has initialized/loaded before the one currently doing so.

I know using InitializeComponent still has that issue, since it’s what I was using before :wink:

Leaving it to the actor gives more control, but also makes the components less plug and play, in that every time you add it you have to ensure the specific actor knows how to initialize it. To an extent of course this is inevitable when you have dependencies between components. I think being able to group components together into a composite which could then deal with initializing and coordinating the components, and be added to an actor as a single entity, would go a long way to solving this, and other issues. But I still think for maximum flexibility being able to manually specify initialization prerequisites would be useful.

Depending on the nature of your component initialization, you might want to do it in OnRegister instead of InitializeComponent. Component registration is the earliest you can rely on having a proper Component <-> Outer Actor relationship. It also precedes PostActorConstruction, therefore InitializeComponents, PostInitializeComponents and BeginPlay. So, for OP’s workflow:

  1. In OnRegister, have component initialize its self state.
  2. Once all components are registered, the few components that have dependencies on other components can then ask for InitializeComponents and query the other components knowing they are in a properly initialized state.

OnRegister also happens to be run at edit time for all subobjects. Initialization being done within OnRegister will therefore be reflected in blueprint defaults using your component or on instances of the same blueprint. Whereas InitializeComponent is a very late, runtime initialization that will not be seen until you run your game loop.

As an example, we have an NPC variant system that allows attaching accessories, changing materials, material params, etc. in order to diversify the appearance of NPCs. This is done through a custom skeletal mesh component, which constructs the required subcomponents and related data in OnRegister. Doing this logic there means I can adjust the variant data on an NPC instance and have the results immediately reflected. If I did it in InitializeComponent, this extra data would only be applied once I start a PIE session.

Basically, whenever I’m in doubt about where I need to do some initialization, I just start at the earliest possible and then move it down until it works as intended.

Thank you for the clear explanation!

I had however some problems with accessing actors or creating widgets in UActorComponent::InitializeComponent, which I did not expect, as it worked in another AActor::BeginPlay method.

I tried to work around this by moving that special code into my Tick-Implementation - executing it only in the first tick - which is why I searched for a better way.

Perhaps my implementation also had other issues.

I will try to reproduce my problem and write again…

Hi,

epic implemented this feature in 4.8, which is just… epic :).

As far as I know, I had some problems with creating widgets in UActorComponent::InitializeComponent, but that is now obsolete.

Thanks :slight_smile: