Supplying an instantiated Actor as a Template in FActorSpawnParameters results in incomplete / broken Actors and a warning message when trying to spawn a copy using UWorld::SpawnActor

First of all, setting FActorSpawnParameters.Template to an instance of an actor to spawn a copy of the given actor results in the following warning: Warning AttachTo: '/Game/UEDPIE_0_TestLevel.TestLevel:PersistentLevel.BP_ActorToClone_0.TRRoot' cannot be attached to itself. Aborting.

NOTE: TRRoot is the root component of the actor I’m trying to clone.

It also results in a broken actor with duplicated dynamically spawned components and without the child components that were previously defined in the editor.

Here is the code I’m using to copy the actor:

UFUNCTION(BlueprintCallable, Category = "Helper")
static AActor* CloneActor(AActor* actorToClone, const FTransform transforms, ESpawnActorCollisionHandlingMethod collisionMethod = ESpawnActorCollisionHandlingMethod::AlwaysSpawn)
{
	if (actorToClone->IsValidLowLevel())
	{
		UWorld* world = actorToClone->GetWorld();
		FActorSpawnParameters params;

		params.SpawnCollisionHandlingOverride = collisionMethod;
		params.Template = actorToClone;

		return world->SpawnActorAbsolute<AActor>(actorToClone->GetClass(), transforms, params);
	}
	return nullptr;
}

These are the results:

Please note that there are only 2 actors in the last picture - one to the right and the other in the middle at (0,0,0) with duplicated TextRenderComponents to the left.

Would be awesome if you could tell me what’s going on and if I’m even supposed to use instances as templates. Thanks! :slight_smile:

Hey sMB,

I am unable to reproduce the issue you are having and I am not certain this is a engine bug but I have a few suggestions.

When it comes to your CloneActor function, I am not sure in which class you writing it. For me, I chose the GameMode class and chose to reference the function through that. Also, I am not using static. Finally, there is no need to assign the actorToClone reference to params.Template.

AActor* AAH449607GameMode::CloneActor(AActor* actorToClone, const FTransform transforms, ESpawnActorCollisionHandlingMethod collisionMethod)
{
	if (actorToClone)
	{
		FActorSpawnParameters params;
		params.SpawnCollisionHandlingOverride = collisionMethod;
		return GetWorld( )->SpawnActorAbsolute<AActor>( actorToClone->GetClass( ), transforms, params );
	}
	return 0;
}

When I used the attached Blueprint, I am able to duplicate an already existing reference to an Actor through the CloneActor Blueprint function.

I am not 100% sure what your results image is showing. If my answer is not enough, please break down your problem a bit more and I will try and help with that.

A few things I can ask of you when describing your problem are:

  • What is your goal with the CloneActor function?
  • In what context will you be using the CloneActor function?
  • Do you have any comparison to show, in regards to another system or game that is doing something you are trying to mimic?

Thanks!

Hi, first of all thanks for answering and sorry for not being specific enough.

I’m actually trying to clone a given instance of an actor with all its current parameters at runtime. In my case, I’m using a blueprint function library for this.

Think of a visual crafting system where the designer can link items together to create recipes. These recipes then get stored and used by the crafting system in-game to spawn items in a given state. For example a key for a specific door, or a water bottle with a quality based on which recipe you used to craft it. It’s basically a bit like having multiple sets of default parameter values for the same actor.

Now I do use inheritance and could just duplicate blueprints to get different default values, but it does seem like an overkill to create copies of blueprints just to change some default values. Custom constructors aren’t ideal either, since they are fairly hard to keep track of later on and can lead to nasty bugs.

That’s why I was hoping I could leverage UE4’s custom reflection capabilities to clone a given actor instance instead. It seems to be possible since the editor appears to do this every time I copy an object in the scene - and setting the FActorSpawnParameters.Template successfully copies the objects parameters, but fails to copy its components.

As for the results picture, it’s a bit hard to explain (and I’m not a native English speaker). Basically what happens is this: When I try to clone the actor on the right side (0, 0, 200) to the left side (0, 0, **-**200), the actor gets cloned to (0, 0, 0) without child components that were created inside the editor. Also, all dynamically created child components (labeled 1, 2, 3 respectively) get duplicated twice - once to (0, 0, 0) and once to (0, 0, -200).

98243-duplicate_components.png

Note that the Gizmo is at (0, 0, 0)

After investigating this doesn’t appear to be a bug with the engine.

With that said, when you create a new instance of a object (spawn an Actor for instance), you can use a previous instance to assign any existing data to it.

As an example, if you have an Actor with the following data:

  • Health: 151
  • Mana: 23
  • Damage: 12
  • Armor: 24

Now, if you want to create a copy of this Actor, you can spawn a new instance of it via Blueprints or C++ which may look like:

  • Health: 200
  • Mana: 100
  • Damage: 5
  • Armor: 15

You can then take the previous instance and assign its values to the default values of the new instance you’ve created so they match.

Such as:

  • Actor_02->Health = Actor_01->Health
  • Actor_02->Mana = Actor_01->Mana
  • Actor_02->Damage= Actor_01->Damage
  • Actor_02->Armor = Actor_01->Armor