この記事でのバージョン
Unity 2018.4.4f1
はじめに
GameObject.Findを使うとHierarchy上のオブジェクトを名前で検索する事ができますが、
(子に配置されているものだったら、transform.Findでも可)
//Targetという名前のGameObjectを検索し、取得(なければnull) Debug.Log(GameObject.Find("Target"));
残念ながら、アクティブじゃないオブジェクトは検索できません。
という事で今回は、Hierarchy上の非アクティブなオブジェクトを検索し、取得する方法の紹介です!
なお、GameObject.Findしかり、こういう検索系の処理は重いので、
使い所を(出来るなら使わない方向で)考える必要がある点には注意が必要です。
ちなみに今回はプログラムで検索と取得をする方法ですが、
エディタ上でパッと見つけたい時には以下の記事の拡張が使えます。
FindObjectsOfTypeAll
非アクティブなオブジェクトを検索し、取得したい場合は、
Resources.FindObjectsOfTypeAllを使います。
なお、FindObjectsOfTypeAllはオブジェクト名でなくタイプを指定して取得するので、
以下のようにGameObjectを全て取得し、その中から名前が一致するものを探す感じになります。
//GameObjectを全て取得 var gameObjectList = Resources.FindObjectsOfTypeAll<GameObject>(); //取得したGameObjectの中からTargetを探す foreach (var go in gameObjectList) { if (go.name == "Target") { Debug.Log("ターゲット! : " + go); } }
ただし、エディタ上だとHierarchy上だけでなくProject上のPrefabも取得してしまいます。
なので、AssetDatabase.GetAssetOrScenePathを使って
取得したものが、どこのものなのか判定する必要があります。
Debug.Log(AssetDatabase.GetAssetOrScenePath(gameObjectInHierarchy));
なお、AssetDatabaseとそれを使うためのusing UnityEditorはエディタ上でしか使えないので、
UNITY_EDITORで囲む必要もあります。まとめると以下のような感じ。
#if UNITY_EDITOR using UnityEditor; //AssetDatabaseを使うために必要 #endif
//GameObjectを全て取得 var gameObjectList = Resources.FindObjectsOfTypeAll<GameObject>(); //取得したGameObjectの中からTargetを探す foreach (var gameObjectInHierarchy in gameObjectList) { #if UNITY_EDITOR //Hierarchy上のものでなければスルー if (!AssetDatabase.GetAssetOrScenePath(gameObjectInHierarchy).Contains(".unity")) { continue; } #endif if (gameObjectInHierarchy.name == "Target") { Debug.Log("ターゲット! : " + gameObjectInHierarchy); } }
ちなみにLINQを使って以下のように実装する事も可能です。
var target = Resources.FindObjectsOfTypeAll<GameObject>() //GameObjectを全て取得 #if UNITY_EDITOR .Where(go => AssetDatabase.GetAssetOrScenePath(go).Contains(".unity")) //Hierarchy上のものだけ選別 #endif .First(go => go.name == "Target"); //Targetという名前のものを取得