본문 바로가기

게임프로그래밍/실습1

[언리얼] 77. 플레이어 데스 몽타주 재생하기


목차

  1. 플레이어 Dead 상태로 바꾸기
  2. 애니메이션 블루프린트 수정하기

1. 플레이어 Dead 상태로 바꾸기

 

UPROPERTY(BlueprintReadOnly)
EDeathPose DeathPose;

 

에너미 클래스에 있던 DeathPose 를 베이스 캐릭터로 옮기자.

 

이제 이 변수는 에너미뿐 아니라 플레이어도 쓸 것이다.

 

int32 ABaseCharacter::PlayDeathMontage()
{
	const int32 Selection = PlayRandomMontageSection(DeathMontage);

	if (Selection < static_cast<int32>(EDeathPose::EDP_MAX) && Selection > -1)
	{
		DeathPose = static_cast<EDeathPose>(Selection);
	}
	return Selection;
}

 

이제 에너미라는 특정 클래스에서 했던 작업을 베이스 캐릭터에서 진행하면 된다. 에너미에 있던 함수는 제거해주자.

 

void ABaseCharacter::Die()
{
	PlayDeathMontage();
}

 

이제 베이스 캐릭터의 Die함수에서 데스몽타주를 재생해준다. 이부분은 에너미랑 플레이어 모두가 실행할 부분이라 부모 클래스에서 구현하였다.

 

이제 에너미는 에너미의 죽음상태로, 플레이어는 플레이어의 죽음상태로 되어야 한다. 에너미는 이미 구현이 되었으니 플레이어도 구현해보자.

 

UENUM(BlueprintType)
enum class EActionState : uint8
{
	EAS_Unoccupied UMETA(DisplayName = "Unoccoupied"),
	EAS_HitReaction UMETA(DisplayName = "HitReaction"),
	EAS_Attacking UMETA(DisplayName = "Attacking"),
	EAS_EquippingWeapon UMETA(DisplayName = "EquippingWeapon"),
	EAS_Dead UMETA(DisplayName = "Dead") //추가
};

 

열거형을 추가해준다.

 

이제 캐릭터 클래스로 가서 Die 함수를 오버라이드 해주자.

 

virtual void Die() override;
void AKnight::Die()
{
	Super::Die();

	ActionState = EActionState::EAS_Dead;
}

 

이제 컴파일하고 제대로 작동하는지 확인하자.


2. 애니메이션 블루프린트 수정하기

 

이렇게 하면 플레이어의 데스 몽타주가 정상적으로 재생된다. 하지만 이게 유지되지는 않는다. 따로 데스포즈를 설정하지 않았기 때문이다.

 

 

플레이어의 메인 스테이트 애니메이션 블루프린트로 들어가자

에일리어스를 하나 만들어주자. 원래 OnGround에서 연결하려고 했는데 점프중에도 애니메이션을 재생할 수 있는게 맞을 거 같아 에일리어스로 구현하려고 한다.

 

이제 조건을 추가해주어야 한다. Action State를 보고 현재 어느 상태인지 알아야 할 것이다.

 

Action State는 현재 블루프린트에서 볼 수 없다. C++ 애님인스턴스 클래스에서 추가해주어야 한다.

 

UCLASS()
class PRACTICE_API UKnightAnimInstance : public UAnimInstance
{

// 생략

	UPROPERTY(BlueprintReadOnly, Category = "Action State")
	EActionState ActionState;
};

 

이제 이 변수를 계속 업데이트 해주어야 한다.

 

NativeUpdateAnimation() 함수에서 해줄 것이다. 그렇게 하기 위해서는 캐릭터 클래스에서 Getter를 만들어 이 값을 가져올 수 있게 해야한다.

 

값을 업데이트 하자

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

	if (KnightCharacterMovement && KnightCharacter)
	{
		GroundSpeed = UKismetMathLibrary::VSizeXY(KnightCharacterMovement->Velocity);
		Velocity = KnightCharacter->GetVelocity();
		IsFalling = KnightCharacterMovement->IsFalling();
		CharacterState = KnightCharacter->GetCharacterState();
		ActionState = KnightCharacter->GetActionState();
	}
}

 

이제 애니메이션 블루프린트에서 이 값을 쓸 수 있다.

 

메인스테이트 애니메이션 블루프린트에서 변수를 추가해주자.

 

 

물론 변수만 추가했다고 끝이 아니라 실제로 이 변수에 값을 집어넣어주어야 한다. 그 작업은 좀 있다 하려고 한다.

 

데드 스테이트의 변환조건에 들어간뒤 이 액션스테이트를 비교하자.

 

 

이제 에일리어스를 상세설정하자

 

 

죽음 상태로는 모든 스테이트에서 넘어올 수 있을 것이다. 그렇기에 모든 스테이트를 체크해주었다.

 

이제 데드 스테이트에서 실제로 애니메이션을 재생해보자.

 

 

블렌드 포즈로 애니메이션을 가져올 것인데 이럴려면 데스포즈 변수도 필요하다. 다시 추가하자

 

UPROPERTY(BlueprintReadOnly, Category = "Action State")
EDeathPose DeathPose;

 

애님인스턴스 클래스에서 추가해줄것이다.

 

추가했으면 업데이트도 해주어야하고 그렇게 하기 위해서 다시 Getter를 만들 필요가 있다.

 

DeathPose = KnightCharacter->GetDeathPose();

 

 

컴파일하고 에디터로 돌아가자

 

액션스테이트에서 했던 작업과 동일한 작업을 다시 하면 된다.

 

 

 

이제 이 변수들에 실제로 값을 넣어주는 작업을 해야한다.

 

메인스테이트 애니메이션 블루프린트의 변수들은 메인 애니메이션 블루프린트에서 값을 할당받고 있다.

 

 

여기서 변수를 바인딩 해주자. 그전에 이 링크드 애님 그래프 노드를 삭제하고 다시 만드는 게 혹시 모를 버그 예방에 좋다고 하니 삭제하고 다시 만들어주자.

 

 

바인딩을 완료해주면 된다.

 

이렇게 하면 완성이 된다. 중간에 데스 상태가 정상적으로 안되는 버그가 있었는데

void AKnight::GetHit_Implementation(const FVector& ImpactPoint, AActor* Hitter)
{
	Super::GetHit_Implementation(ImpactPoint, Hitter);

	if (IsAlive()) // 조건문 추가
	{
		SetWeaponCollisionEnabled(ECollisionEnabled::NoCollision);
		ActionState = EActionState::EAS_HitReaction;
	}
}

 

Hit 함수에서 조건문을 추가해서 죽었을때는 HitReaction으로 안 가게 수정하였다.

 

또한 죽었을때 콜리전도 없애주었다.

 

void AKnight::Die()
{
	Super::Die();

	ActionState = EActionState::EAS_Dead;
	GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
}