본문 바로가기
개발/Unity 내일배움캠프 TIL

Unity2D 월드 좌표계 vs 로컬 좌표계

by 석시 2023. 9. 11.



나는 완벽하게 구분할 수 있을 줄 알았지

생각보다 헷갈리는 부분이 많아 따로 게시글로 정리해본다.


기본적인 월드 좌표계와 로컬 좌표계의 구분

월드 좌표계는 절대적인 위치를 나타낸다.

월드 좌표가 같으면 씬에서 봤을 때 정확히 같은 곳에 있다.

로컬 좌표계는 상대적인 위치를 의미하는데, 이는 오브젝트 사이에 부모자식 관계가 있을 때만 의미가 있다.

부모를 두고 있는 오브젝트의 경우 로컬 좌표계는 부모 오브젝트의 위치가 기준이다. 부모 오브젝트의 위치를 (0, 0, 0)으로 생각한다는 소리이다.

즉, 속한 부모가 없는 오브젝트의 경우 로컬 좌표계와 월드 좌표계가 동일하다.

여기까지는 크게 어렵지 않다.


변수와 함수들의 좌표계 구분

Inspector 상에서 Transform에 표시되는 좌표는 로컬 좌표계이다.

골때리는 게 스크립트 상에서는 반대이다.

transform.position월드 좌표계의 좌표를 의미한다.

로컬 좌표를 접근하거나 수정하고 싶으면 transform.localPosition을 사용한다.

또 메서드는 반대이다!

보통 Transform 컴포넌트에 있는 메서드로 이동이나 회전을 할 경우 이는 로컬 좌표계를 기준으로 한다.

 
void Update()
{
    transform.Translate(Vector3.up * Time.deltaTime);
}
 

Translate도 당연히 로컬 좌표계를 기준으로 한다.

“아니 어차피 좌표 옮기는건데 로컬이나 월드 좌표계나 거기서 거기 아님?”이라고 할 수 있다.

나도 그랬다.

이제 골때리는 부분은 회전이 가해질 때이다.

지금까지 표현을 좌표계로 했던 것은 그 이유이다.


Rotation 변경 시 씬에서 변화 관찰하기

실제 Object의 Rotation을 바꾸면서 씬을 보자.

다음과 같이 Bullet 오브젝트와 Player 오브젝트가 있다고 해보자.

Bullet 오브젝트는 Player를 부모로 가지는 자식 오브젝트이다.

현재 BulletPosition(0, 1.2, 0)으로 씬 상에서 Player보다 Y좌표 상으로 1.2만큼 위에 위치한다.

Player를 90도 돌려보자.

오브젝트를 돌리는 순간 월드 좌표계의 방향과 Player와 그 자식 오브젝트들의 좌표계의 방향이 서로 달라지게 된다.

신기한건, 이래도 Bullet의 Inspector를 보면 Position은 여전히 (0, 1.2, 0)이다.

이 상황에서 Scene에서 Bullet을 붙잡고 위아래로 움직여보자.

위아래로 움직이는데 X좌표가 바뀐다.

지금 우리가 바꾸는 건 글로벌 좌표인데, Position 값은 로컬 좌표이기 때문이다!

45도만 돌려놔도 똑같다.

만약 Tool의 좌표계를 Global이 아닌 Local로 바꿔주고 싶으면, 왼쪽 상단에서 바꿀 수 있다.

Global → Local로 바꿔주면…

Tool이 해당 오브젝트의 로컬 좌표계로 바뀐다.

이 때부턴 씬의 Tool을 사용하여 위치를 바꿔도 로컬 좌표계를 기준으로 바뀌는 것이다.


스크립트에서 좌표계 지정하기

씬에서 좌표계를 바꿨던 것처럼, 스크립트 상에서도 내가 어느 좌표계의 좌표를 변화시킬 것인지 지정해줄 수 있다.

Space.Self vs Space.World

transform.Translate 함수를 사용할 때는

Space라는 enum을 매개변수로 넣어주는 것이다.

Space에는 Space.SelfSpace.World 두 가지가 있다.

잘 생각해보면 예측 가능하다.

Space.Self는 자기자신을 축으로 삼기 때문에 로컬좌표계를 기준으로 이동한다는 말이다.

자신이 각도가 틀어져 있으면 그 틀어진 상태를 정방향으로 보고 이동한다는 것이다.

Space.World는 반대로 글로벌 좌표계, 즉 월드 상의 좌표를 바꾼다.

 
void Update()
{
    transform.Translate(Vector3.up * Time.deltaTime, Space.World);
}
 

Vector3.up vs transform.up (right, forward)

Vector3에서 참조하는 Vector3.up이 항상 (0, 1, 0)을 리턴하는 것과 달리 한 오브젝트에서 transform.up을 참조할 때는 그 transform의 로컬 좌표계의 up월드 좌표계에서 봤을 때의 값을 나타내준다.

green axis를 반환해준다는데, 아래 그림에서 초록색 화살표를 world space에서 봤을 때 방향 값을 반환한다는 소리이다.

그림에서 bullet.upVector3(-1, 1, 0).normalized와 같은 값을 반환해줄 것이다.

다음 두 줄의 코드가 모두 같은 방향으로 이동한다는 것을 알 수 있다면 지금까지의 내용을 제대로 이해한 것이다.

 
bullet.Translate(bullet.up * 1f, Space.World);
bullet.Translate(Vector3.up * 1f);
 

TransformDirection vs InverseTransformDirection

로컬 좌표계와 월드 좌표계의 구분을 확실히 할 수 있다면 회전이 들어가는 이동을 구현할 때 조금 더 편할 것이다.

이해가 안갈때를 위한 함수도 있다.

transformtransform.TransformDirection이라는 함수는 로컬 좌표계의 벡터를 월드 좌표계의 값으로 바꿔주는 함수이다.

반대로 transform.InverseTransform의 경우는 월드 좌표계의 벡터를 로컬 좌표계 기준으로 바꿔주게 된다.


Uploaded by N2T

'개발 > Unity 내일배움캠프 TIL' 카테고리의 다른 글

Unity2D 애니메이터 State와 Transition  (0) 2023.09.13
Unity2D 레이캐스트 (Raycast)  (0) 2023.09.12
Unity 오브젝트 풀  (0) 2023.09.08
Unity2D 셀 애니메이션  (0) 2023.09.07
Unity2D 타일맵 (Tilemap)  (0) 2023.09.06