언리얼 - C++ 프로젝트

OpenWorldRpg (21) 플레이어 사망 애니메이션

earth-star 2025. 6. 10. 00:28

플레이어의 사망 애니메이션을 추가해볼 것이다.

 

먼저 적에게 있던 사망 애니메이션 함수를 플레이어와 적 공통으로 사용하기 위해서 BaseCharacter로 아래와 같이 옮겼다.

// BaseCharacter.cpp

void ABaseCharacter::Attack()
{
	if (CombatTarget && CombatTarget->ActorHasTag(FName("Dead")))
	{
		CombatTarget = nullptr;
	}
}

void ABaseCharacter::Die()
{
	Tags.Add(FName("Dead"));
	PlayDeathMontage();
}

int32 ABaseCharacter::PlayRandomMontageSection(UAnimMontage* Montage, const TArray<FName>& SectionNames)
{
	if (SectionNames.Num() <= 0) return -1;
	const int32 MaxSectionIndex = SectionNames.Num() - 1;
	const int32 Selection = FMath::RandRange(0, MaxSectionIndex);
	PlayMontageSection(Montage, SectionNames[Selection]);
	return Selection;
}

int32 ABaseCharacter::PlayDeathMontage()
{
	const int32 Selection = PlayRandomMontageSection(DeathMontage, DeathMontageSections);
	TEnumAsByte<EDeathPose> Pose(Selection);
	if (Pose < EDeathPose::EDP_MAX)
	{
		DeathPose = Pose;
	}

	return Selection;
}

 

죽으면 Dead 태그를 달아서 공격을 하지 않도록 하였다.

// SlashAnimInstance

void USlashAnimInstance::NativeUpdateAnimation(float DeltaTime)
{
	Super::NativeUpdateAnimation(DeltaTime);

	if (SlashCharacterMovement)
	{
		GroundSpeed = UKismetMathLibrary::VSizeXY(SlashCharacterMovement->Velocity);
		IsFalling = SlashCharacterMovement->IsFalling();
		CharacterState = SlashCharacter->GetCharacterState();
		ActionState = SlashCharacter->GetActionState();
		DeathPose = SlashCharacter->GetDeathPose();
	}
}

 

AnimInstace에 플레이어의 ActionState와 DeathPose를 알려주기 위해서 FORCEINLINE을 추가하여 위와 같이 에디터에서 볼 수 있도록 변수를 추가한다.

 

 

ABP에서 Dead 스테이트를 추가한다.

 

전에 했던 적의 사망애니메이션과 같다.

 

죽는 애니메이션은 적에게서 몇개를 빼와서 리타겟 애니메이션으로 간단히 적용하였다.

 

위와 같이 ActionState와 DeathPose 2개의 새 변수가 추가된 것을 볼 수 있다.

 

// Enemy.cpp

void AEnemy::PawnSeen(APawn* SeenPawn)
{
	const bool bShouldChaseTarget =
		EnemyState != EEnemyState::EES_Dead &&
		EnemyState != EEnemyState::EES_Chasing &&
		EnemyState < EEnemyState::EES_Attacking &&
		!SeenPawn->ActorHasTag(FName("Dead")) &&
		SeenPawn->ActorHasTag(FName("EngageableTarget"));

	if (bShouldChaseTarget)
	{
		CombatTarget = SeenPawn;
		ClearPatrolTimer();
		ChaseTarget();
	}
}

 

추가로 사망한 캐릭터를 적이 쫓지 않도록 Enemy.cpp에서 폰 감지함수에서 !SeenPawn->ActorHasTag(FName("Dead"))를 추가하여 Dead 태그를 가지고 있을시 CombatTarget을 설정하지 않도록 하였다.

 

 

플레이어의 사망 애니메이션이 잘 적용되고 죽은 후에는 적이 더이상 관심갖지 않고 순찰을 도는 모습을 볼 수 있다.