멈추지 않고 끈질기게

[Unity][번외] Transform.SetPositionAndRotation 본문

Unity

[Unity][번외] Transform.SetPositionAndRotation

sam0308 2023. 2. 15. 11:25

※ 해당 포스팅은 개인의 공부 정리용 글입니다. 틀린 내용이 있다면 추후 수정될 수 있습니다.

※ 해당 포스팅은 Unity 2021.3.15f1 버전을 기준으로 작성되었습니다.

해당 포스팅은 UnityKorea 공식 채널의 영상을 토대로 정리한 내용임을 밝힙니다.

(출처: [유니티 TIPS] 알아두면 쓸 데 있는 '트랜스폼' )

 

 

 

 유니티에서 오브젝트를 다룰 때 빠트릴 수 없는 것이 트랜스폼일 것입니다. 좌표값(position), 회전값(rotation), 크기(scale)라는 모든 오브젝트가 가지는 3가지 요소를 포함하고 있으며, MonoBehaviour 클래스를 상속받은 클래스는 transform을 통해 해당 게임 오브젝트의 트랜스폼에 접근할 수 있습니다. 사실 트랜스폼의 3가지 요소들은 유니티 엔진 내부에서 4x4 크기의 하나의 배열 형태로 저장되어 있습니다.

 

그림 1. 오브젝트의 트랜스폼

 유니티에서 큐브 하나를 생성한 뒤 상기 인스펙터 창에 나타난 것처럼 설정하였고, 연결한 Test 클래스에서 Awake 타이밍에 transform.localToWorldMatrix를 콘솔 창에 출력하도록 했습니다. 해당 변수는 Matrix4x4 구조체 타입을 반환하며, 오브젝트의 포지션, 로테이션, 스케일 값이 모두 포함되어 있습니다.

 

 그리고 Transform 클래스에는 SetPositionAndRotation() 함수가 존재합니다. 이름에서 유추할 수 있듯이 오브젝트의 포지션과 로테이션 값을 넘겨준 매개변수를 통해 변경하는 함수입니다. 다만 포지션과 로테이션은 각각 position, rotation 값을 통해 변경할 수 있는데, 굳이 동시에 바꿔주는 함수가 존재하는 이유는 무엇일까요? 해당 함수를 이용하면 행렬을 한번 갱신하면서 포지션과 로테이션을 모두 변경할 수 있기 때문입니다. 

using UnityEngine;

public class Test : MonoBehaviour
{
    void Awake()
    {
        Debug.Log(transform.localToWorldMatrix);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Return))
            SetDefaultPositionAndRotation();
    }

    void SetDefaultPositionAndRotation()
    {
        transform.position = Vector3.zero;
        Debug.Log(transform.localToWorldMatrix);
        transform.rotation = Quaternion.identity;
        Debug.Log(transform.localToWorldMatrix);
    }
}

그림 2. 포지션, 로테이션 각각 변경

 상기 코드는 엔터 입력 시 오브젝트의 포지션과 로테이션 값을 모두 (0, 0, 0)으로 만들고, 각 연산 후 트랜스폼 행렬을 출력하는 코드입니다. 포지션 변경 시, 그리고 로테이션 변경 시 각각 행렬이 갱신된 것을 볼 수 있습니다. 이렇게 포지션과 로테이션을 각각 변경할 경우, 연산과 행렬 갱신이 2번씩 일어나게 됩니다. 하지만 SetPositionAndRotation()을 이용하면 한꺼번에 연산 후 행렬 갱신을 1번만 행하여 비용을 절감할 수 있습니다.

using UnityEngine;

public class Test : MonoBehaviour
{
    void Awake()
    {
        Debug.Log(transform.localToWorldMatrix);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Return))
            SetDefaultPositionAndRotation();
    }

    void SetDefaultPositionAndRotation()
    {
        transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
        Debug.Log(transform.localToWorldMatrix);
    }
}

그림 3. 포지션, 로테이션 동시 변경

 물론 오브젝트를 회전시키는 방법에는 여러가지가 있기 때문에 포지션과 로테이션을 바꾸는 경우마다 항상 SetPositionAndRotation() 함수를 사용할 수는 없겠지만, 트랜스폼의 구조를 이해하고 가능할 때는 해당 함수를 이용하여 트랜스폼 갱신 비용을 절감하도록 해야겠습니다.

'Unity' 카테고리의 다른 글

[Unity][UI] Content Size Fitter  (0) 2023.04.13
[Unity][UI] 레이아웃 그룹(Layout Group)  (0) 2023.03.31
[Unity][2D] 타겟을 향한 회전  (0) 2023.02.11
[Unity] 코루틴(CoRoutine)  (0) 2022.12.17
[Unity] Script Lifecycle  (0) 2022.12.16