캐릭터가 벽 모서리에서 떨릴 때 게임 충돌 처리 고치는 법

profile_image
작성자 물리엔진개발자 유담
댓글 0건 조회 6회

플레이어가 평지를 달릴 때는 멀쩡한데 벽 모서리에 닿는 순간 몸이 떨리거나, 계단 앞에서 제자리걸음을 하거나, 얇은 벽을 뚫고 지나간다면 애니메이션부터 의심하기 쉽습니다. 하지만 이런 현상의 상당수는 게임 충돌 처리의 순서, 좌표 갱신 방식, 시간 간격이 서로 맞지 않아 발생합니다.

특히 직접 만든 수학 라이브러리나 캐릭터 컨트롤러를 사용하는 프로젝트에서는 작은 오차가 여러 프레임 동안 누적됩니다. 화면에 보이는 떨림만 감추기보다 충돌 검출과 위치 보정이 어떤 값을 주고받는지 추적해야 재발을 막을 수 있습니다.

벽에 닿는 순간 떨림이 시작되는 원인부터 분리합니다

렌더링 문제와 물리 계산 문제를 먼저 구별합니다

가장 먼저 할 일은 카메라와 애니메이션을 끄고 충돌체만 표시하는 것입니다. 캐릭터 메시만 흔들리고 캡슐 충돌체는 안정적이라면 렌더 보간이나 루트 모션 문제일 가능성이 큽니다. 반대로 충돌체 자체가 벽 안팎을 반복한다면 침투 해소와 이동 계산이 충돌하고 있는 상태입니다.

예를 들어 입력 코드가 캐릭터를 매 프레임 벽 안쪽으로 2cm 이동시키고, 물리 코드가 다시 바깥으로 2cm 밀어낸다고 가정해 보겠습니다. 다음 프레임에도 같은 순서가 반복되면 논리 좌표는 계속 왕복합니다. 카메라가 이 좌표를 그대로 따라가면 아주 작은 수치 오차도 눈에 띄는 떨림으로 확대됩니다.

  • 메시만 흔들림: 렌더 보간, 애니메이션 루트 모션, 카메라 추적 순서를 확인합니다.
  • 충돌체도 흔들림: 위치 보정이 한 프레임에 몇 번 수행되는지 기록합니다.
  • 특정 프레임률에서만 발생: 이동량에 델타 타임이 중복 적용됐는지 살펴봅니다.
  • 모서리에서만 발생: 두 접촉면의 법선을 합치는 방식과 우선순위를 검사합니다.
  • 경사면에서 악화: 지면 판정 거리와 최대 등판 각도가 서로 간섭하는지 확인합니다.

디버그 화면에는 현재 위치만 그리지 말고 충돌 전 위치, 희망 이동 벡터, 충돌 지점, 접촉 법선, 최종 보정 위치를 서로 다른 색으로 표시하는 편이 좋습니다. 값이 한눈에 겹쳐 보인다면 프레임 번호와 함께 로그 파일에도 남겨야 합니다. 그래야 화면이 흔들린 결과가 아니라 어느 계산이 먼저 잘못됐는지 확인할 수 있습니다.

흔한 고장 원인을 재현 가능한 장면으로 줄입니다

복잡한 스테이지에서 바로 고치려 하면 벽 메시, 이동 플랫폼, 애니메이션, 네트워크 보정이 한꺼번에 개입합니다. 빈 테스트 장면에 평면 하나, 수직 벽 하나, 90도 안쪽 모서리 하나를 배치하고 동일한 캐릭터 충돌체를 옮겨 보십시오. 충돌 재현 장면은 그래픽 품질이 아니라 변수를 하나씩 끌 수 있는 구조가 중요합니다.

  1. 카메라 추적과 캐릭터 애니메이션을 비활성화합니다.
  2. 중력 없이 벽을 향해 일정한 속도로 이동시킵니다.
  3. 30, 60, 120fps 조건에서 같은 입력을 반복합니다.
  4. 벽과 평행한 입력, 벽 안쪽을 향한 입력, 모서리를 향한 대각선 입력을 각각 시험합니다.
  5. 충돌체 크기와 벽 두께를 절반씩 바꾸며 결과를 비교합니다.
  6. 문제가 발생한 프레임의 입력과 위치를 저장해 자동 재생합니다.
디버깅 팁: “가끔 떨린다”는 설명으로는 고칠 수 없습니다. “캡슐 중심이 안쪽 모서리에서 3프레임 연속 0.006m 왕복한다”처럼 측정 가능한 문장으로 바꾸면 수정 지점이 선명해집니다.

팀에서 이 문제를 다룬다면 재현 조건을 기획 의도와 함께 기록해야 합니다. 이동 감각과 장애물 통과 기준은 코드만의 문제가 아니므로 게임 기획자의 역할을 설명한 지식백과처럼 직무 간 책임 범위를 참고해, 허용할 동작과 버그로 볼 동작을 구분하는 것도 도움이 됩니다.

충돌 검출과 위치 보정을 한 방향으로 작동시킵니다

겹친 뒤 밀어내기보다 이동 경로를 먼저 검사합니다

단순한 구현은 새 위치로 캐릭터를 옮긴 다음 벽과 겹쳤는지 확인하고, 침투 깊이만큼 밀어냅니다. 속도가 느리고 충돌면이 하나라면 잘 작동하지만 빠른 이동이나 모서리에서는 한 프레임에 여러 면과 겹칠 수 있습니다. 첫 번째 벽에서 밀려난 위치가 두 번째 벽을 침범하고, 두 번째 보정이 다시 첫 번째 벽을 침범하면 반복 진동이 생깁니다.

해결의 중심은 현재 위치에서 목표 위치까지 충돌체를 쓸어 보는 스윕 테스트입니다. 가장 먼저 만나는 지점 직전까지만 이동하고, 남은 이동 벡터에서 접촉 법선 방향 성분을 제거하면 벽을 따라 미끄러질 수 있습니다. 이 방식은 결과 좌표를 반복해서 뒤집는 대신 이동 가능한 거리를 순서대로 소비하므로 동작을 추론하기 쉽습니다.

  1. 현재 위치와 입력으로 희망 이동 벡터를 계산합니다.
  2. 캡슐이나 구를 희망 이동 방향으로 스윕해 가장 이른 충돌 시간을 구합니다.
  3. 충돌 지점보다 작은 안전 여백만큼 앞에서 이동을 멈춥니다.
  4. 남은 벡터에서 법선 방향 성분을 제거해 접선 이동을 만듭니다.
  5. 새 벡터로 제한된 횟수만큼 다시 스윕합니다.
  6. 마지막에 작은 초기 침투만 별도의 복구 단계에서 처리합니다.

접선 이동은 보통 remaining - normal × dot(remaining, normal) 형태로 계산합니다. 다만 내적이 양수라면 이미 표면에서 멀어지는 이동일 수 있으므로 무조건 법선 성분을 제거하면 안 됩니다. 법선이 정규화되지 않은 상태에서 이 공식을 사용하면 속도까지 달라지므로 수학 라이브러리의 정규화 계약도 확인해야 합니다.

안전 여백은 월드 단위와 캐릭터 크기에 맞춰야 합니다. 너무 작으면 부동소수점 오차 때문에 다음 반복에서 같은 면을 다시 검출하고, 너무 크면 캐릭터가 벽에서 떠 보입니다. 고정된 숫자 하나를 모든 오브젝트에 적용하기보다 충돌체 반지름에 비례하는 값에 최소·최대 범위를 두면 크기가 다른 캐릭터에서도 일관성을 얻기 쉽습니다.

모서리, 계단, 얇은 벽은 별도 규칙으로 검증합니다

두 벽이 만나는 안쪽 모서리에서는 첫 번째 접촉 법선만 사용해 미끄러지면 다른 벽 안으로 향할 수 있습니다. 두 번째 접촉까지 얻었다면 두 법선의 외적으로 만들어지는 교선 방향만 허용하거나, 이동 가능 공간을 제약식으로 풀어야 합니다. 2차원 게임이라면 두 법선이 이동을 완전히 막는지 판정한 뒤 남은 이동을 0으로 만드는 편이 안정적입니다.

계단은 작은 수직 벽과 수평 바닥이 연속된 구조입니다. 일반 벽 충돌만 적용하면 캐릭터가 첫 단의 수직면에 걸립니다. 계단 오르기 높이보다 낮은 장애물에 한해 위쪽 공간을 검사하고, 올라갈 위치에서 캡슐이 겹치지 않을 때만 단계 이동을 허용하십시오. 단순히 y좌표를 올리면 낮은 천장이나 계단 옆 난간을 통과할 수 있습니다.

  • 안쪽 모서리: 접촉 법선 두 개를 보존하고 같은 면을 중복 등록하지 않습니다.
  • 바깥 모서리: 접촉점이 끝났는데 이전 법선을 계속 적용해 캐릭터가 허공에 붙지 않게 합니다.
  • 계단: 전진, 상승, 착지의 세 구간을 각각 충돌 검사합니다.
  • 얇은 벽: 이동 거리가 벽 두께보다 커도 잡을 수 있도록 연속 충돌 검사를 사용합니다.
  • 이동 플랫폼: 플랫폼 변위와 플레이어 입력을 분리해 어느 좌표계에서 계산했는지 기록합니다.
  • 경사 경계: 등판 가능 각도 바로 근처에서 판정이 번갈아 바뀌지 않도록 작은 히스테리시스를 둡니다.
접촉 반복 횟수를 무작정 늘리는 것은 근본 해결이 아닙니다. 보통은 제한된 반복 안에서 끝나도록 설계하고, 한도를 넘으면 입력 벡터·법선·충돌체 ID를 저장해 잘못된 제약 조합을 찾는 편이 낫습니다.

대형 게임 개발 사례를 살필 때는 발표의 화려한 결과보다 문제를 어떻게 측정하고 재현했는지 보는 편이 유용합니다. 업계 발표가 집중되는 GDC의 개념과 성격을 알아두면 게임 프로그래밍 세션이나 사후 분석 자료를 찾을 때도 맥락을 잡기 쉽습니다.

한 번 고친 떨림이 다른 맵에서 돌아오지 않게 만듭니다

수치 기준과 업데이트 순서를 코드 계약으로 고정합니다

충돌 버그가 반복되는 프로젝트에는 흔히 서로 다른 오차 기준이 섞여 있습니다. 벡터 라이브러리는 0.000001을 0으로 보는데 캐릭터 컨트롤러는 0.001 이하 이동을 버리고, 월드 충돌 코드는 또 다른 여백을 사용하면 같은 접촉을 두고 각 시스템이 다른 판단을 내립니다. 길이, 각도, 침투 깊이의 허용 오차를 구분하고 이름 있는 상수나 설정으로 관리하십시오.

업데이트 순서도 명문화해야 합니다. 권장 흐름은 입력 수집, 희망 속도 계산, 플랫폼 변위 반영, 충돌 스윕, 위치 확정, 지면 상태 갱신, 애니메이션과 카메라 반영 순입니다. 프로젝트 특성에 따라 달라질 수 있지만 카메라가 보정 전 좌표를 읽고 애니메이션이 보정 후 좌표를 읽는 혼합 상태만큼은 피해야 합니다.

관찰 증상우선 확인할 값권장 대응
벽을 따라갈 때 속도가 줄어듦법선 정규화와 접선 벡터 길이법선 성분만 제거하고 입력 속도 정책을 별도로 적용
프레임률이 낮을 때 벽 통과프레임당 이동 거리와 벽 두께스윕 기반 연속 충돌 검사 사용
모서리에서 좌우 왕복접촉 법선 목록과 처리 순서복수 제약을 유지하고 중복 접촉 제거
계단 위에서 위아래 떨림지면 스냅 거리와 상승 높이상승 중 지면 스냅을 제한하고 착지 후 다시 적용
카메라만 미세하게 흔들림물리 좌표와 렌더 좌표확정된 물리 상태 사이를 렌더 단계에서 보간

자동 테스트에는 정확한 최종 좌표만 넣지 않는 편이 좋습니다. 플랫폼과 컴파일러가 달라지면 마지막 몇 비트가 달라질 수 있기 때문입니다. 대신 캐릭터가 벽을 통과하지 않았는지, 허용 범위보다 깊게 침투하지 않았는지, 제한 반복 횟수 안에 해결됐는지 같은 불변 조건을 검사하십시오. 결정론이 필수인 프로젝트라면 입력과 초기 상태를 저장한 뒤 일정 프레임 동안 상태 해시를 비교하는 테스트를 추가할 수 있습니다.

  • 60프레임 동안 벽을 향해 이동해 최대 침투 깊이를 측정합니다.
  • 안쪽 모서리에 대각선 입력을 주고 위치 왕복 횟수를 셉니다.
  • 계단 높이의 경계값 바로 아래와 바로 위를 각각 시험합니다.
  • 낮은 프레임률을 흉내 내 큰 델타 타임에서도 얇은 벽 통과 여부를 확인합니다.
  • 이동 플랫폼의 방향이 바뀌는 프레임에 지면 상태가 끊기지 않는지 검사합니다.
  • 충돌체 크기를 바꿔 안전 여백이 과도한 틈을 만들지 확인합니다.

개인 프로젝트와 팀 프로젝트는 다른 수선 순서를 택합니다

혼자 만드는 포트폴리오 게임이라면 범용 물리 솔버를 처음부터 완성하려고 시간을 쓰기보다 플레이에 실제로 등장하는 충돌 형태부터 제한하는 것이 현실적입니다. 캡슐 캐릭터, 정적 벽, 단순 계단만 지원하고 재현 장면과 디버그 드로잉을 갖춘 뒤 기능을 넓히십시오. 제한 사항을 기술 문서에 적으면 오히려 설계 판단과 문제 해결 능력을 보여주는 좋은 포트폴리오 자료가 됩니다.

여러 개발자가 월드와 캐릭터를 동시에 수정하는 팀이라면 먼저 진단 도구와 공통 수치 기준에 시간을 배정해야 합니다. 기능 일정만 잡고 안정화 비용을 남겨두지 않으면 맵이 늘어날수록 예외 처리도 증가합니다. 제한된 개발 자원을 목적별로 배분한다는 관점은 계획예산 제도의 설명에서도 참고할 수 있으며, 충돌 안정화 작업을 기능 개발과 별개의 예산 항목으로 보는 데 도움이 됩니다.

  1. 개인 개발자라면: 최소 재현 맵을 만든 뒤 스윕 이동, 벽 미끄러짐, 계단 처리 순으로 구현하고 지원 범위를 좁게 유지합니다.
  2. 팀 개발자라면: 공용 디버그 표시, 접촉 로그 형식, 허용 오차, 업데이트 순서를 먼저 합의하고 회귀 테스트를 빌드 과정에 연결합니다.
  3. 네트워크 게임이라면: 로컬 화면 보간으로 떨림을 숨기기 전에 서버 권위 좌표와 예측 좌표의 충돌 결과가 왜 달라지는지 비교합니다.
  4. 정밀 액션 게임이라면: 자동 계단 오르기나 강한 지면 스냅이 조작 의도를 바꾸지 않는지 플레이 테스트로 검증합니다.

따라서 짧은 기간에 플레이 가능한 데모를 완성해야 하는 독자라면 지원할 지형을 제한하고 안정적인 캡슐 스윕 컨트롤러를 선택하는 편이 낫습니다. 반면 여러 캐릭터와 이동 플랫폼, 네트워크 동기화까지 운영할 독자라면 복수 접촉 제약과 자동 재현 테스트를 갖춘 충돌 파이프라인에 먼저 투자하는 선택이 장기적으로 수정 비용을 줄여줍니다.

캐릭터가 벽 모서리에서 떨릴 때 게임 충돌 처리 고치는 법

댓글목록

등록된 댓글이 없습니다.