Spawning an actor in PostActorCreated() creates two of them

Can be reproduced with a simple AActor* derived class with this function in it:

void ATest::PostActorCreated() {
	Super::PostActorCreated();
	AActor* a = GetWorld()->SpawnActor<AActor>();
	a->SetActorLabel("___TEST");
}

Result: Two actors called __TEST are created on the stage. Why is this?

(Apologies in advance if this is something fixed in the later versions–would just like to get things working with what I have now before updating blindly)

PostActorCreated seems to be called twice during the drag’n drop operation.
First call when you drag the object and your cursor enter the screen (called by OnDragEnter), and a second one when you place the item (called by OnDrop).
If you use Right click > Place Actor > Test, the actor spawn only one actor.
Maybe you should use OnConstruction ?

Hey sgp-

The bug with the PostActorCreated function being called twice has been reported (UE-23900) for further investigation. For now I would advise using Begounet’s suggestion of spawning the actor elsewhere such as OnConstruction or OnBeginPlay

Cheers

.

Thanks, that makes sense, I guess I can go with right clicking for now. It seems that OnConstruction is called on every property change though. Is there another called-only-once post-spawn function?

Hi sgp,

I’ve taken a look at the editor drag and drop operation, and as Begounet stated, it’s called twice - once upon drag starting over the viewport (to spawn the preview actor), on again on drop (to spawn the proper instance in the level).

While not ideal, we won’t be changing this behaviour at the moment as the preview actor really has different properties and behaviour to the real instance and is best implemented as a separate spawn.

I don’t know if your code snippet was a real case that you’re implementing or just a theoretical example to demonstrate the issue. In general, I wouldn’t recommend spawning actors in PostActorCreated like this, not least because, once spawned, they are no longer associated with the actor which spawned them and if the code changes in the future, you could be left with junk actors in your level which need updating. Maybe take a look at ChildActorComponent if you wish to do this, or consider using a Blueprint with a construction script.

If you really would like to do this in PostActorCreated, you could try something like the following:

void AMyActor::PostActorCreated()
{
	Super::PostActorCreated();
	if (!HasAllFlags(RF_Transient))
	{
		AActor* A = GetWorld()->SpawnActor<AActor>();
		A->SetActorLabel("___TEST");
	}
}

This assumes that you will never have transient instances of your actor spawned, so is not a perfect solution by any means.

Thanks for the in-depth explanation. I tried searching for ChildActorComponent but am not finding any references on how to actually use it (especially in C++). Would you have a link anywhere? Also, during my search I’ve found people saying that ChildActorComponent was more for use in blueprints to get around something and that it is easier in C++ to manage hierarchies without it (which is what I feel to be the case, at least in regards to casting). When I spawn actors in PostActorCreated(), I am actually keeping a pointer to it inside the parent actor’s class (unlike what the example code shows). Would using ChildActorComponent still be preferred?

Hey sgp-

Can you explain what you are trying to accomplish by spawning and actor from the PostActorCreated() function? Are you trying to create a procedural asset or are you trying to create an asset that also spawns a companion asset? If it is the latter, you should be able to use OnConstruction or BeginPlay(). As Richard pointed out, you can also setup the blueprint Construction Script to handle spawning the second actor / setting the pointer to it (if the pointer is exposed with UPROPERTY).

I am trying to create an asset that spawns a companion asset, but I want to be able to make changes to said companion asset inside the editor so BeginPlay() is out of the question. OnConstruction() (and the BP Construction Script) is called every time something is changed, so that’s not what I’m looking for either. Is there something I’m missing about it (which is why it’s been suggested)?

If using OnConstruction creates multiple copies of the companion asset whenever it is updated, you can add a block to the spawn portion that only creates the asset if it doesn’t already exists. It would look something like:

if (CompanionAsset == NULL)
{
	//Spawn Companion asset
	//CompanionAsset = Spawned asset
}

Why is that preferred though? If right-clicking instead of dragging is all it takes to have PostActorCreated() work, it seems a lot cleaner code-wise to do just that than to have to do null checks for every single companion asset, especially when I have multiple of them. I’ve checked the docs but I’m not understanding why this is considered better.

As previously mentioned, dragging from the content browser into the level creates a preview asset first and then creates the final asset when you release the left mouse button. Using the right click method likely skips creating the preview asset which is why it’s only called once. If this works for you then you can continue to use that instead.