그동안은 최대한 블루프린트를 제외하고 C++만을 이용한 프로그래밍을 해왔다
그러나 애니메이션에서의 블루프린트가 굉장히 강력하기 때문에
애니메이션을 하는 동안은 블루프린트를 쓸 예정이다
2023-01-07 애니메이션 리타게팅 방식 추가
먼저 AnimInstance
클래스를 만들어주자
AnimInstance
는 언리얼 엔진에서 블루프린트를 통한 애니메이션 제작 도구이다
All Classes -> AnimInstance
를 통해 만들 수 있다
헤더 내용을 작성해준다
class ARENABATTLE_API UABAnimInstance : public UAnimInstance
{
GENERATED_BODY()
public:
UABAnimInstance();
virtual void NativeUpdateAnimation(float DeltaSeconds) override;
private:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Pawn, Meta = (AllowPrivateAccess = true))
float CurrentPawnSpeed;
};
CurrentPawnSpeed 값을 폰의 속도와 연동해 속도가 0초과라면 움직임이라 판단하고
애니메이션이 움직이도록 해줄 것이다
NativeUpdateAnimation()
함수를 통해 폰의 정보를 가져올 것이다
이후 cpp 파일을 작성해준다
UABAnimInstance::UABAnimInstance()
{
CurrentPawnSpeed = 0.0f;
}
void UABAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
auto Pawn = TryGetPawnOwner();
if (IsValid(Pawn))
{
CurrentPawnSpeed = Pawn->GetVelocity().Size();
}
}
TryGetPawnOwner()
함수를 통해 Pawn을 찾고,
Pawn 이 있다면 CurrentPawnSpeed 를 폰의 속도로 동기화 해주는 코드이다
이제 그렇다면 블루프린트를 통해 실제로 애니메이션을 연결해주도록 하자
언리얼 엔진 또한 유니티와 동일하게 FSM(Finite State Machine)으로 애니메이션을 제작하게 되어있다
FSM이란 여러개의 상태가 존재하고 그 상태들을 조건으로 엮는 기계를 뜻한다
우리는 땅에 있는지, 공중에 있는지 등을 나눠 애니메이션을 만들려 한다
먼저 상태(State)를 만들어줘야 하니 우클릭 후 state machine
을 만들어준다
이름을 BaseAction으로 바꾸고, 애니메이션을 연결해주었다
BaseAction에 들어간 후, add State
를 통해 Ground
state를 만들고,
Entry에서 Ground로 연결시켜주었다
Ground 안에서, 에셋 브라우저에 있는 WarriorRun과 WarriorIdle을 Ground 상태창에 올려둔다
우리는 CurrentPawnSpeed 변수가 0 초과시 Run, 아니라면 Idle 상태를 만들것이다
먼저 CurrentPawnSpeed 변수를 Ground 상태창에 올려두고
초록색 노드를 눌러 비교 연산자 >
를 찾는다
greater 노드에서는 빨간 노드(boolen)에서 Blend Poses by bool 을 만들어준다
이후 true일때는 Run, false 일때는 Ilde 애니메이션을 연결해주고,
블랜딩 되는 포즈를 Output에 연결해준다
blend Time은 적당히 자연스럽게 0.3 정도를 줬다
(완성된 모습)
컴파일 후 에디터 오른쪽 하단에서 Current Pawn Speed를 바꿔보며 잘 움직이는지 확인해 보자
먼저 input 창에 jump 액션을 추가해준다
다른 모션들은 함수를 선언해주었지만, ACharacter 클래스에는 기본적으로 Jump 함수가 내장되어 있다
그렇기에 Jump 함수의 바인딩만 해주면 된다
이번에는 Jump 중 착지할 때를 인지하도록 하겠다
Pawn 에서 제공하는 IsFalling()
함수를 통해 가능한데
animinstance 클래스에 IsInAir 변수를 두고 그 상태를 지켜보도록 하겠다
생성자에서 초기화해주는 것을 잊지말고
이후 cpp 파일에서 IsInAir변수를 IsFalling 과 연동시켜주자
void UABAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
auto Pawn = TryGetPawnOwner();
if (IsValid(Pawn))
{
CurrentPawnSpeed = Pawn->GetVelocity().Size();
auto Character = Cast<ACharacter>(Pawn);
if (Character)
{
IsInAir = Character->GetMovementComponent()->IsFalling();
}
}
}
여기까지 왔다면 이제 블루프린트에서 점프 모션을 추가해 줄 차례인데,
우리가 애니메이션에는 점프가 없기 때문에 언리얼 엔진 기본 마네킹 모션을 리타게팅해서 가져올 것이다
UE4에서는 리타게팅 매니저를 통해 리타게팅을 하였는데,
현재 UE5에서는 그 방법이 되지 없어진 상황이다
이 방식은 모든 스켈레톤에 가능한지는 모르겠으나, 현재 나의 상황에는 아무 문제가 없었기에 일단 기재하려고 한다
먼저 기본 애니메이션에서 Jump
, Fall_loop
, Land
3가지 애니메이션을 복사해준다
이 3가지 애니메이션을 우리 애니메이션 폴더로 붙여넣기 후, 우리 캐릭터의 스켈레톤으로 바꿔준다
이후 이름을 WarriorJumpStart 등으로 바꿔주자
Skeltal Mesh를 선택해 리타게팅 하는 방식을 찾았다
Duplicate and Retarget Animation Asset
을 클릭후 IK Retargeter
항목을 RTG_Mannequin
으로 설정
왼쪽에는 소스가 될 스켈레탈 메쉬, 오른쪽에는 내가 애니메이션을 얻고 싶은 스켈레탈 매쉬를 놓고 리타겟 버튼을 눌러준다
완성된 모습
블루프린트에서는 JumpStart
, JumpLoop
, JumpEnd
3가지 상태를 만들어주고,
각 각 Ground
-> JumpStart
-> JumpLoop
-> JumpEnd
-> Ground
로 이어주자
각각에 State에는 자신의 애니메이션을 연결해준다
Ground
에서 JumpStart
로 가는 화살표를 클릭 후, Is In Air 상태일때를 만들어주고,
JumpLoop
에서 JumpEnd
로 가는 화살표에는 Is In Air 에 Not 을 붙여주자
JumpStart
-> JumpLoop
와 JumpEnd
-> Ground
는 애니메이션이 끝나면
자동으로 다음 애니메이션이 나오는 Automatic Rule Based in Sequence in Player State
를 체크하자
이후 Is in Air 를 체크 해보며 잘 작동하는지 확인해보자
마지막으로 인게임 내에서도 실험을 해보자