개발/Unreal Engine / / 2022. 1. 22. 22:50

Learning Unreal 4 언리얼 공부일지 - 애니메이션 적용하기

반응형

애니메이션을 조작하고 싶다면, 우선 static mesh가 아닌 뼈대가 있는 skeletal mesh의 디테일란에 Animation란이 있다.여기서 애니메이션을 선택해서 적용할 수 있는데, 애니메이션 클래스를 이용해서 조작해보자.

 

엔진에서 C++ 클래스 중 AnimInstance를 이용한다.

 

블루프린트로도 해보도록 하자.

블루프린트 클래스 중 애니메이션 파트에 애니메이션 블루프린트를 부모 클래스를 C++클래스로 지정하고, 타깃 스켈레톤을 지정해서 생성하자.

 

애니메이션 블루프린트에서는 위 그림과 같이 최종 애니메이션 포즈를 설정할 수 있다. 에셋 브라우저 창에서 필요한 애니메이션을 드래그해서 연결한다.

 

이를 캐릭터에 적용하고 싶다면, 

캐릭터 블루프린트에서 Animation Mode를 Blueprint로 설정하고, Anim Class를 생성한 애니메이션 블루프린트로 설정하면 된다.

 

참고로 위 그림처럼 실행중인 애니메이션을 구분하는 효과를 보기 위해서는 디버그 필터를 원하는 애니메이션으로 설정 한다.

 

지금 하려는 것은 speed라는 값을 이용해서 idle과 뛰는 상태를 구분하여 각각 애니메이션으로 표현할 것이다.

speed라는 변수가 필요해서 다음 코드와 같이 AnimInstance 클래스의 헤더에 변수 Speed를 추가했다.

UCLASS()
class UNREALINTRODUCTION_API UMyAnimInstance : public UAnimInstance
{
	GENERATED_BODY()
	
private:
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Pawn, Meta = (AllowPrivateAccess = true))
    float Speed;
};

 

위 그림은 애니메이션 블루프린트의 그래프를 작성한 모습니다.

Speed value 노드와 이어진 노드는 값의 크기를 비교하여 결과를 bool로 반환하는 노드이다.

결과에 따라서 포즈를 바꾸는 것을 'bool로 포즈 블랜딩' 노드가 실행한다. false이면 idle, true이면 jog_fwd라는 애니메이션을 재생한다.

 

speed변수에 캐릭터(pawn class)의 속도값을 담는 코드가 AnimInstance.cpp에 필요하다.

#include "MyAnimInstance.h"

void UMyAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
	Super::NativeUpdateAnimation(DeltaSeconds);

	auto pawn = TryGetPawnOwner(); // Pawn에 해당하는 인스턴스가 있는지 없는지 여부상관없이 받아옴
	if (IsValid(pawn)) // pawn이 null인지 체크
	{
		Speed = pawn->GetVelocity().Size(); // pawn의 값을 추출.
	}
}

Super 클래스는 해당 클래스의 부모 클래스를 의미한다.

TryGetPawnOwner를 통해 애니메이션이 할당된 Pawn의 정보를 가져오고, Pawn의 속도를 speed에 저장한다.

 

위 애니메이션 블루프린트의 AnimGraph그림을 보면 'bool로 포즈 블랜딩'에 블랜드 시간 값이 있다. 즉 애니메이션이 다른 것으로 교체될 때 자연스럽게 매꿔주는 블랜딩 기능이 자동으로 할당되는 것이다. 유니티에서였다면 블랜딩을 따로 설정해주어야하는데 언리얼의 블루프린트는 더 쉽게 되어있다.

 

이번에는 상태에 따라서 다른 애니메이션이 발동되도록 스테이트 머신을 사용해보자.

그래프에서 스테이트 머신을 생성해 최종 포즈에 연결하고, 스테이트 머신으로 들어가면 위 그림에서 Entry만이 있다.

여기에 스테이트를 추가해서 연결하고, 각 스테이트로 클릭해서 들어가면, 해당 스테이트에서 실행될 애니메이션만을 따로 구분해놓을 수 있다.

 

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Pawn, Meta = (AllowPrivateAccess = true))
	bool IsFalling;

점프하고 떨어지는 것을 구분하기 위해 AnimInstance 헤더에 IsFalling이라는 bool변수를 추가했다.

 

#include "MyAnimInstance.h"
#include "GameFramework/Character.h"
#include "GameFramework/PawnMovementComponent.h"

void UMyAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
	Super::NativeUpdateAnimation(DeltaSeconds);

	auto Pawn = TryGetPawnOwner(); // Pawn에 해당하는 인스턴스가 있는지 없는지 여부상관없이 받아옴
	if (IsValid(Pawn)) // pawn이 null인지 체크
	{
		Speed = Pawn->GetVelocity().Size(); // pawn의 값을 추출.

		auto Character = Cast<ACharacter>(Pawn); // pawn을 Character로 변환
		if (Character) // null 체크
		{
			// movement component의 IsFalling함수의 결과를 대입
			IsFalling = Character->GetMovementComponent()->IsFalling(); 
		}
	}
}

cpp파일에는 IsFalling을 이용하여 떨어지는 상태를 체크하는 기능을 추가하였다.

PawnMovement에는 게임에서 많이 사용되는 기본적인 함수들이 포함되어있다. IsFalling함수도 그 중 하나일 것이다.

 

점프기능을 추가하기 위해 InputComponent를 다음 코드로 추가하자.

PlayerInputComponent->BindAction(TEXT("Jump"), EInputEvent::IE_Pressed, this, &AMyCharacter::Jump);

 

 

키보드와 매핑하기 위해 엔진의 프로젝트 세팅 → 입력에서 액션 매핑에 스페이스바를 추가하자.

 

 

떨어지는 상태에서는 별도의 애니메이션을 적용해보자.

위 그림에서 스테이트가 Ground에서 Jumping으로 넘어가는 데에는 조건이 필요하다. 이 조건을 설정하는 것은 스테이트 사이에 넘어가는 화살표 엣지를 클릭하면 설정할 수 있다.

 

참고로 그래프로 끌고올 변수가 보이지 않는다면, 내 블루프린트 창의 검색창 옆 눈모양의 메뉴 중 상속된 변수 표시를 체크하면 보일 것이다.

 

엣지를 클릭하면 조건을 생성하는 그래프가 나오는데, Falling → Ground에서는 위와 같이 IsFalling 변수가 false일 경우 상태를 변경하도록 설정하고, 반대의 경우는 true일때 변경하도록 설정하면, IsFalling이 true 상태일 때 애니메이션 스테이트가 Jumping상태로 전환될 것이다.

 

점프하는 애니메이션은 한 번 동작하고 떨어지는 모션으로 이동한다. 즉 점프하는 애니메이션은 한 번만 수행되어야 하므로 디테일에서 loop animation을 체크 해제한다.

 

위 조건 그래프는 Time Remaing의 값이 0.1보다 작을 경우 스테이트 상태를 변환한다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유