[UE5] Lena: Dev Diary #2 - Animation State Machine의 여러가지 상태변화 방법

ChangJin·2024년 6월 7일
0

Unreal Engine5

목록 보기
93/114
post-thumbnail

2024.06.07

깃허브!풀리퀘!
https://github.com/ChangJin-Lee/SimpleShooter https://github.com/ChangJin-Lee/SimpleShooter/pull/2

HUD 패널에서 체력바를 나타내는 기능을 구현했고, 캐릭터가 죽었을 때 나오는 애니메이션이 정상적으로 작동하도록 만들었다.

진행상황

  • ✅ 적 캐릭터의 이동, 공격 구현
  • ✅ 적 캐릭터의 플레이어 추적 구현
  • ✅ 캐릭터 사망 애니메이션
  • ⬜ 더 다양한 캐릭터가 적으로 등장하기
  • ✅ HUD에서 플레이어의 체력이 등장하지 않음




HUD 체력 바 등장하지 않던 문제

  • 체력 바가 등장하지 않던 문제는 기존에 플레이어 클래스로 사용하던 "ShooterCharacter"를 Cast TO로 받아와서 이 클래스에 있는 Get Health Percent() 함수를 실행하고 있었기 때문이었다.

  • 바뀐 이름으로 클래스를 업데이트 해주고 노드를 정상적으로 연결시켜주니 해결되었다.

수정 전수정 후


죽음 Animation 실행

  • Animation Blueprint에서 State Machine을 죽음 관련 스테이트를 기준으로 상태변환을 하면 된다라고 생각했다.

  • alsV4에서 매우 비슷한 로직을 찾을 수 있었는데 여기선 죽었을 때를 Ragdoll 이라는 이름으로 표시하고 있었다.

  • 처음에는 이 애니메이션이 실행되는 시작지점을 찾아서 그 지점에 분기를 시퀀스를 만들고 Movement Sate를 Ragdoll로 바꾸면 되겠구나라고 생각했다.


기존 State MachinealsV4의 State Machine
기존 State Machine 변환 로직alsV4의 State Machine 변환 로직


플레이 화면

  • 이렇게하면 정상적으로 바닥에 쓰러지지 않는다.

  • 원인은 Animation Blueprint에서 Ragdoll Override 부분에서 Blend Pose를 해서 사용하고 있는데 단순히 해당 애니메이션을 실행시키고 있기 때문이다.

ALS_Flail

  • 해당 애니메이션은 플레이 화면에서 보는 거처럼 떨어지고 있는 애니메이션이다.

ALS_Flail

  • 그럼 대체 어디서 저렇게 쓰러지는 애니메이션이 실행되고 있는 것일까?
Asset Browser

  • 에셋 브라우저를 다 뒤져봐도 죽음과 관련된 애니메이션은 없다.

  • Base_Character의 이벤트 그래프에서 Ragdoll로 검색을 해보았다.

  • 그랬더니 다음처럼 만들고 있었다. 즉 여러가지 애니메이션을 여기서 섞어서 사용하고 있었다.

바인드 액션


  • 저번과 마찬가지로 Base_Character 클래스에서 OnDead 라는 함수를 선언했다.
UFUNCTION(BlueprintImplementableEvent, Category = "Animation Slot")
void OnDead();
  • 그리고 IsDead() 라는 죽었을 때 내용을 처리하는 로직에서 해당 함수를 콜하는 형식으로 구현했다.
float ABase_Character::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser)
{
	float DamageToApplied = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);

	DamageToApplied = FMath::Min(Health, DamageToApplied);
	Health -= DamageToApplied;
	
	UE_LOG(LogTemp, Warning, TEXT("Health Left : %f"), Health);

	if(IsDead())
	{
		ASimpleShooterGameMode *GameMode = GetWorld()->GetAuthGameMode<ASimpleShooterGameMode>();
		if(GameMode != nullptr)
		{
			GameMode->PawnKilled(this);
		}
		DetachFromControllerPendingDestroy();
		GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
		OnDead();
	}
	
	return DamageToApplied;
}

  • 그 다음 기존에 사용하던 바인드 액션 로직을 가져와서 OnDead Event가 일어날 때 실행하도록 만들어주었다.

profile
게임 프로그래머

0개의 댓글