이번 프로젝트에서 담당한 부분이 캐릭터이어서, 자연스러운 애니메이션을 만들고 싶어서 공부한 내용과 적용해 본 것을 정리해 보았다.
1. Motion Matching
1 - 1. 이슈
현재 상황에 있어서 가장 적합한 애니메이션을 찾아서 해당 애니메이션을 재생해주는 시스템이다.
- 정확한 동작 원리나 방식은 이해하지 못했지만, 여러 튜토리얼 영상을 통해 사용하는 법을 알게되어서, locomotion에 있어서 모션매칭 시스템을 적용하게 되었다.
- 참고로 모션 매칭을 사용하려면, 플러그인에서 아래 플러그인을 활성화 해야 한다.
- motion trajectory
- pose search
- chooser
- 가장 도움이 되었던 영상 공유
https://youtu.be/j8RgsganqRU?si=0NPtCiB3Fd6y722I
현재까지 이해한 내용은 크게 아래 세가지로 나눌 수 있다.
- 포즈 서치 스키마 : 여러 채널을 통해서 현재 상황에 맞는 애니메이션을 골라주는 가장 기본적인 시스템
- 포즈 서치 데이터베이스 : 포즈 서치 스키마를 통해 선택할 애니메이션들이 저장되어있는 데이터베이스
- Chooser : 특정 상황에 따라 포즈 서치 데이터베이스를 변경해주는 시스템 (변수를 통한 변경이 가능하다)
처음에는 chooser까지 써서 애니메이션 구성을 해보았지만, Jump 관련된 부분에 있어서 잘 동작하지 않아서 캐릭터 만들때 사용한 스테이트 머신과 섞어서 사용해 보자는 생각을 하게 되었다. 캐릭터는 팀 프로젝트에 있어서 빠르게 프로토타입을 만들어서 테스트할 수 있도록 해야하기에 추후 기능들이 구현된다면, Chooser에 대해 공부해 볼 생각이다.
1 - 2. 모션 매칭 구현
1. 포즈 서치 스키마를 만들고
2. 포즈 서치 데이터 베이스를 위에서 만든 포즈서치 스키마를 기반으로 만든 후, 우리가 원하는 에셋을 모두 선택해서 넣어주면 된다.
- 이때, Idle, Run, Walk 모든 애니메이션을 한번에 다 넣고 실행하니 동작이 부드러워져서, 해당 애니메이션을 모두 넣었다.
- 동작이 어색한 부분이 있다면, 리와인드 디버거와 디테일을 사용해서 어색한 애니메이션을 찾아서 데이터베이스에서 제거하는 방식으로 구현하였다.
- 리와인드 디버거는 아래와 같이 테스트할 캐릭터를 선택한 후 녹화 버튼을 누르면 멈추기 전까지 동작이 녹화되고
- 다시 돌려보면서, 확인할 수 있다. 아래와 같이 해당 시점에 어떤 애니메이션이 사용되었는지 볼 수 있어서 이상한 동작을 발생시키는 애니메이션을 찾아서 데이터베이스에서 제거하는 식으로 유용하게 사용할 수 있다.
캐릭터 AnimGraph에서 모션 매칭은 아래와 같이 세팅했다.
- Motion Matching 노드에서는 만들어둔 DataBase를 넣어주고
- Pose History노드에는 궤적 생성을 선택해 주었다.
- cache pose에 저장하지 않고 바로 Output pose에 연결해도 잘 동작한다.
- 그러나 나중에 다른 State에서 사용하고, Blend Pose를 위해서 cache pose로 저장하였다.
2. State Machine
Chooser로 제대로 구현하지 못한 Jump를 캐릭터 관련 구현을 하면서, 만든 State Machine을 사용해서 Jump 가 자연스럽게 동작하도록 구현하였다.
- State 를 Main State라고 이름을 짓고 이 또한 Cache pose로 저장하였다.
- 내부는 아래와 같이 구성하였다. (자세한 세팅은 여기로)
3. Blend Pose
예전에 애니메이션을 사용할 때 언리얼에 Blend Pose라는 기능이 있었던 것이 생각이 나서, 다시 한번 찾아보고 적용하게 되었다.
적용하게 된 계기는 캐릭터가 총을 장착했을 때 상체는 캐릭터가 총을 장착한 모션으로 바뀌는 대신 하체는 기존의 애니메이션을 사용할 수 있게 하기 위함이다.
3 - 1. Blend Pose by int
이 방식은 int 타입의 값을 통해 어떤 pose를 선택할지 골라주는 방식이다.
구현 로직
- 캐릭터가 무기를 가지고 있다면, 1키를 눌러 blend pose variable 이라는 변수를 1로 바꿔준다.
- 그러면 그때 상체 애니메이션이 총기를 든 애니메이션으로 바뀌게 되고,
- 다시 캐릭터가 무기를 들고 있는 상태에서 1키를 누르면 해당 변수를 0으로 되돌려주어
- 총기를 들지 않은 애니메이션으로 바꿔준다.
- blend 된 애니메이션을 cache pose로 저장해 두고, 아래와 같이 Layered blend per bone이라는 노드를 통해서 상체라고 인식하게 될 bone을 지정해 주었다(spine_01)
- 해당 노드를 바로 Output pose에 연결해도 동작하지만, 다시 Cache pose에 넣은 이유는 캐릭터가 점프를 할 때 어색한 모습이 나와서 해당 문제를 해결하기 위해서 였다.
3 - 2. Blend Pose by bool
위에서 언급한 문제점인 점프가 제대로 동작하는 않는 문제를 해결하기 위해 무기를 들고 있지 않는 상황에서는 upper body 애니메이션을 사용하지 않고, main state만 사용하고 싶어서 해당 노드를 찾게 되었다.
- blend poses by bool은 int와 마찬가지로 bool값에 따라 포즈를 blend 해주는데,
- weapon equipped 라는 변수를 통해 캐릭터가 무기를 들고 있는지 아닌지를 체크하여, 결과 애니메이션을 만들었다.
- 무기를 들고 있을 때와 아닐 때 값을 변경해주는 부분은 아래 cpp 코드에서 구현했다.
//equip weapon
void APlayerCharacter::EquipWeapon1(const FInputActionValue& value)
{
//equip -> idle
if (bIsWeaponEquipped)
{
BlendPoseVariable = 0;
bCanFire = false;
bIsWeaponEquipped = false;
if (CurrentWeapon)
{
FName WeaponSocket(TEXT("back_socket"));
CurrentWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, WeaponSocket);
}
return;
}
//idle->equip
if(!bIsWeaponEquipped && IsValid(CurrentWeapon))
{
BlendPoseVariable = 1; //for animation
bCanFire = true; // for attack
bIsWeaponEquipped = true;
FName WeaponSocket(TEXT("hand_socket"));
CurrentWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, WeaponSocket);
}
}
- 최종 동작 모습은 아래와 같다.
참고) 모션 매칭을 안쓰고 자연스러운 애니메이션을 만들때 Blend Space를 쓸 수 있다
https://www.youtube.com/watch?v=P2X4luGMxDA
'Unreal Engine' 카테고리의 다른 글
UE5 Issues : 캐릭터 아이템 획득 로직 구현 (0) | 2025.02.24 |
---|---|
UE5 Issues : Enhanced Input (Triggered & Started) (0) | 2025.02.23 |
UE5 Issues : 이모저모 (0) | 2025.02.13 |
Unreal Engine - 3D UI (0) | 2025.02.13 |
Unreal Engine - UI Animation (0) | 2025.02.13 |