언리얼 엔진 5/개발 일지

[UE5] 블루아카이브 TPS게임 개발일지 (5) - Mixamo Converter 사용, 구르기 구현

ciel45 2023. 12. 14. 18:07

지난 포스트 마지막에서, 코드를 통해 직접 구르기의 움직임을 구현하기가 곤란했었다.

 

 

이 경우 루트 모션(Root Motion)을 사용할 수 있다.

 

https://docs.unrealengine.com/5.3/ko/root-motion-in-unreal-engine/

 

루트 모션

언리얼 엔진의 루트 모션 애니메이션을 살펴봅니다.

docs.unrealengine.com

 

 

루트 모션 애니메이션을 사용하면 애니메이션 데이터로 캐릭터 무브먼트를 제어하여 레벨에서 보다 사실적인 무브먼트를 연출할 수 있습니다. ← 공식 문서의 루트 모션에 대한 설명이다.

 

 

 

간단히 말해서, 캐릭터의 움직임이 애니메이션 자체에 의해 결정되도록 하는 것이다.

 

 

그런데 구르기 애니메이션에 루트 모션을 적용하려고 하니 문제점이 있었다.

루트 모션을 적용하지 않은 정상적인 애니메이션

 

루트 모션을 적용한 애니메이션.(좌측 패널 가운데 Enable Root Motion가 체크되어있다.)

 

 

루트 모션을 사용하면 구르기 애니메이션이 허공에서 허우적 되는 모션으로 바뀌는 현상이 있었다.

 

이유를 알아보니 다음과 같았다.

 

 

 

 

현재 캐릭터와 애니메이션은 모두 Mixamo의 Auto-Rigging 시스템을 사용하고 있는데, Mixamo가 만들어주는 스켈레톤에는 root가 존재하지 않는다.

 

Root가 존재하지 않는 애니메이션에 루트 모션을 적용하려고 하면, 사진과 같이 애니메이션이 이상하게 바뀌어버리는 것이다.

 

 

 

 

다행히 스켈레톤에 루트 모션을 추가해주는 방법이 있었다. 다음 동영상의 도움을 많이 받았다.

https://www.youtube.com/watch?v=f32fzAuJyZU&t=1218s&ab_channel=DruidMechanics

블렌더를 활용해 Mixamo 스켈레톤에 root를 추가하는 방법을 알려주는 영상이다.

 

이곳에서 블렌더 애드온을 다운 받을 수 있다.

https://github.com/enziop/mixamo_converter

 

GitHub - enziop/mixamo_converter: Blender addon for converting mixamo animations to Unreal 4 rootmotion

Blender addon for converting mixamo animations to Unreal 4 rootmotion - GitHub - enziop/mixamo_converter: Blender addon for converting mixamo animations to Unreal 4 rootmotion

github.com

 

 

zip 파일로 애드온을 설치해준다.
우측 Mixamo 탭을 열어서 Input Path, Output Path를 지정해준 뒤 Input Path에 변환하고자 하는 FBX파일을 넣고 Batch Convert를 눌러준다.
그러면 output 폴더에 변환된 파일이 생겨난다. 루트가 포함된 구르기 애니메이션과 캐릭터 스켈레탈 메시를 얻었다.

 

기존의 캐릭터 스켈레톤. 루트가 존재하지 않는다.
Mixamo Converter로 얻은 새로운 스켈레탈 메시. 좌측 상단 패널에 root bone이 추가된 것을 볼 수 있다.

 

 

 

 

이제 스켈레톤에 루트가 추가된 새로운 캐릭터 스켈레탈 메시가 생겼으므로, 기존 것을 교체해야 한다.

Import 해놨던 애니메이션들을 모두 다시 새로운 스켈레톤 기준으로 다시 다운받기는 힘드니, IK Retargeter를 사용했다.

루트가 있는 스켈레톤과 없는 스켈레톤 간의 리타겟팅. 루트의 유무 외에 차이점은 없으므로 어려울 것은 없었다.

 

 

 

 

여기서도 한가지 문제점이 있었다. 걷기, 달리기와 같이 캐릭터의 몸이 흔들리는 애니메이션의 경우 루트가 있는 캐릭터 쪽으로 리타겟팅된 애니메이션은 몸이 흔들리지 않는 문제가 있었다.

 

https://boobiebird.tistory.com/55

 

[언리얼엔진 5] IK Retargeter with Root Motion

https://docs.unrealengine.com/5.0/ko/root-motion-in-unreal-engine/ 루트 모션 언리얼 엔진 4 에서 루트 기반 애니메이션을 처리하는 방식을 살펴봅니다. docs.unrealengine.com 언리얼엔진 4를 공부할 떄 역시 루트모션

boobiebird.tistory.com

 

 

다른 분의 포스팅에서 도움을 받았다. 

 

 

 

요약하자면, 새 스켈레톤의 루트의 리타겟팅 옵션을 Animation Scaled로 바꾸고, IK Retargeter의 RetargetRoot 체인의 Translation Mode를 Globally Scaled로 바꾸어주면 된다.

 

 

이렇게 해주니 기존 애니메이션이 잘 리타겟팅이 되는 것을 확인할 수 있었다.

 

 

 

이제 리타겟팅된 애니메이션들을 생성해주고, 애니메이션 블루프린트에서 애니메이션 시퀀스와 스켈레톤을 교체해주면 된다.

(포스팅 하는 시점에서 기존 애니메이션들을 모두 지워버려서 다른 Retargeter의 이미지로 대체) 변환할 애니메이션 선택 후 우측의 Export Selected Animaion을 눌러 리타겟팅된 애니메이션을 생성할 수 있다.

 

애니메이션 블루프린트의 스켈레톤 교체

 

 

 

이후 애니메이션 블루프린트 내부의 상태 머신에서 사용되는 애니메이션 시퀀스도 모두 교체해주었다.

 

 

 

여기까지 상당히 오랜 시간이 걸리고 귀찮았지만, 루트가 없는 스켈레톤을 계속 사용하면서 프로젝트가 커진 뒤 그제서야 스켈레톤을 교체하려고 했다면 더 골치아팠을 것 같다.

 

 

 

이제 구르기를 추가할 시간이다.

Mixamo Converter로 변환된 애니메이션은 루트 적용이 아주 잘 되었다.

좌측 EnableRootMotion를 체크하고도 잘 동작하고있다.

 

이제 스페이스바를 누르면 해당 애니메이션 시퀀스로 만든 애니메이션 몽타주가 재생되도록 했다.

그 결과 나쁘지 않은데, 뭔가 구르기 거리가 좀 짧은 느낌이 들었다. 속도감을 위해 구르기 거리를 늘리면 좋을 것 같았다. 

 

 

https://forums.unrealengine.com/t/rootmotion-how-to-change-roll-distance-with-the-same-animation/477658/2

 

Rootmotion - how to change roll distance with the same animation

I finally found my answer to this matter. Please follow the steps below for a sample change of the distance on your animation. Make copy of your animation first Open your new animation (duplicated from step 1) Open “Skeleton Tree” tab on the left side.

forums.unrealengine.com

이번에는 포럼의 도움을 받았다. 애니메이션 시퀀스에 키를 추가하여 이동 거리를 늘릴 수 있다.

 

root.Translation.Z의 키를 조정하여 이동 거리를 늘렸다.

 

그 결과 이동 거리가 잘 늘어났지만, 아직 한가지 문제점이 더 남았다.

 

총알이 빗발치는 상황에서 구르기는 회피로써의 기능도 해야하는데, 구르기를 해도 칸나의 캡슐 콜라이더는 줄어들지 않는다. 또한 이로 인해서 구르기로 낮은 장애물을 통과할 수도 없다.

 

 

 

그래서 구르는 동안은 콜라이더를 반으로 줄이는 코드를 넣었더니, 다음과 같은 현상이 발생했다.

캡슐 콜라이더가 가운데를 피봇으로 하여 줄어들어서, 캐릭터가 땅 속으로 들어가게 된다.

 

 

어떻게 해야 할 지 고민하던 중, 포럼에서 CharacterMovement에 이미 구현되어있는 Crouch()가 콜라이더를 바닥을 피봇으로 해서 줄여주는 기능을 해준다는 글을 보았다.

 

 

따라서 해당 함수를 사용해보았다.

주의해야 할 점이 Crouch는 GetCharacterMovement()->Crouch()가 아니고 그냥 Crouch()로 호출해야한다.

당연히 CharacterMovement의 멤버 함수로 구현되어 있을줄 알았는데 아니었던 모양이다.

저것 때문에 또 2시간을 날렸다.

 

 

그리고, 캡슐 콜라이더가 반으로 줄어들면 연결되어있는 카메라 스프링암의 위치도 바뀐다.

그래서 구르기를 시작할 때와 끝날 때 카메라가 뚝 뚝 움직이는 현상이 있었다.

따라서 스프링암을 캡슐 콜라이더가 아닌 메시에 붙이는 방식으로 바꿨다.

SpringArm->SetupAttachment(GetMesh());

 

 

 

 

내친김에 구를 때의 카메라 워킹도 만들어보았다.

조준 기능을 구현했을 때 처럼 Timeline 노드를 사용하였다.

 

주의할 점이, Timeline의 Play가 아닌 Play from Start에 연결해주어야 한다. Play는 타임라인을 종료된 이전 시점부터 재생하는데, 구르기는 항상 누를 때마다 처음부터 재생해야 하기 때문이다.
타임라인 내부

 

 

결과:

https://www.youtube.com/watch?v=m08An6I0ld4