▲ '니케' 지스타 2021 시연 버전

'니케: 승리의 여신'은 김형태 시프트업 대표의 독특한 아트가 인상적인 모바일 슈팅 RPG다. 원화를 그대로 옮긴 듯한 게임 캐릭터가 특징이다. 특히, 캐릭터가 움직일 때마다 반응하는 머리카락과 엉덩이는 다른 게임보다 나은 생동감을 준다.

시프트업의 이제민 클라이언트 프로그래머가 '니케' 캐릭터 움직임 노하우를 '유니티 웨이브 2022'에서 전했다. 이제민 프로그래머는 개발자들 사이에서 닉네임 'retr0'로 알려진 인물이다. 그는 '레트로의 유니티 게임 프로그래밍 에센스' 책을 쓰기도 했다. 이제민 프로그래머는 알고리즘 준비 과정, 실제 구현 과정, 문제 해결 방법 순으로 설명했다.

▲ 시프트업 이제민 클라이언트 프로그래머

기본적으로 '니케' 캐릭터 움직임은 유니티 스파인 물리 시뮬레이션을 활용해 제작됐다. 이는 애니메이션과 물리를 혼합해 지원하고, 편집이 편리하다는 장점이 있다. 또한, '니케'에 중요한 머리카락과 엉덩이 흔들림 애니메이션을 따로 제작하지 않아도 되게 한다.

이제민 프로그래머는 '니케' 캐릭터의 머리카락과 엉덩이 움직임에 '훅의 법칙'이 적용됐다고 소개했다. 훅의 법칙은 물체가 원래 위치에서 벗어난 만큼, 반대 방향으로 힘이 생기는 경우다. 스프링이 대표적인 훅의 법칙 사례다.

대부분 경우 머리카락보다 머리가 먼저 움직인다. 자연스러운 머리카락 움직임을 위해 이제민 프로그래머는 머리카락에 해당하는 '자식 본'이 따를 수 있는 '부모 본'을 만들었다. 또한, 원활한 연산을 위해 '스켈레톤 본'과 '가상 본'으로 나누어 구현했다. 그는 게임 내에서 연산과 구현이 동시에 일어나기란 논리적으로 불가능해 나눴다고 설명했다. 스켈레톤 본이 애니메이션이 반영된 최신 본 위치를 가상 본에 전달하면, 가상 본이 계산해 새로운 위칫값을 스켈레톤 본에 내놓는다. 계산된 값은 스켈레톤 본에 전달된 뒤 쌓이지 않고 삭제되도록 했다.



▲ '니케' 캐릭터 머리카락에는 다양한 효과가 적용되어 있다

▲ 머리카락 움직임에 감쇠를 적용하는 게 중요하다. 감쇠를 적용하지 않으면 머리카락 움직임이 끝나지 않아서다.

시프트업은 머리카락 움직임, 엉덩이 움직임 계산을 병렬 연산으로 계산한다. 모든 스프링 본 위치를 동시에 부모에서 자식 방향으로 계산한다. 어떤 본이 먼저 계산될지 알 수 없다는 문제는 있으나, 시프트업은 성능을 위해 약간의 오차를 감수했다. 이제민 프로그래머는 물리 연산을 자주 실행하면 어느 정도 오차를 줄일 수 있다고 덧붙였다.

이제민 프로그래머 경험했던 문제는 계단 현상, 물리와 애니메이션의 혼합, 오버 슈팅 문제였다. 계단 현상은 머리카락이 물리에 의해 위치는 변하지만, 회전은 그대로여서 발생했다. 그는 부모에 회전 옵션을 추가해 부모 본이 자식 본을 따라 추가 회전하도록 구현해 문제를 해결했다고 전했다.

최종적으로 스켈레톤 본에 반영된 위치 값은 물리, 애니메이션, 여러 부가 트랜스폼 연산이 뒤섞인 값이다. 일반적으로 하나의 스켈레톤으로는 정보량이 부족해 제대로 구현이 힘들다. 이제민 프로그래머는 고스트 스켈레톤을 구현해 애니메이션만 반영했을 때의 위치와 물리만 반영했을 때의 위치를 나누어 관리해 문제를 해결했다. 이 값은 매 프레임 렌더링 직전에 혼합이 가능하다.








▲ '니케' 머리카락 움직임에 대한 코드 일부

오버 슈팅 문제는 현실과 게임의 차이로 발생한다. 현실 시간은 무한하게 쪼개지지만, 게임은 델타 타임으로 쪼개진 이산 시간이란 차이가 있다. 이로 인해 게임 내 스프링 본이 과하게 움직이거나, 본이 원래 이동할 경로를 벗어나 튕겨 나가는 문제가 발생할 수 있다. 간접적인 해결 방법으론 스프링 질량, 강성 값 등을 계속 다듬어 안정적이고 높은 FPS를 확보할 수 있다.

이제민 디렉터는 '니케'의 오버 슈팅 문제를 물리 연산을 더 짧은 단위로 자주 실행해 해결했다고 전했다. 직접적인 해결 방식이다. 다른 직접적인 방법으론 '오일러-크로머 방법'이 있다. 이제민 디렉터는 "어떤 방법으로도 완벽하게 해결은 불가능하지만, '니케'의 경우 연산을 더 자주 실행하는 것으로 보완했다"고 소개했다.

끝으로 이제민 디렉터는 '승리의 여신: 니케'의 머리카락과 엉덩이 흔들림을 스프링 물리 시뮬레이션으로 구현하고, 캐릭터 모델의 본과 물리 계산용 가산의 본을 나눠 사용했고, 성능을 위해 버스트(Burst) 컴파일러와 C# Job 시스템을 사용했으며, 물리와 애니메이션 혼합을 위해 고스트 스켈레톤을 사용했다고 요약했다.