【Unity】非アクティブなGameObjectを取得する

Unity で FindXxxx 系のメソッドを使って非アクティブな GameObject を取得する方法の紹介です。

  • Unity 2022.3

非アクティブなオブジェクトは取得できない

まず前提として以下のメソッド呼び出しだと非アクティブなオブジェクトは取得できません。

// ★非アクティブなオブジェクトは取得できない
GameObject.Find("xxx/yyy/zzz");

public class TestComponent1 : MonoBehaviour
{
    public void Test()
    {
        // ★非アクティブなオブジェクトは取得きない
        var c1 = FindObjectOfType<TestComponent2>();
        var c2 = UnityEngine.Object.FindObjectOfType<TestComponent2>();
    }
}

限定的に非アクティブオブジェクトを取得する

次の実装例では自分の子要素に限り非アクティブなオブジェクトを取得できます。

// 子要素に限定して非アクティブなオブジェクトを取得できる

// ヒエラルキーの構成
+ Parent ← ここで処理を実行する
  + Child1 ← アクティブ
    + Child2 ← 非アクティブ

// 非アクティブでも正確に名前を指定できれば取得できる
GameObject child = transform.Find("Child1/Child2").gameObject;

全部から探すより子要素から探すというほうが使いやすい場合があるのでその場合これを使います。

非アクティブなオブジェクトを取得する

次の実装例ではシーンのヒエラルキー全体から非アクティブなオブジェクトを検索して取得できます。

非アクティブオブジェクトを結果に含めるかどうかを引数で指定します。

// 非アクティブなオブジェクトが取得できる
UnityEngine.Object[] objects =
    FindObjectsOfType(typeof(TestComponent2), true);

// 上記の処理と同じだが結果をインスタンスID順に整列しない分少し高速に動作する
UnityEngine.Object[] objects =
    FindObjectsByType(typeof(TestComponent2),
        FindObjectsInactive.Include, FindObjectsSortMode.None);

以下は型をジェネリックで指定できます。こっちのほうがおすすめです。

// 非アクティブなオブジェクトが取得できる
// 非アクティブなオブジェクトが取得できる
UnityEngine.Object[] objects = FindObjectsOfType<TestComponent2>(true);

// 上記の処理と同じだが結果をインスタンスID順に整列しない分少し高速に動作する
FindObjectsByType<TestComponent2>(FindObjectsInactive.Include, FindObjectsSortMode.None);

次の例ではアクティブ・非アクティブ関係なくオブジェクトを1つだけ取得できます。

シーン内でその型のオブジェクトをひとつだけ扱う場合に便利ですが、もし複数のオブジェクトが存在するとどのオブジェクトが最初に返されるかは保証されません。

// インスタンスIDが一番小さいオブジェクトを取得する
UnityEngine.Object object =
    FindObjectOfType(typeof(TestComponent2), true);

UnityEngine.Object object =
    FindObjectOfType<TestComponent2>(true);

UnityEngine.Object object =
    FindFirstObjectByType(typeof(TestComponent2), FindObjectsInactive.Include);

// 最初に見つかったオブジェクトを取得する
UnityEngine.Object object = FindFirstObjectByType(typeof(TestComponent2), true);
UnityEngine.Object object = FindFirstObjectByType<TestComponent2>(true);
// インスタンスID順に整列しない分少し高速に動作する
UnityEngine.Object object =
    FindAnyObjectByType(Type type, FindObjectsInactive findObjectsInactive);