같은 게임에서 같은 절벽에 매달리는 상황인데도 불구하고 어떨 때는 손이 허공에 뜨거나 벽 속으로 살짝 파고든 것처럼 보이고 어떨 때는 정확히 모서리를 잡고 있는 것처럼 보인 적이 있을 것입니다. 이 차이는 게임의 퀄리티 문제가 아닌 캐릭터가 절벽으로 다가가는 속도에 따라 실제 충돌하는 위치가 다르기 때문에 생기는 문제인데요. 이번 글에서 이 문제와 그 해결책인 렛지 스냅(Ledge Snap)을 코드로 구현해서 체크해보겠습니다.
손의 위치가 매번 다르다
게임 속 캐릭터의 위치는 보통 매 프레임마다 일정한 거리씩 움직이면서 달라지는데요. 문제는 절벽 모서리가 그 이동 간격의 배수에 정확히 맞아 떨어지는 위치에 있으라는 규정이 없다는 점입니다. 캐릭터는 모서리를 정확히 밟는 것이 아니라 모서리를 넘어선 것을 감지한 바로 다음 프레임에서야 스탑하기 때문에 그 프레임의 이동 거리만큼 항상 좀 더 들어간 위치에서 멈추게 됩니다.
이걸 파이썬을 이용해서 직접 확인해봤는데요. 캐릭터가 초당 2m부터 12m까지 여러 속도로 절벽에 다가온다고 전제하고 매 프레임 이동 후 충돌을 인지해 멈추는 위치가 실제 절벽 모서리에서 얼마나 이탈하는지 체크했습니다. 결과는 속도가 빠를 수록 더 크게 이탈하였습니다. 초당 2m로 캐릭터가 다가왔을 때는 오차가 0.3cm 밖에 되지 않았지만 초당 12m로 다가왔을 때는 오차가 17cm까지나 벌어졌습니다. 또한 이 오차는 속도에 딱 정비례하는 것도 아니었습니다.(8m/s와 10m/s에서 우연히 같은 10.3cm가 나옴) 프레임 이동 거리와 절벽까지의 거리가 어떻게 부합하느냐에 따라 오차가 불규칙하다는 뜻입니다.

실제로는 이렇게 구현한다
이렇게 불규칙한 위치에서 캐릭터를 그대로 붙잡게 두면 안되니, 실제 게임에서는 별도의 조정 단계를 거치게 되는데요. 게임 개발자 제이콥 해밀턴은 본인의 블로그에서 렛지 그랩 기능을 적용한 방식을 세상에 공개하였는데 매 프레임 캐릭터가 벽에 닿았는지 확인한 후 벽이 앞에 있는지 확인하기 위해 레이캐스트를 쏘고 지면과 밀접한지도 레이캐스트로 파악한다고 안내합니다.
그렇게 감지된 렛지 지점을 향해 캐릭터는 감지 지점과 같은 높이까지 위로 이동한 다음 그 지점을 향해 다시 이동하는 2단계 과정을 밟아 위치를 선정합니다.
이 원리를 그대로 시뮬레이션에 적용시켜보니 캐릭터가 다가오는 속도가 얼마든지 관계없이 최종적인 오차는 항상 0으로 나왔습니다. 감지까지는 네이브 버전과 똑같은 과정을 밟지만 감지된 다음에는 실제 물리 위치가 아니라 미리 계산된 렛지 지점으로 캐릭터를 옮기기 때문입니다.(이렇게 물리적으로 멈춘 위치를 무시하고 설정한 목표 지점으로 강제로 맞춰버리는 처리를 스냅이라고 부름)
스냅이 만능은 아니다
위 실험에서는 스냅을 이용해서 오차를 0으로 만들었지만 이건 위치 하나만 놓고 봤을 때의 이야기입니다. 절대 스냅 처리 하나로 모든 렛지 그랩이 자연스러워진다고 할 수는 없습니다.
이번 시뮬레이션은 캐릭터가 정면을 향해 곧장 접근하는 가장 단순하고 쉬운 상황만 다루었는데 실제 게임 상에서는 렛지 위쪽에 캐릭터가 올라갈 공간이 충분한지와 렛지가 기울어져 있는지도 함께 봐야 합니다. 해밀턴의 구현 방식에서도 게임 캐릭터를 감싸주는 벽 감지용 콜라이더와 별도로 렛지 자체를 감지하는 센서를 앞쪽에 따로 띄워두는 이중 구조를 쓰고 있습니다.
이는 벽에 닿았다는 사실만으로는 정확히 렛지 위치를 알 수가 없기 때문이에요. 더불어 스냅이 순간적으로 일어나면 캐릭터가 순간 이동을 하는 것처럼 보일 수가 있기 때문에 실제 게임에서는 애니메이션 재생 시간에 맞춰 스냅 이동을 부드럽게하는 처리까지 함께 적용합니다.
캐릭터가 다가오는 각도가 정면이 아니라 측면 혹은 대각선인 경우에도 캐릭터가 바라볼 방향과 렛지의 방향을 따로 계산해서 회전값까지 함께 스냅해주어야하니 위치 하나만 조정하는 것보다 실제로는 훨씬 더 힘든 작업이라고 할 수 있습니다.
결론: 정확함은 우연이 아니다
캐릭터의 손이 매번 정확히 절벽 모서리를 붙잡은 것처럼 보이는 것은 물리 연산이 우연히 잘 맞물려져서 나타난 결과가 아니라 감지된 지점으로 위치를 강제로 맞추는 스냅 처리 덕분이었습니다.
위에서 파이썬을 이용해 진행한 실험에서 체크했듯이 접근 속도에 따라 원래는 최대 17cm의 오차가 발생할 수 있었지만 스냅 처리 한 번으로 오차가 완벽하게 0이 되었습니다. 보다 완벽한 게임 개발을 하기 위해서는 물리적으로 정확한 지점보다 시각적으로 정확하게 보이는 지점을 따로 계산해서 조정하는 것이 필요하다는 것을 이번 글을 통해서 깨달았기를 바랍니다.