게임에서 작은 맵에 계단 몇 개를 넣고 걷게 했더니 예상과 전혀 다른 일이 벌어졌는데요. 5cm짜리 낮은 턱 앞에서 캐릭터가 마치 거대한 벽에 부딪힌 것처럼 그 자리에 딱 멈춰진 것입니다.
실제 사람이라면 성큼 넘어갈 높이인데 캐릭터는 한 발자국도 나아가지 못했습니다. 원인을 찾아보니 이건 물리 충돌 처리 방식 자체의 문제였습니다. 이번 포스팅에서 이에 대해 자세히 알아보겠습니다.
충돌 처리기는 높이를 모른다
원인은 생각보다 단순했습니다. 대게의 간단한 충돌 처리는 캐릭터의 충돌 박스가 장애물의 옆면에 닿았는지만을 판단하는데요. 해당 로직 입장에서는 5cm짜리 턱이나 5m짜리 턱이나 똑같은 “옆면에 닿은 장애물”일 뿐입니다.
별도의 예외 처리가 없다면 사람 눈에는 우습게 넘어갈 수 있는 낮은 턱에도 게임 속 캐릭터는 아주 거대한 벽을 마주친 것처럼 그대로 멈춰버리게 됩니다. 원인을 파악하고 나니 해야 할 일이 명확해졌습니다. 필요한 건 “이 정도 높이에 한해서는 그냥 넘어가도 된다.”는 예외 처리 하나였습니다.
해결책, 스텝 오프셋
이 문제는 게임 업계에서 이미 표준적으로 다뤄지는 문제였습니다. 유니티의 공식 스크립트 레퍼런스는 CharacterController의 stepOffset 속성을 “캐릭터가 어딘가로 이동할 때 자동으로 넘을 수 있는 최대 높이(미터 단위)”라고 정의하고, 이 값을 이용하여 돌출부나 계단 같은 미세한 장애물들을 부드럽게 통과할 수 있게 제작한다고 설명합니다.
쉽게 말해 장애물의 높이가 설정한 값보다 낮으면 캐릭터를 그 높이만큼 빠르게 끌어올려서 계속 걸을 수 있도록 하고, 설정한 값보다 높으면 원래대로 앞으로 나아가지 못하게 하는 것입니다.
코드로 직접 확인해보니
이 동작을 파이썬을 이용해서 그대로 구현해봤는데요. 게임 속 캐릭터가 초당 2m로 앞으로 나아가다가 정해진 위치에서는 다양한 높이의 장애물을 만난다고 설정하고 스텝 오프셋이 없는 네이브 버전과 스텝 오프셋(30cm로 세팅)을 적용한 버전 각각에서 1초 뒤 캐릭터가 실제로 얼마나 전진했는지 체크해보았습니다.
결과는 명확한 계단식 그래프로 나타났는데요. 네이브 버전은 장애물 높이가 5cm든 60cm든 관계없이 장애물을 만나는 그 즉시 전진 거리가 1m에서 멈췄습니다.(장애물이 아예 없을 때는 2m를 전진할 수 있었습니다.)
이와 달리 스텝 오프셋을 세팅한 버전은 장애물의 높이가 30cm 이하일 때는 마치 장애물이 없는 것처럼 2m를 전진할 수 있었고 30cm를 넘어가는 순간부터는 네이브 버전과 마찬가지로 1m에서 멈췄습니다. 30cm라는 세팅 값을 기준으로 정확하게 나뉘어지는 이 결과는 스텝 오프셋이 “일정 높이까지는 장애물을 없는 것으로 치고 그 이상은 진짜 장애물로 취급합니다.”라는 단순하지만 실용적인 규칙이라는 것을 수치로 보여줍니다.

오프셋을 무작정 키우면?
실험 결과만 따지고 보면 스텝 오프셋 값을 최대한 크게 설정하는 것이 이득처럼 보일 수가 있는데요. 그러나 실제로 그렇게 실행에 옮기면 다른 문제가 발생하게 됩니다. 스텝 오프셋 값을 예를 들어 2m처럼 극단적으로 높게 설정해두면 게임 속 캐릭터 허리 높이의 낮은 담벼락까지도 계단인 것처럼 순간 이동하듯 타고 올라가 버리기 때문에 물리적으로 현실적이지 않은 움직임이 구사됩니다. 유니티의 문서에서도 이 값이 높을 수록 불규칙한 지형이나 계단같은 지형은 잘 통과할 수 있지만 너무 높게 세팅하면 비현실적인 움직임이 발생할 수 있다고 명백히 밝히고 있습니다.
게다가 이 세팅값 하나로 지형 문제가 모두 해결되는 것이 아닙니다. 유니티 문서는 스텝 오프셋이 경사 제한 설정과 함께 맞물려서 작동하며 장애물의 경사가 가파르면 스텝 오프셋 범위 안에서도 이동이 막힐 수 있다고 얘기한 적이 있습니다. 다시 말해 이번 포스팅에서 직접 진행한 실험에서는 캐릭터가 정면으로 전진하는 것만 다루었는데 실제 게임에서는 완만한 경사로를 만나거나 비스듬한 각도로 접근하는 경우까지 함께 다루어야 한다는 뜻입니다. 즉, 스텝 오프셋은 정답이 있는 것이 아니라 “사람이 계단이라고 인식할 만한 높이”에 맞추어서 다른 도구들과 함께 조정하고 타협해야 하는 튜닝 값에 가깝다고 할 수 있습니다.
결국 숫자 하나의 문제
게임 속 캐릭터가 계단에서 이상하게 통통 튀지 않고 자연스럽게 올라갈 수 있었던 이유는 충돌 판정에 숨어 있는 이 세팅값 하나가 전부였습니다.
여러가지 효과를 추가하거나 화려한 애니메이션을 추가 하기 전에 캐릭터가 이상하게 낮은 턱에 걸려 멈추는 버그부터 없애는 것이 게임의 완성도와 이용자의 만족도를 끌어올릴 수 있는 방법이라는 것을 이번 글의 실험을 통해 확인하였습니다. 마지막으로 본 포스팅에서 언급한 오프셋을 무작정 키웠을 때의 단점을 잘 고려해서 독자 분들이 보다 나은 게임을 만들 수 있도록 기원하겠습니다.