How to make an actor spawn other actors after dropping it into viewport? C++

I want to create a complex actor that consists of many other actors.


For example:

  • I want to create a grid of cells for any reason: set of buttons to interact with, tiles to create map.
  • Or to create a map that consists of many generated chunks.
  • Or to create squad of soldiers in specific quantity and each placed in specific location.

But I want to see all this created in the editor after I drag and drop it to viewport but not during the gameplay because I want to see what I’m designing.

Have you already done it in blueprint? If not, then do it there first.

If you want to do this in blueprints, then use construction script part of the blueprints to spawn the actors and components.

If you want to do this in C++, then use the constructor of the actor to spawn more actors and components. Look for NewObject function.

You might want to look at PostLoad virtual function, it can be helpful for tasks like this to initialize or change the actors that you spawned after they spawned and loaded in the editor. (This is wrong, sorry. PostLoad is called when scene loads and if the actor is in the scene)

You would want to look at Component Visualizer. It can be great help when you are spawning more actors from one actor. (https://sondreutheim.com/post/ue4_component_visualizers)

There is one specific case in your question, “creating chunks of map”, this can be better achieved using World Composition and level streaming if the chunks are big.

I want to do it in C++. But even if I wanted to do it in blueprints construction script doesn’t really work because it’s triggered twice: first time when you drag the actor into viewport and second time when you drop it in there. So this way extra actors are created.

You can’t use class constructor for the same reason: it’s executed twice. The same about PostActorCreated and OnConstruction.

PostLoad doesn’t fire at all when I drop my actor into viewport, just checked.

I’ve tried to do it in construction script but it’s executed twice so it creates extra actors. Also I don’t want to do it in blueprints but in C++.

That was my mistake with PostLoad. It runs if actor is already in scene and when you open then scene.

The expected behavior of both C++ constructor and blueprint construction script runs is to run when dragged and dropped and also when object is moved in the scene too. So you need to save the objects you spawned into the actor that is spawning them and not spawn them again if they are already spawned and just set their positions or something like that.

Either I’m dumb or it doesn’t work like this.

You can’t store the actor you spawned when you first entered the viewport area during dragging because after you release dragging and drop the actor into viewport it’ll create a new instance that doesn’t know anything about the actor you stored in previous instance.

What you said is true, which is why you would mark the variables you are using for this purpose as static.
Mind that this is all a work around and is not at all recommended thing to do. Spawning actors in constructor of another actor isn’t recommended for the very reason you mentioned. You can read more about it in this reply.

https://forums.unrealengine.com/unreal-engine/feedback-for-epic/29060-spawn-actor-from-construction-script-loophole?p=317601#post317601

Using static variables to store actors between two instances is such a horrible idea.

In the link you sent they’re talking about spawning actors in construction script and that it’s bad since CS fires too often and because of that it’ll create too many actors. Which can be simply prevented by storing the created actor as you said. But sadly it won’t work since CS fires twice on drag and drop respectively.