If I try to change any property of my C+±class-derived-blueprint Actor (while playing in editor or not), it seems to get reconstructed everytime (Actor::OnConstruction() is called). Simply translating the object in the editor (not even in play mode) will trigger this. All the components on the Actor get destroyed and then reallocated (components pointing to new addresses), but PostInitComponents() is not called afterward. Is this working as intended? This seems very wasteful and causes a lot of problems when caching references to components in PostInitComponents().
Repro Steps
Create a new MyActor C++ class (MyActor.cpp/MyActor.h)
Create a blueprint BP_MyActor derived from the MyActor C++ class
Place an instance in the level
Observe that if you move the object around, you get spammed with OnConstruction() logs
Hit the PIE button
Observe that changing any other property of the Actor will cause the object to be reconstructed
You can also try adding components to the blueprint (e.g. PointLightComponent) and monitor its address using FindComponentByClass() in the OnConstruction() method. You will see a different pointer everytime you change a property of the actor or move it around.
This is the intended behavior of the construction script. You should not put your Component creation in there, the construction script whole purpose is to be called each time you modify a property of the actor so you can do custom “in editor” stuff related to that actor.
You can do Component creation in there, but yes, it will be flushed and re-done everytime. In permits lots of neat stuff like creating procedurally generated stuff :
Hm ok I wasn’t aware of this. My blueprint construction graph is empty, and I also don’t expect my entire list of components on my object to be recreated everytime I change a property of the object.
How do I cache reference to components in my C++ then? Right now this is causing my custom actor to be uneditable while in PIE mode because the components reset as soon as a property on the actor is modified. I’m currently caching the component references in MyActor::PostInitComponents() like so:
And I use these component references in the Actor’s Tick() method. This breaks as soon as I change a property on that actor while in PIE mode. Is there another event I should be monitoring, or some kind of tag/annotation I could use to tell the engine to not mess with these components?
void MyActor::BeginPlay()
{
//I don't know about FindComponentByClass, but an alternative would be this :
TArray<UStaticMeshComponent*> staticMeshComps;
GetComponents(staticMeshComps);
//You will now have all your StaticMeshCompoenent in the staticMeshComps array
}