Components Created in Actor's Construction Script Become Trash Objects

The case is that components created in an Actor’s construction script could become trash objects when the construction script is called the next time.

It is pretty simple to reproduce the case:

  1. Create a Blueprint Actor named BP_Actor.
  2. Add a variable named TextRenderArray, which is an array of Text Render Component. Make it editable so that its content in a BP_Actor instance could be observed in Details panel of the map editor.
  3. Set up the BP_Actor construction script like this:

Basically it is adding and attaching a Text Render Component to BP_Actor and insert it at the front of TextRenderArray.

  1. Now go to the map editor and place a BP_Actor in the map. Change it somehow (e.g. simply by dragging it around) and here is what TextRenderArray contains:

The trash elements are not visible in the map, and after a while they become None, indicating that they have been garbage collected.

I can reproduce this case on UE 4.14 and 4.13. It can also be reproduced with other components or if the component adding logic is driven by an event triggered in AActor::OnConstruction() in C++.

This is a simplified version of what I am trying to do: Use the construction script to monitor changes on an actor, and update it incrementally. I prefer not to create a new actor because the update involves adding few new components only upon some rare changes. It would be costly to create a new actor and add back all components back upon any change.

Based on the observation, my guess is that somehow the construction script creates a new actor in the back, copies everything over from the current actor and switch to the new actor as the current one. The previous actor’s components are marked for garbage collection, even if the components are still referenced by the array that is shallow-copied to the new actor. Just my guess.

Questions:

  1. Is this how construction script works?
  2. Is it safer to treat the object as a new one created from scratch than to incrementally update the object in construction script? Arrays of simple types e.g. Boolean works fine, but garbage collection could take place else where which breaks the logic in construction script.
  3. Back to the case of incrementally adding components in construction script: Is there a way to work around the trash objects issue?

Thank you for your thoughts.

I would imagine that this is not a bug and only serves to protect you against accidentally adding a million trillion USceneComponents to your actors when you move it around the level.

From my tests it also occurs with AddBillboardComponent so im guessing that the USceneComponent class has protection in it against being created in the construction script over and over again.

If you wish to create a specific amount of USceneComponents in the Construction Script i recommend using a ForLoop and iterating yourself as it will maintain any purely specified USceneComponents through this manner.

Why don’t you reset/resize your array?