게임 오브젝트 찾기(GameObject.Find())에 대해

2023. 5. 14. 19:30유니티/성능 관리

* 잘못된 정보 지적은 항상 감사합니다 *

 

얼마 전, 공부하던 중 GameObject.Find() 에 대해 더 찾아본 적이 있었습니다.

이 동안 배운 내용들을 정리하여 적어보겠습니다.

 

1. 비활성화 오브젝트 찾기

GameObject.Find() 는 비활성화 상태의 오브젝트를 가져올 수 없다고 합니다.

비활성화 상태의 오브젝트를 가져오려면 Transform.Find() 를 사용해야 한다고 하더군요.

다만, Transform.Find는 자식 오브젝트만 가져올 수 있다고 합니다.

 

제가 사용하는 시점에서는 Transform.FindObjectOfType<T>() 을 사용 가능한 모양입니다.

 

 

2. Find 의 단점

Find 계열 메서드는 모든 오브젝트를 검사해 찾아내기 때문에 성능에 좋지 못하다고 합니다.

GetComponent<T> 또한 마찬가지로, 해당 오브젝트의 모든 컴포넌트를 탐색한다고 합니다.

GetComponent() 의 경우는 Find 보다는 덜 하지만, 부담이 되는 것은 마찬가지이니

Update 같은 반복적인 곳보다는 한 번만 호출되게 한 뒤, 참조를 통해 재사용을 하는 것을 추천한다고 합니다.

 

public class MyClass
{
    MyComponent comp;
    
    private void Start()
    {
        // 한 번만 실행되는 함수에서 참조를 통해 가져올 수 있도록 한다.
        GameObject obj = GameObject.Find("MyObject");
        comp = obj.GetComponent<MyComponent>();
    }
    
    private void Update()
    {
        // 나쁜 예시
        // Find 계열 메서드는 비용이 많이 들기 때문에
        // Update 같이 자주 호출되는 메서드에서의 사용은 자제할 것
        GameObject obj = GameObject.Find("MyObject");
        MyComponent comp = obj.GetComponent<MyComponent>();
    }
}

 

3. Find 의 대체

Find 계열 메서드를 사용하기 보다는 아예 참조용 변수를

public 이나 [Serializefild] private 로 인스펙터 창에 띄워 오브젝트를 끌어다 놓는것을 추천한다고도 합니다.

public class MyClass
{
    // 인스펙터 창에서 끌어다 놓는 것으로 대체한다.
    public MyComponent comp;
}