経緯
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/豆知識を添えて 〜