BeginDestroy is never called?

// header
virtual void BeginDestroy() override;

// cpp
void ABaseSegment::BeginDestroy()
{
	// Also destroy any obstacles that this segment may have spawned.
	for (int i=0; i<Obstacles.Num(); i++) // never called
	{
		Obstacles[i]->Destroy();
	}

	Super::BeginDestroy(); // outcommenting this line does not cause a crash for some odd reason even though it should.
}

Setting a breakpoint on the internal code will cause a crash:

void AActor::BeginDestroy()
{
	UnregisterAllComponents(); // <<<<< Setting breakpoint here will cause a crash where it complains about a super not being called. Works fine without a breakpoint. It seems that breakpoints are not allowed here.
	Super::BeginDestroy();
}

So I don’t really know how to debug this. Why is BeginDestroy() never called when I call Destroy() on the actor?

I tried to use this too, also crashed, looks like on BeginDestroy all the actor references and components and whatsoever is already freed and can’t be accessed, I just swaped BeginDestroy with Destroyed and it worked.

//header
virtual void Destroyed() override;

//cpp
void AProjectile::Destroyed()
{
	Super::Destroyed();

	FVector location = GetActorLocation();
	DrawDebugLine(GetWorld(), lastPosition, location, GetColorByVelocity(), false, 15.f, 0, 3);
}
4 Likes

You probably have moved on from this but I’m leaving the answer here in case anyone else comes upon the question.

BeginDestroy is not called as soon as an actor is destroyed. It will be called on the next Garbage Collector iteration.
What does called immediately is “EndPlay”.

Here’s a handy AActor lifecycle guide:

1 Like

It seems like EndPlay is a superset of Destroyed and gets invoked in additional circumstances per the enum value other than being explicitly “Destroyed”. Depending on what needs to be cleaned up this may or may not be what you want, but based on OP it looks like they wanted to override “Destroyed” rather than “BeginDestroy”.

1 Like