Hello
I have a reproducible case of an assert when trying to spawn an actor from a template
For my game I am trying to spawn a duplicate of an actor at runtime, with deep copy of its subobjects, in particular the custom components necessary for my game logic.
However, trying to call UWorld::SpawnActor(UClass*,FTransform const*, const FActorSpawnParameters&) with an actor template that contains a component added in the editor will result in an assert.
Am I doing something wrong?
I traced through execution of what seemed a perfectly reasonable instanciation of subcomponents, although the recursion seems to make it reallocate its own array by adding an element in an inner loop with integrity check.
The actual assert happens at PropertyArray.cpp line 338 after successfully instanciating the subobjects including the actor components:
checkf(DestValue == ArrayHelper.GetRawPtr(ElementIndex), TEXT("%s has been re-allocated while instancing subobjects for %s, fix higher level code!"), *GetName(), *Owner->GetPathName());
Here is an example of how to reproduce the problem quickly:
In a UBlueprintFunctionLibrary header file :
UFUNCTION(BlueprintCallable, Category = "Test")
static AActor* SpawnActorFromTemplate(AActor* anOwner, AActor* aTemplate, const FTransform aTransform, ESpawnActorCollisionHandlingMethod aCollisionHandling = ESpawnActorCollisionHandlingMethod::AlwaysSpawn);
.cpp
AActor* UProjectStatics::SpawnActorFromTemplate(AActor* anOwner, AActor* aTemplate, const FTransform aTransform, ESpawnActorCollisionHandlingMethod aCollisionHandling /*= ESpawnActorCollisionHandlingMethod::AlwaysSpawn*/)
{
if(anOwner && aTemplate)
{
FActorSpawnParameters params;
params.Template = aTemplate;
params.SpawnCollisionHandlingOverride = aCollisionHandling;
params.ObjectFlags = RF_Transient;
return anOwner->GetWorld()->SpawnActor(aTemplate->GetClass(), &aTransform, params);
}
return nullptr;
}
Create a new level and add any static mesh actor and a component, here I used a PointLightComponent
Add the testing code in level blueprint:
What am I doing wrong? What is the correct way to duplicate actors with deep copy of subobjects at runtime?
Thanks in advance!