Spawning Actor with child Actor when dragged into scene

I want to Spawn an Actor with a child Actor when dragging the parent Actor into the scene. It is working but another child actor is spawned without being attached to the parent actor. Here my approach.

ASpawningActor::ASpawningActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it. 
	
	PrimaryActorTick.bCanEverTick = false;
	bReplicates = true;

	UStaticMesh* Mesh = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), NULL, TEXT("StaticMesh'/Game/Geometry/Meshes/1M_Cube.1M_Cube'")));
	UMaterial* Material = Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), NULL, TEXT("Material'/Game/Geometry/Meshes/CubeMaterial.CubeMaterial'")));
	
	
	UStaticMeshComponent* MeshComponent = NewObject<UStaticMeshComponent>(this, UStaticMeshComponent::StaticClass(), TEXT("StaticMesh"));

	if (!ensure(Mesh) || !ensure(Material) || !ensure(MeshComponent)) { return; }
	MeshComponent->SetStaticMesh(Mesh);
	MeshComponent->SetMaterial(0, Material);
	MeshComponent->SetWorldLocation(FVector(0.0f, 0.0f, 0.0f));
	MeshComponent->RegisterComponent();
	this->AddOwnedComponent(MeshComponent);
	this->SetRootComponent(MeshComponent); 
}

// Called when the game starts or when spawned
void ASpawningActor::BeginPlay()
{
	Super::BeginPlay();
}

// Called every frame
void ASpawningActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void ASpawningActor::PostActorCreated()
{
	FActorSpawnParameters SpawnInfo;
	Actor = GetWorld()->SpawnActor<AStreetActor1>(FVector(0.0f, 0.0f, 0.0f), FRotator(0.0f, 0.0f, 0.0f), SpawnInfo);
	Actor->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
}

I don’t use OnConstruction because child actors getting spawned all the time when moving the parent actor around. The old one won’t get destroyed.

252490-clipboard01.jpg

… but another child actor is spawned without being attached …

Do you mean:

  1. that the spawned actor is not attached?
  2. that the spawned actor is attached but second one is created (and not attached)?

It’s ok that you don’t use OnConstruction() although you can check IsValid(Actor) before spawning, which will prevent it from creating multiple copies.

Anyways I would imagine that PostActorCreated() is better.

There is one Actor which I drag into the scene (SpawnedActor) and one who gets created when doing so (StreetActor). I need to have this hierarchy in order to move the parent actor and everything gets moved around with it together.
When pressing the mouse and draggin into the scene one parent actor and its child gets created. That is fine. However, when I then release the mouse button another StreetActor is getting spawned, not being attached (as shown in the picture).
I tried IsValid, but it doesn’t seems to work.

FActorSpawnParameters SpawnInfo1;
AStreetActor1* Actor1 = GetWorld()->SpawnActor<AStreetActor1>(FVector(4025.339103f, 4016.818612f, -8459.981933f), FRotator(0.0f, 0.0f, 0.0f), SpawnInfo1);
if (IsValid(Actor1))
	{
		Actor1->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
	}

Can you add a trace and try to encapsulate the spawner in the validation check like this:

//other code...
void ASpawningActor::PostActorCreated()
{
	UE_LOG(LogTemp, Warning, TEXT("Post Create Call by: %s"), this->GetName().ToString());
	if (!IsValid(Actor))
	{
		FActorSpawnParameters SpawnInfo;
		Actor = GetWorld()->SpawnActor<AStreetActor1>(FVector(0.0f, 0.0f, 0.0f), FRotator(0.0f, 0.0f, 0.0f), SpawnInfo);
		Actor->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
	}
}

Note that there might be some errors as I got no compiler on the phone :wink:

Please show the log with “Post Create Call by: X” to see if there are multiple objects that call it or just one.

Thats the result of the trace:

252556-clipboard01.jpg

but…:

252557-clipboard02.jpg

this happens. I just want to spawn it once :frowning:
So PostActorCreated gets called twice. First: When dragging into scene, Second: When releasing the mouse button.

It is called by 2 different actors - SpawningActor_0 and SpawningActor_1… Are you sure you don’t have 2 of those on the scene?

So it looks like that: When I drag the parent actor into the scene he gets created and PostActorCreate gets called. When releasing the mouse button the parent actor gets destroyed and another one gets created and PostActorCreated gets called again. Thats why I have 2 child actors but only 1 parent actor.
I came to this idea because the number of the parent actor changes after releasing the mouse button.

Ahh! Those post- methods are all so badly documented :frowning:

You said you don’t use OnConstruction() but have you tried it with bRunConstructionScriptOnDrag = false? Alternately you can try AActor::PostActorConstruction().

There are a bunch more and I doubt anyone knows why there are 10+ post- and on- construction methods: AActor::PostSpawnInitialize(), AActor::PostInitializeComponents(), AActor::PostRegisterAllComponents(), …

So I tried bRunConstructionScriptOnDrag = false and it ends up with the same result as shown in the picture. I really would like to try AActor::PostActorConstruction() but it’s not a virtual method. Is there a way to access those methods in any way eventhough they are not virtual? Or is there a way to do something after they get called? I am not that deep into c++ yet.
Thank you for your effort!