숏컷 코드
local -> world -> view -> clip -> screen문법과 예시
같은 값도 어느 공간에서 정의됐는지에 따라 의미가 완전히 달라진다
(0, 1, 0)이라는 벡터가 local space에서는 오브젝트의 위쪽, world space에서는 씬 전체 기준 위, view space에서는 카메라 기준 위를 의미합니다. 캐릭터가 기울어져 있다면 local up과 world up은 다릅니다. 이 구분 없이 "위쪽 방향으로 힘을 준다"는 코드를 작성하면, 캐릭터가 누워 있을 때 하늘이 아니라 옆으로 밀리는 현상이 나옵니다. 좌표계 버그의 대부분은 값이 틀린 것이 아니라 다른 공간의 값을 같은 공간의 값처럼 다루는 것에서 시작합니다.
// 버그 예시: local offset을 world 좌표처럼 더하기
worldPos = parentWorldPos + localOffset // 틀림 (local은 부모 기준)
// 올바른 처리: local을 world로 변환 후 더하기
worldPos = parentWorldMatrix * localOffset각 공간은 변환 체인에서 고유한 역할을 가진다
local space는 오브젝트 자신의 기준입니다. 메시의 모든 정점은 처음에 local space에 정의됩니다. world space는 씬 전체의 공통 기준으로, 오브젝트가 실제로 배치된 위치입니다. view space는 카메라가 원점이 되도록 world를 회전·이동한 공간입니다. clip space는 projection 이후 화면 비율에 맞게 정규화된 공간으로, rasterization 전 clipping이 이루어집니다. screen space는 최종 픽셀 좌표입니다. 이 체인을 이해하면 "지금 이 값은 어느 행렬을 곱해야 다음 단계로 이동하는가"가 명확해집니다.
local space --[modelMatrix]--> world space
world space --[viewMatrix]--> view space
view space --[projMatrix]--> clip space
clip space --[rasterizer]--> screen space공간을 섞어 쓰면 값이 약간 틀린 것이 아니라 완전히 다른 결과가 나온다
총구(muzzle) 위치를 local offset으로 잡고 발사 방향을 world forward로 계산하면, 캐릭터가 회전해도 총구 위치가 캐릭터 몸 기준으로 올바르게 따라다닙니다. 반면 world offset을 쓰면 캐릭터가 돌아도 총구가 씬 고정 위치를 가리킵니다. UI 앵커 위치, 미니맵 아이콘 좌표, billboard 계산, 카메라 조준점의 world 변환도 모두 "어느 공간에서 계산하고 어느 공간으로 넘기는가"의 문제입니다. 이 판단이 정확하면 행렬 공식을 외우지 않아도 API를 올바르게 쓸 수 있습니다.
// 총구 위치 올바른 처리
muzzleLocalOffset = Vector3(0, 0.1, 0.8) // 캐릭터 local 기준
muzzleWorldPos = characterTransform.TransformPoint(muzzleLocalOffset)
fireDir = characterTransform.forward // world forward디버깅할 때 각 값에 공간 레이블을 붙이면 버그가 빠르게 드러난다
좌표계 버그는 숫자가 조금 틀린 정도로 보이지만 원인은 공간 혼용인 경우가 많습니다. 디버깅할 때 식을 줄이려 하기보다, 변수 이름 또는 주석에 _local, _world, _view를 붙여 각 값이 어느 공간에 있는지 명시하는 것이 훨씬 빠릅니다. 값이 world라고 생각했는데 local이었다면 그게 버그의 출발점입니다.
좌표 공간을 구분할 때 핵심
| 상황 | 적합한 선택 |
|---|---|
| 오브젝트 기준 offset 배치 | local space 값 사용, TransformPoint로 world 변환 |
| 씬 전체 공통 기준 계산 | world space에서 처리 |
| 카메라 기준 방향 판정 | view space 값 사용 |
| UI 픽셀 좌표 배치 | screen space 변환 후 사용 |
| 좌표계 버그 디버깅 | 변수마다 공간 레이블 붙이고 혼용 여부 추적 |
| 부모 회전에 따라 자식 위치가 바뀌어야 할 때 | world가 아니라 local offset을 저장 |
특이 케이스와 주의할 점
가장 자주 깨지는 경우는 부모 기준 offset을 world 좌표처럼 저장해 두고, 부모가 회전하거나 스케일될 때 자식 배치가 틀어지는 경우입니다. 숫자 자체보다 "이 값은 어느 공간 소속인가"를 먼저 확인하세요. 좌표계 레이블이 불분명하면 행렬 계산이 맞아도 결과는 틀립니다.
참고 링크
2 sources