TakeDamage bug when you shoot a dead character

Basically happends when you spam the Shoot button and if for some reason the AShooterCharacter::TakeDamage method enters when the character is dead it would crash unreal engine because our statements

if (IsDead())
	{
		DetachFromControllerPendingDestroy();
		GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	}

So I added an contition at the very first of the TakeDamage method so easily get rid of that problem.

if(IsDead()) return 0.0f;

this is the full method:

float AShooterCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
	if(IsDead()) return 0.0f;

	float DamageToApply = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);

	DamageToApply = FMath::Min(Health, DamageToApply);
	Health -= DamageToApply;
	UE_LOG(LogTemp, Warning, TEXT("%s received damage! %f health remaining"), *GetOwner()->GetName(), Health);

	if (IsDead())
	{
		DetachFromControllerPendingDestroy();
		GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	}

	return DamageToApply;
}
2 Likes

It’s the UE_LOG calling a nullptr.

When you run DetachFromControllerPendingDestroy(), you also get rid of the owner from my guess.
This solution works, and I don’t see anything going wrong with it, but this should help people understand what’s causing this issue.

My Solution was to get rid of the UE_LOG, but if you want to keep reporting you can just embed it in an else statement after checking if (IsDead()).

	UE_LOG(LogTemp, Warning, TEXT("%s has recieved %f Damage, and now has %f Health left"), *GetOwner()->GetName(), DamageToApply, Health);

Which would make your method look more like:

float AShooterCharacter::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) 
{
	float DamageToApply = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
	DamageToApply = FMath::Min(Health, DamageToApply);
	Health -= DamageToApply;


	if (IsDead())
	{
		DetachFromControllerPendingDestroy();
		GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("%s has recieved %f Damage, and now has %f Health left"), *GetOwner()->GetName(), DamageToApply, Health);
	}

	return DamageToApply;
}

Privacy & Terms