FindObjectOfType<T>와 FindObejctsByType<T>

한 줄 요약

FindObjectOfType은 이제는 Obsolete된 API이고, 유니티 2023부터 FindObjectsByType이 생겨난 새로운 API이다.

들어가며

어떤 기능을 구현하기 위해 찾아보는 자료들이 보통 연식이 있다보니, FindObjectOfType을 쓴 코드들이 많이 보인다. 그런 코드를 따라서 쳐보면 가끔 CS0618 오류 코드가 뜨는데, 찾아보니 이는 Obsolete(쓸모없는) API에 붙는 그런 것이라고 하더라.

즉, 우리나라 언어로 생각하면 사장된 말이라는 것과 같은 뜻이다. 그래서 2023버전 이후에는 FindObejctsByType 류의 API들이 좀 생겨났던데, CS0618은 그런 메서드들을 사용하라고 권고하는 뜻의 메세지였던 것이다.

그러면 그냥 그렇구나~ 하고 넘어가면 될테지만, 일단은 둘다 알아두는 편이 좋을 것이다. 왜냐면 이후에 최신 버전의 유니티만 사용한다는 보장이 없기 때문이다. 예를 들어 기존 게임의 유지 보수를 위해 사용하는 경우가 있을 것 같다.

 

 


정의와 장단점

두 메서드는 기능적으로는 타입을 찾는다는 점에서 다를 바가 없다. 하지만, 그 기본형이 반환하는 자료 구조가 다른 것을 인지하자.

일단, 두 메서드 다 씬 전체를 검색하는 것은 동일하다. 그렇기 때문에 당연히 둘 다 성능 비용이 크다는 점을 명심하고 남용하지 말자.

FindObjectOfType<T>()

public static T FindObjectOfType<T>() where T : Object;
public static T FindObjectOfType<T>(bool includeInactive) where T : Object;

 

유니티가 제공하는 메서드의 형태이다. 보면은 오버로드 된 함수가 두개 있는 것을 확인할 수 있다.

bool 타입으로 받는 매개변수는 꺼져있는 것도 포함하여 검색을 실행할지의 여부를 결정한다.

    public Enemy GetEnemy()
    {
        Enemy item = (Enemy)FindObjectOfType(true);
        return item;
    }

 

위 코드의 경우 현재 씬에 있는 모든 오브젝트를 검색하여 가장 첫번째로 검색된 Enemy class를 반환하는 함수이다.

매개변수로 true를 줬기 때문에 꺼져있는 오브젝트를 포함하여 검색할 것이다.

 

장점

1. 코드가 짧고 간단해서 빠른 테스트나 프로토타입에 유용하다.
2. 특정 매니저 등의 씬에 유일해야 하는 오브젝트 탐색에 간단히 사용 가능하기 편하다.

 

단점

1. 같은 타입이 여러개 존재할 경우 어떤 것이 반환될지 보장되지 않는다.
2. Awake나 Start 타이밍에 호출하면 못찾을 수 도 있다.

 


FindObjectsByType<T>()

public static T[] FindObjectsByType<T>(FindObjectsSortMode sortMode) where T : Object;
public static T[] FindObjectsByType<T>(FindObjectsInactive inactive, FindObjectsSortMode sortMode) where T : Object;

 

유니티가 제공하는 메서드의 형태이다. 이런건 유니티 메뉴얼을 찾아보면 더 자세히 설명이 있을테니 참고하길 바란다.

이전의 위에서는 bool을 매개변수로 받았다면 ByType은 유니티에서 자체 정의된 enum을 타입으로 매개변수로 받는다.

FindObjectsInactive : 비활성화된 오브젝트도 찾을지 여부 (Exclude,Include)
FindObjectsSortMode : 반한되는 배열 정렬 방식 (None, InstanceID, Scene, TransformHierarchy)

MyEnemy[] enemies = FindObjectsByType<MyEnemy>(FindObjectsInactive.Include, FindObjectsSortMode.None);​

 

    public Transform[] GetTransformItem()
    {
        Transform[] item = FindObjectsByType<Transform>(FindObjectsSortMode.None);
        return item;
    }

 

FindObjectsByType 메서드는 복수형을 사용한 것으로 짐작할 수 있듯이, 해당 타입의 Array 타입으로 반환을 한다. 그래서 받을 때도, 배열로 반환을 받아야한다.

 


FindObjectOfType의 대체 API

FindFirstObjectByType<T>()

기존 FindObjectOfType의 대체용으로 나온 메서드이다. 씬에서 가장 먼저 발견된 하나만 반환하는 기능을 가지고 있고, 이는 완전히 이전 API와 동일한 기능을 가지고 있다.

public static T FindFirstObjectByType<T>() where T : UnityEngine.Object;
public static T FindFirstObjectByType<T>(FindObjectsInactive findObjectsInactive) where T : UnityEngine.Object;

public static UnityEngine.Object FindFirstObjectByType(
    System.Type type,
    FindObjectsInactive findObjectsInactive = FindObjectsInactive.Exclude
);

FindAnyObjectByType<T>()

이 메서드는 좀 다른 기능을 가지고 있는데, 씬에서 아무거나 한 개를 반환한다. 그래서 반환 순서는 보장이 안되지만, 성능은 FindFirst보다 최적화된 경우도 있다.

그래서 특정 오브젝트 하나만 필요할 때, 빠르게 가져오는 용도로 사용할 수 있을 것 같다.

public static T FindAnyObjectByType<T>() where T : UnityEngine.Object;
public static T FindAnyObjectByType<T>(FindObjectsInactive findObjectsInactive) where T : UnityEngine.Object;

public static UnityEngine.Object FindAnyObjectByType(
    System.Type type,
    FindObjectsInactive findObjectsInactive = FindObjectsInactive.Exclude
);