[Unity/Physics] “내 캐릭터가 벽을 뚫는다?” 게임 물리 엔진의 주요 이슈 정리 (터널링, 고스팅 등)
게임 개발 중 물리 엔진(Physics Engine)은 가장 강력한 도구이자, 가장 큰 스트레스의 원인이기도 합니다. 분명히 콜라이더를 씌웠는데 적이 나를 통과해 가거나, 바닥에 발이 껴서 점프가 안 되는 현상들. 오늘은 이런 현상들을 부르는 전문 용어와 그 원인을 알아보겠습니다.
1. 터널링 (Tunneling) - “벽을 뚫는 총알”
가장 흔히 발생하는 문제입니다. 물체가 너무 빠르게 이동해서, 물리 엔진이 충돌을 검사하는 프레임 사이의 빈 공간에 벽이 위치할 때 발생합니다.
- 현상: 물체가 벽을 인식하지 못하고 그대로 통과함.
- 원인: 물리 연산은 불연속적인 시간() 단위로 이루어집니다. 프레임 1에서 벽 앞에 있던 물체가 프레임 2에서 이미 벽 뒤로 이동해버리면, 엔진은 “충돌하지 않았다”고 판단합니다.
- 해결법:
- Continuous Collision Detection: Rigidbody의 감지 모드를
Continuous 또는 Continuous Dynamic으로 변경합니다.
- Raycast 기반 예측: 이동하기 전, 이동할 거리만큼 미리 레이캐스트를 쏴서 충돌 여부를 먼저 확인합니다.
2. 고스팅 (Ghosting / Internal Edge Problem) - “매끄러운 바닥인데 왜 걸리지?”
여러 개의 콜라이더가 맞닿아 있는 평평한 바닥 위를 지나갈 때, 갑자기 무언가에 걸린 듯 툭 멈추거나 튀어 오르는 현상입니다.
- 현상: 매끄러운 바닥임에도 불구하고 타일과 타일 사이의 경계선(Edge)에 걸림.
- 원인: 물리 엔진이 인접한 두 콜라이더의 경계를 완벽하게 평면으로 인식하지 못하고, 미세하게 튀어나온 ‘모서리’로 판단해 충돌 반응을 일으키는 것입니다.
- 해결법:
- Composite Collider 2D: 여러 콜라이더를 하나로 합쳐 경계선을 없앱니다.
- Capsule Collider: 캐릭터 하단을 둥근 캡슐 형태로 만들어 모서리에 걸리지 않게 합니다.
3. 지터링 (Jittering) - “부들부들 떨리는 물체”
물체가 제자리에 가만히 있지 못하고 미세하게 떨리는 현상입니다.
- 현상: 바닥에 놓인 상자나 캐릭터가 미친 듯이 떨림.
- 원인: 두 물체의 콜라이더가 겹쳐 있어 엔진이 서로 밀어내려고 하는데, 다음 프레임에 중력 때문에 다시 겹쳐지는 과정이 무한 반복될 때 발생합니다.
- 해결법: * Sleep Threshold: 물리 연산을 중단할 속도 임계값을 조절합니다.
- Solver Iterations: 물리 연산의 반복 횟수를 높여 계산의 정밀도를 올립니다.
4. 고속 회전 시 튕김 (High Angular Velocity)
물체가 너무 빠르게 회전할 때 주변 물체를 멀리 날려버리거나 맵 밖으로 튕겨 나가는 현상입니다.
- 원인: 회전 속도가 프레임 업데이트 속도보다 빠를 때, 콜라이더가 다른 물체 안쪽 깊숙이 파고든 것으로 계산되어 엄청난 반발력이 발생하는 현상입니다.
💡 개발자 팁: Debug 기즈모(Gizmos) 활용의 중요성
이런 물리 이슈들은 눈에 보이지 않는 ‘연산의 공백’에서 발생합니다. 그래서 단순히 코드만 봐서는 알 수 없습니다.
저는 프로젝트 진행 중 Debug Gizmo를 활용하여 다음과 같은 데이터를 시각화했습니다.
- 이전 프레임과 현재 프레임의 위치를 잇는 선 (Trajectory)
- 실제 연산되고 있는 트리거 범위 (Trigger Bounds)
- 가해지는 힘의 방향과 크기 (Vector)