Adding component OnConstruction

Hello,

I am trying to add a static mesh component in OnConstruction inside an extended actor class as shown in screenshots below. However if I create a blueprint with base class as “ATestActor” C++ class and place it in the scene, the mesh can be seen. Once I press play the mesh disappears.

I am unable to determine why static mesh component is destroyed on play when a reference to that is stored in another UObject derived class. Any help regarding this would be greatly appreciated.

Thank you.

Hello, Gam3r

Please note that TestStaticMeshComponent is a local variable in this case (it is declared and initialized inside

OnConstruction).

Thus, it gets destroyed outside of the method’s body.

To fix the issue, please declare the component in the header file before initializing it. (Please note that you won’t need to put auto (or any other type-related keywords) before name of the component in the initialization line, since the variable is already declared in the header).

Hope this helped!

Cheers!

Hello,

Thank you for your response.

I think you misinterpreted my question or I am fundamentally misunderstanding something here. To clarify few points.

1.) The pointer to a static mesh component is indeed declared in the header named TestObject.h containing UTestObject ( As shown in Capture2.png image above ).

2.) After doing NewObject(this) in ATestActor class OnContruction method at the end I am passing the pointer to UTestObject class
via “TestObject->SetMeshComponent(TestStaticMeshComponent)

3.) TestObject is declared in the header of ATestActor and is allocated/created in FObjectInitializer constructor like this

TestObject = ObjectInitializer.CreateDefaultSubobject(this, TEXT(“TESTOBJECT”));

Which is executed way before OnConstruction.

=============================================

So what I do not understand is :

1.) Is NewObject() → stack allocated not dynamic heap allocation? If it is latter when why is it getting destroyed automatically even though the dynamically allocated memory pointer is held in UTestObject

I have attached the test project for your reference to try out.link text

Steps to reproduce :

1.) Drag the blueprint named “BP_TestActor” which extends ATestActor C++ class, into the level.

2.) Press play in any level and the wheel will disappear.

I had a quick play around, this is not related to garbage collection. It’s far more confusing!

In my tests, if I set the static mesh in the blueprint and then immediately hit play, it would have disappeared. But if I then hit play again, it would work. Each time I changed the static mesh property, the next time I played it would be gone. If however I saved the blueprint immediately after changing the mesh, it would work.

I can’t fully explain this behaviour, but I’m pretty sure it’s related to the way actors in the level are duplicated for play in editor, and how OnConstruction behaves. Basically, OnConstruction isn’t invoked when you play (only when you change properties in the editor). So for your mesh component to be setup, this is relying on the mesh being setup in the instance of the actor used to initialize the actor in your newly run level. That instance is some confusing combination of the existing object in the level editor, the CDO of the blueprint, and/or a serialized version of the object. It varies between play in editor, simulate in editor, standalone, packaged/cooked, etc.

I don’t know if it’s a bug, probably more likely a weird but expected quirk.

Generally I don’t make use of OnConstruction - it’s more of an editor-time thing, only really useful for when you want to do design time procedural generation based on modified properties. Any initialization that just needs to happen once when you start playing or an object is spawned, should just go inside BeginPlay.

Hey Kamrann thank you for your response, your response makes way more sense than initial response I got for this question. Definitely did notice that OnConstruction is not invoked for an actor which is already in the level. As a workaround if you might have noticed the comment in my test project I added this method in BeginPlay :
this->RerunConstructionScripts();

That made sure it reconstructs again.

And another thing is if I store a pointer reference to that StaticMeshComponent in the same actor class the object remains. It only gets destroyed if I store the pointer via UTestObject proxy.

What would be great though is if someone from Epic can respond clearly and explain why a component created in OnContruction is destroyed for actors already placed in the level.