Spawning an Actor with a Template Actor set in the FActorSpawnParameters prevents the spawned Actor from replicating

I originally stumbled across this Issue while trying to get the ChildActorComponent to replicate the Actor properly. Spoiler: The ChildActorComponent will not replicate the the Child Actor because of this issue. Two methods for reproducing:

Method 1, using a ChildActorComponent

  1. Create a new Blueprint Actor, BP_Child (give it a cube so you can see it)
  2. Create a new Blueprint Actor, BP_Parent and give it a ChildActorComponent
  3. Set the ChildActorClass of the ChildActorComponent to BP_Child
  4. Set the Replicates flag on either the BP_Child Blueprint, or the details panel of theChildActorComponent to “true”
  5. Set NetMode in the Play dropdown to “Play as Listen Server”
  6. Set “Num Players” to 2
  7. Start with “Standalone Game” option
  8. Observer that the BP_Child actor is not present on the Client window

Method 2, using a custom SpawnActorFromTemplate() UFUNCTION

  1. Add class based on BlueprintFunctionLibrary (MyFunctionLib)
  2. Add the following to MyFunctionLib.h
UFUNCTION(BlueprintCallable, Category = "Actor")
static AActor* SpawnActorFromTemplate(AActor* Template, FTransform Transform)
{
	AActor* Result;
	FActorSpawnParameters Params;
	Params.Template = Template;
	Result = Template->GetWorld()->SpawnActor(Template->GetClass(), &Transform, Params);
	return Result;
}
  1. Create an actor Blueprint BP_TemplateActor (give it a cube so you can see it)
  2. Check the “Replicates” box of the actor
  3. Call the SpawnActorFromTemplate function from somewhere (e.g. in the LevelBlueprint of a map)
  4. Set “Num Players” to 2
  5. Start with “Standalone Game” option
  6. Observer that the BP_TemplateActor actor is not present on the Client window

The oldest (and only) record of this bug that I was able to find is this thread from 2014. It’s honestly kind of baffling that this is still an issue, since this seems like a really bad bug that would prevent any kind of reasonable use of the ChildActorComponent.

WORKAROUND:

If you have this problem, there are two solutions I have found.
Solution method 1:

  1. Create a new C++ child class of ChildActorComponent

UCLASS()
public UMyChildActorComponent : public UChildActorComponent
  1. Override the “CreateChildActor()” method like this

void UBGChildActorComponent::CreateChildActor()
{
	Super::CreateChildActor();
	if (GetChildActor() && GetChildActor()->GetIsReplicated())
	{
		GetWorld()->AddNetworkActor(GetChildActor());
	}
}

Note that the ChildActor property of the ChildActorComponent might still not be valid in the BeginPlay event on the Client

Solution method 2:

  1. Rewrite your “SpawnActorFromTemplate()” method like this

UFUNCTION(BlueprintCallable, Category = "Actor")
static AActor* SpawnActorFromTemplate(AActor* Template, FTransform Transform)
{
	AActor* Result;
	FActorSpawnParameters Params;
	Params.Template = Template;
	Result = Template->GetWorld()->SpawnActor(Template->GetClass(), &Transform, Params);
	if (Result->GetIsReplicated())
	{
		Template->GetWorld()->AddNetworkActor( Result );
	}
	return Result;
}

I hope this helps somebody out, since I banged my head against this for a while.

2 Likes