How to Spawn New Actor Immediatly upon Actor Death?

I’m creating an aim trainer, and would like to have a new target spawn as soon as one is destroyed. I have an Actor class called TargetSpawner, which spawns using:

TSubclassOf ActorToSpawn;
and
GetWorld()->SpawnActor(ActorToSpawn, &SpawnLocation);

The actual actor being spawned is an Actor class called SphereTarget which has a health component. When it reaches zero, I use:

GetOwner()->OnTakeAnyDamage.AddDynamic(this, &UHealthComponent::DamageTaken);

to decrement the health of the Sphere target and destroy it if it has less than 0 health. Is there a way for me to communicate to the TargetSpawner that the actor it has spawned (SphereTarget) has been destroyed? Or if destruction isn’t necessary, and it could simply be moved, how would I communicate that to TargetSpawner?

Thanks,
Mark

SpawnActor should be like this:

GetWorld->SpawnActor<AClassToSpawn>(ActorToSpawn, SpawnLocation);

you can invoke this after health <= 0

From spawner code, when spawning new target you can bind a listener to its Destroyed event :

void ATargetSpawner::SpawnTarget()
{
    AActor* Target = GetWorld()->SpawnActor<AActor>(ActorToSpawn, SpawnTransform);
    if (Target)
    {
        Target->OnDestroyed.AddDynamic(this, &ATargetSpawner::OnTargetDestroyed);
    }
}
void ATargetSpawner::OnTargetDestroyed(AActor* DestroyedActor)
{
    SpawnTarget();
}
2 Likes

Thanks for the response, but unfortunately the program never makes it to the OnTargetDestroyed function, even after the spawned target has been destroyed. I’m going to explain more of my code in hopes that I have an error somewhere else.
Quick recap on the flow of the code: TargetSpawner spawns SphereTargets. Upon taking lethal damage, the health component calls the game mode class, and passes the damaged actor. The game mode class then calls SphereTarget to destroy itself.

This is my TargetSpawner class:

ATargetSpawner::ATargetSpawner()
{
	PrimaryActorTick.bCanEverTick = true;
	SpawnBox = CreateDefaultSubobject<UBoxComponent>("SpawnBox");
	RootComponent = SpawnBox;
}
void ATargetSpawner::BeginPlay()
{
	Super::BeginPlay();
	BoxBounds = SpawnBox->CalcBounds(GetActorTransform());
	FVector SpawnLocation = BoxBounds.Origin;
	AActor* SpawnTarget = GetWorld()->SpawnActor<AActor>(ActorToSpawn, SpawnLocation, SpawnBox->GetComponentRotation());
	if (SpawnTarget)
	{
		SpawnTarget->OnDestroyed.AddDynamic(this, &ATargetSpawner::OnTargetDestroyed);
	}
}
void ATargetSpawner::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}
void ATargetSpawner::SpawnActor()
{
	FVector SpawnLocation = BoxBounds.Origin;
	ASphereTarget* SpawnTarget = GetWorld()->SpawnActor<ASphereTarget>(ActorToSpawn, SpawnLocation, SpawnBox->GetComponentRotation());
	if (SpawnTarget)
	{
		SpawnTarget->OnDestroyed.AddDynamic(this, &ATargetSpawner::OnTargetDestroyed);
	}
}
void ATargetSpawner::OnTargetDestroyed(AActor* DestroyedActor)
{
	SpawnActor();
}

This the SphereTarget class:

ASphereTarget::ASphereTarget()
{
	PrimaryActorTick.bCanEverTick = true;
	CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>("Capsule Collider");
	RootComponent = CapsuleComp;
	BaseMesh = CreateDefaultSubobject<UStaticMeshComponent>("Base Mesh");
	BaseMesh->SetupAttachment(CapsuleComp);
}
(Beginplay and tick are default)
void ASphereTarget::HandleDestruction()
{
	Destroy();
}

This is the HealthComponent class:

void UHealthComponent::BeginPlay()
{
	Super::BeginPlay();
	Health = MaxHealth;
	GetOwner()->OnTakeAnyDamage.AddDynamic(this, &UHealthComponent::DamageTaken);
	BeatAimGameMode = Cast<ABeatAimGameModeBase>(UGameplayStatics::GetGameMode(this));
}
void UHealthComponent::DamageTaken(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* Instigator, AActor* DamageCauser)
{
	if (Damage <= 0.f) return;
	Health -= Damage;
	if (Health <= 0.f && BeatAimGameMode)
	{
		BeatAimGameMode->ActorDied(DamagedActor);
	}
}

And finally the GameMode class:

void ABeatAimGameModeBase::ActorDied(AActor* DeadActor)
{
	if (ASphereTarget* DestroyedTarget = Cast<ASphereTarget>(DeadActor))
	{
		DestroyedTarget->HandleDestruction();
	}
}

Apologies if my formatting is terrible, I do not know how to format posts.

Seems correct overall.
Are you actually adding the health component to the target actor?
I don’t see it added in c++ :

I don’t have it added in c++, but i did add the health component to the blueprint based off of ASphereTarget.cpp. But your solution did end up working! I forgot to declare OnTargetDestroyed as a UFUNCTION()

Thanks again.