【Unity】Hierarchy上のゲームオブジェクトを全て取得
経緯
Hierarchy上のGameObjectを全て取得し、
そのGameObjectに対して色々したいEditorWindowを作るときに
必要になったので調べることにしました。
方法
Hierarchy上のGameObjectを全て取得する方法は2通りあります。
1通り目はActiveであるGameObjectの配列を返す
UnityEngine.Object.FindObjectsOfTypeです。
ですが、これはActiveであるGameObjectのみです。
2通り目はUnityオブジェクトとしてロードされているものを対象にTypeで指定した型の全てのオブジェクトの配列を返す
UnityEngine.Resources.FindObjectsOfTypeAllです。
これを使えば、ActiveでないGameObjectも取得することが可能です。
下記にこの2通りのサンプルスクリプトを記述しております。
Object.FindObjectsOfType
using UnityEngine; using System.Collections; /*===============================================================*/ /** * ActiveであるGameObjectのみを取得するサンプル * 2014年12月31日 Buravo */ public class Example : MonoBehaviour { /*===============================================================*/ /** * @brief 最初に一度だけ実行されるメソッド */ void Start () { // typeで指定した型の全てのオブジェクトを配列で取得し,その要素数分繰り返す. foreach (GameObject obj in UnityEngine.Object.FindObjectsOfType(typeof(GameObject))) { // シーン上に存在するオブジェクトならば処理. if (obj.activeInHierarchy) { // GameObjectの名前を表示. Debug.Log(obj.name); } } } /*===============================================================*/ } /*===============================================================*/
このスクリプトではFindObjectsOfTypeで取得した配列をforeach文で繰り返しています。
取得したGameObjectがシーンで有効であるかをactiveInHierarchyプロパティで調べています。
Resources.FindObjectsOfTypeAll
using UnityEngine; using UnityEditor; using System.Collections; using System; /*===============================================================*/ /** * ActiveでないGameObjectも取得するサンプル * 2014年12月31日 Buravo */ public class Example : MonoBehaviour { /*===============================================================*/ /** * @brief 最初に一度だけ実行されるメソッド */ void Start () { // Typeで指定した型の全てのオブジェクトを配列で取得し,その要素数分繰り返す. foreach (GameObject obj in UnityEngine.Resources.FindObjectsOfTypeAll(typeof(GameObject))) { // アセットからパスを取得.シーン上に存在するオブジェクトの場合,シーンファイル(.unity)のパスを取得. string path = AssetDatabase.GetAssetOrScenePath(obj); // シーン上に存在するオブジェクトかどうか文字列で判定. bool isScene = path.Contains(".unity"); // シーン上に存在するオブジェクトならば処理. if (isScene) { // GameObjectの名前を表示. Debug.Log(obj.name); } } } /*===============================================================*/ } /*===============================================================*/
このスクリプトではFindObjectsOfTypeAll関数で取得した配列をforeach文で繰り返しています。
取得したGameObjectがシーン上に存在するオブジェクトかどうかを判断するために、
まずはAssetDatabase.GetAssetOrScenePath関数でアセットからパスを取得します。
これはシーン上に存在するオブジェクトの場合、シーンファイル(.unity)のパスが返されます。
この文字列が一致するかどうかをSystem.String.Contains関数を使用して判断し、
一致するならばシーン上に存在するオブジェクトとして処理しています。
まとめ
ActiveなオブジェクトのみならばObject.FindObjectsOfTypeを
Activeでないオブジェクトも含めたいならばResources.FindObjectsOfTypeAllを
場合に応じて使っていけばいいと思います。
参考サイト
Unity Editor上で動く自作ツールについて 〜 TIPS/豆知識を添えて 〜