はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】Hierarchy上のゲームオブジェクト(コンポーネント)を全て取得する方法

はじめに

今回はHierarchy上のゲームオブジェクト(コンポーネント)を全て取得する方法についての記事になります!

Hierarchy上のゲームオブジェクトといっても、この2つの場合に分けられるのではないでしょうか。

  • Activeな全てのゲームオブジェクトを取得
  • Activeに関係なく全てのゲームオブジェクトを取得

前者はObject.FindObjectsOfType,後者はResources.FindObjectsOfTypeAllを使えば実現できますが、特に後者は誤った情報をよく見ます。

さっそく見ていきましょう!

Activeな全てのゲームオブジェクトを取得

Object.FindObjectsOfTypeを使うことでHierarchy上のActiveなゲームオブジェクトを全て取得することができます

public static Object[] FindObjectsOfType(Type type);

typeオブジェクトの型を指していて、Typeof(GameObject)Typeof(Transform)などを指定することができます。

using UnityEngine;

public class FindObjectTest : MonoBehaviour
{
    private void Start()
    {
        //Hierarchy上にActiveで表示されているGameObjectを配列で受け取る
        GameObject[] gameObjects = FindObjectsOfType(typeof(GameObject)) as GameObject[];

        //受け取った配列のそれぞれの名前を出力
        foreach(var item in gameObjects)
        {
            Debug.Log(item.name);
        }
    }
}

Activeに関係なく全てのゲームオブジェクトを取得

Resources.FindObjectsOfTypeAllを使うことでHierarchy上のActiveでないものも含めてゲームオブジェクトを全て取得することができます

ただそのまま使おうとするとAssetsフォルダ内のオブジェクトも検索されてしまう仕様になっています。これは必要ないので、HideFlagsを利用してAssetsフォルダ内のオブジェクトは検索対象外にする必要があります。
全ての GameObject をリストアップ 凛(kagring)のUE4とUnityとQt勉強中ブログ

public static Object[] FindObjectsOfTypeAll(Type type);

ここでのtypeは先程と同様に扱います。

using UnityEngine;
using System.Collections.Generic;
using System.Linq;      //これを忘れずに


public class FindObjectTest : MonoBehaviour
{
    private void Start()
    {
        //Hierarchy上のGameObjectのコレクションを受け取る
        var gameObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject))
            .Select(c => c as GameObject)
            .Where(c => c.hideFlags != HideFlags.NotEditable && c.hideFlags != HideFlags.HideAndDontSave);

        //受け取ったコレクションのそれぞれの名前を出力
        foreach(var item in gameObjects)
        {
            Debug.Log(item.name);
        }
    }
}


ちなみにLinqが曖昧な方をこちらを一読ください。
www.hanachiru-blog.com

さいごに

Hierarchy上のゲームオブジェクトを全て取得する方法を紹介しました。

ただこれらの処理は比較的重い処理とされているので、Update内で呼ぶなどは避けたほうが良いとは思います。