Home [UE5 TPS 제작기] 7. AnimInstance
Post
Cancel

[UE5 TPS 제작기] 7. AnimInstance

1. AnimInstance란?

AnimInstance는 애니메이션을 만들기 위해 필요한 데이터들의 집합이라 볼 수 있다.
 
즉,
애니메이션에 필요한 데이터가

  • 캐릭터 이동 속도
  • 공중에 있는지 여부
  • 죽었는지 여부

이 있다고 하면 AnimInstance에서 위 데이터들을 관리하고
애니메이션은 AnimInstance에서 데이터를 참조해 최종 애니메이션을 재생한다.
 
그래서 애니메이션 블루프린트를 생성하려고 하면 부모 클래스는 AnimInstance가 되는 것을 볼 수 있다.

img

2. AnimInstance 코드 생성

블루프린트로 작업할수도 있지만 CPP로 하면 초기 상태나 변수 상태를 코드로 조작할 수 있기에 CPP로 생성한다.
 

2-1. 부모 클래스 선택

부모 클래스는 AnimInstance를 선택하자!

img_1

2-2. 변수 및 메서드 선언

애니메이션을 만들 때 필요한 정보는 일단 아래와 같이 정리할 수 있을 것 같다.

  • 애니메이션 블루프린트를 소유하고 있는 Pawn 객체 변수
  • 움직이는 속도
  • 움직이는 방향
  • 공중에 있는지 여부

코드로 변환하면 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
UPROPERTY(EditAnyWhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
float _movementSpeed;

UPROPERTY(EditAnyWhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
float _direction;
    
UPROPERTY(VisibleAnywhere, meta = (AllowPrivateAccess = "true"))
bool _bIsInAir;

UPROPERTY(EditAnyWhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class APawn* _playerPawn;

그리고
3개의 멤버 변수 값들을 애니메이션이 진행되는 동안 계속 갱신될 수 있도록 UpdateProperties() 라는 변수를 만들어줄 것이다.

1
2
UFUNCTION(BlueprintCallable, Category = "Update Properties")
void UpdateProperties();

애니메이션 업데이트 될 때마다 UpdateProperties()를 호출할 수 있도록 NativeUpdateAnimation(float DeltaSeconds) 가상 함수를 오버라이드 한다.

1
virtual void NativeUpdateAnimation(float DeltaSeconds) override;

마지막으로
애니메이션 블루프린트가 시작할 때 변수들을 초기화하고 싶기 때문에 NativeInitializeAnimation() 가상 함수를 오버라이드할 것이다.

1
virtual void NativeInitializeAnimation() override;

2-3. NativeInitializeAnimation

코드를 추가로 작성하기 전에 NativeInitializeAnimation()에 대해 좀 더 알아보자.
 
아래 코드는 공식 문서에서 그리고 UAnimInstance class에 적힌 주석 글처럼
“애니메이션 각 단계에 대한 초기화를 재정의하는 함수”라고 볼 수 있을 것 같다.

액터의 InitializeComponent 또는 BeginPlay 메서드와 유사하다

 UAnimInstance::NativeInitializeAnimation

1
2
3
4
5
// the below functions are the native overrides for each phase
// 번역: 아래 함수는 각 단계에 대한 기본 재정의입니다.
// Native initialization override point
// 번역: 기본 초기화 재정의 지점
virtual void NativeInitializeAnimation();

2-4. NativeUpdateAnimation

NativeUpdateAnimation(float DeltaSeconds) 메서드는 애니메이션이 업데이트 될 때마다 재정의해주는 것이라 볼 수 있다.

액터의 Tick(float DeltaTime) 메서드와 유사하다.

1
2
3
// Native update override point. It is usually a good idea to simply gather data in this step and 
// for the bulk of the work to be done in NativeThreadSafeUpdateAnimation.
virtual void NativeUpdateAnimation(float DeltaSeconds);

2-4. CPP 구현

이제 메서드를 하나씩 구현해 보자.
 
일단 NativeInitializeAnimation() 먼저 구현해 보자.
TryGetPawnOwner()를 통해 해당 애니메이션 블루프린트를 소유한 Pawn 객체를 얻는다.

1
2
3
4
5
6
7
8
void UCharacterAnimInstance::NativeInitializeAnimation()
{
	Super::NativeInitializeAnimation();
	if (_playerPawn == nullptr)
	{
		_playerPawn = TryGetPawnOwner();	// 소유자의 Pawn를 가져온다.
	}
}

그다음 UpdateProperties()를 통해 변수들의 상태를 업데이트해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void UCharacterAnimInstance::UpdateProperties()
{
	if (_playerPawn == nullptr)
		_playerPawn = TryGetPawnOwner();

	if (_playerPawn)
	{
    	// 공중에 있는지
        _bIsInAir = _playerPawn->GetMovementComponent()->IsFalling();
        
        // Z축이 필요없기 때문에 Z는 0.f로 처리해서 속력를 구한다
        FVector velocity = _playerPawn->GetVelocity();
        velocity = FVector(velocity.X, velocity.Y, 0.f);
        _movementSpeed = FVector(velocity.X, velocity.Y, 0.f).Size();
        
        // AnimInstance에 있는 CalculateDriection() 메소드를 통해 방향을 구한다.
        _direction = CalculateDirection(velocity, _playerPawn->GetActorRotation());
	}
}

그리고 UpdateProperties()를 NativeUpdateAnimation(float DeltaSeconds)에서 호출해 매 업데이트마다 호출되도록 한다.

1
2
3
4
5
void UCharacterAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
	Super::NativeUpdateAnimation(DeltaSeconds);
	UpdateProperties();
}
This post is licensed under CC BY 4.0 by the author.

[UE5 TPS 제작기] 5. 마우스로 시야 움직이기

[UE5 TPS 제작기] 6. 위, 아래를 볼 때 캐릭터 이동 속도가 느려지는 버그 수정법