<--! 수학 기호 --> [Unity] Vector의 Set()으로 수정이 안 됐던 이유

새소식

반응형
Trouble Shooting/Unity

[Unity] Vector의 Set()으로 수정이 안 됐던 이유

  • -

 

유니티 개발을 진행하다 보면, 게임 오브젝트를 움직이거나 회전하는 등 벡터(Vector)를 조작할 일이 많습니다. 그런데, 쓰다보니 Set() 함수가 적용이 안 되는 것을 여러 번 확인한 적이 있었습니다.

float x = ...
float y = ...
float z = ...

...

transform.position.Set(x, y, z);  // 동작하지 않음

 

왜 바뀌지 않을까요? 정답은 Vector구조체(struct)이므로 value type이기 때문입니다.

 

 

값 형식은 스택(stack)에 저장되며, 블록(block)이 끝나는 순간 메모리를 자동 반납하여 사라집니다. 제일 결정적으로 원본이 전달되는 것이 아니라 복사본이 전달된다는 게 큰 특징이구요. transform.position의 구현 부분을 한 번 살펴보면 다음과 같습니다.

 

 

 

프로퍼티(property)로 구현되어 있습니다. 즉, getter를 통해 position을 읽으면 해당 Vector3의 복사본을 리턴해주죠.

그러니 transform.position.Set()을 하면, 복사된 Vector3를 변경을 죽어라 하니 원본 transform.position은 아무런 영향이 없는 것이었습니다.

 

따라서, 다음과 같이 새로운 Vector를 넣어줘야 합니다.

transform.position = new Vector3(x, y, z);

 

매 프레임마다 실행되는 Update() 함수에서 계속 새로운 Vector를 생성해도 괜찮을까란 생각이 들었었는데, 구조체이므로 힙 할당에 대한 가비지(Garbage) 걱정없이 사용해도 되겠네요.

 

transform.position이 프로퍼티에 의해 복사본을 받았기 때문에 Set()이 적용되지 않은 걸 알았으니, 다음과 같은 경우라면 Set() 함수는 제대로 동작할 겁니다.

public class Test : MonoBehaviour
{
    Vector3 vector;

    void Start()
    {
	/*
        또는 지역변수로 평소에 쓰던 방식으로 써도 같은 결과가 나온다.
        Vector vector = new Vector();
        */
        
        vector.Set(1f, 1f, 1f);
        Debug.Log(vector);

        vector.Set(2f, 2f, 2f);
        Debug.Log(vector);
    }
}

 

수정이 잘 된다.

 

728x90
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.