So I have a custom actor component, derived from UActorComponent. I also have a custom actor derived from UActor.
My setup in the editor is as follows:
Create a blueprint based on the custom actor
In the blueprint 's components I add the custom component
I add an instance of this to my scene, and I setup the properties on the custom component. One property that is important is a StaticMesh property which is used internally to build some data
In the construction script, I have added a sequence of nodes that essentially samples internal data (which is based on the StaticMesh) and prints it out
Inside the custom component, I have added code to the OnComponentCreated() and OnComponentDestroyed() methods. In the former, I essentially take information from the properties to setup internal state, and in the latter I am cleaning up allocated objects. I have added LOG statements to these methods to track execution as well as internal state. I also print out “this” pointer to track actual instances.
Now when I change a value in my construction script, this is what I am seeing
OnComponentDestroyed (instance 1)
OnComponentCreated (Instance 2) - StaticMesh property not valid
OnComponentCreated (Instance 2) - StaticMesh property not valid
Blueprint Construction script executes - at this point my internal data is not valid due to the StaticMesh property not being valid
OnComponentCreated (Instance 2) - Static Mesh property valid - but now it is too late
This is the sequence I see upon each change to a property. The problem I am having is that it appears that the component is “created” multiple times, but the first two times all its user filled properties are not valid for some reason, then the construction script executes while they are not valid, then it gets created a third time and now the data is valid but it’s too late at this point, as the BP has already run on invalid data.
One thing I forgot to mention is that I have tried doing this two ways. The way above, is NOT calling Super::OnComponentCreated(). With this method it gets called three times (presumably because I didn’t bubble up) but the third time eventually the StaticMesh is valid. If I do bubble up, then it only gets called once which is more what you would expect, but the problem is if I do that then the StaticMesh is never valid during the OnComponentCreated(). I get the feeling there is some other method I should be using here, I just don’t know what it is.
First time you see “component created”, it’s the CDO being reconstructed.
Every uobject class in UE4 has a default object based on the static class.
Second time, is instance of your object.
Depending on the function you override, you will see it being called for each instance of your object that you have created.
Last time, is your object being spawned into the game World.
Seems a bit excessive to do that every time a property changed, but I can see what you mean. But that doesn’t explain why the construction script is getting executed before the object is fully initialized and all its properties are valid. There must be some other event I am missing here, where I can hook in to build my internal state after all properties are loaded and valid but before the construction script executes.
So in desperation here, I forced an update of my internal state at the moment that one of my BlueprintCallable methods is called. When I did this I found the same problem, that being that at the moment of the BP executing, the Properties on the object are still not valid!
I have a property on the component class:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = “Machi Terrain”)
class UStaticMesh* TerrainMesh;
Then in code I am checking its validity before using it as such:
if (TerrainMesh->IsValidLowLevel())
{
}
But even at the moment the construction script nodes are executing, this validity check is still returning false. What am I missing here?