Sceneには何がある? GameObject一覧をC#から表示してみよう【Unity 6】
前回の記事「GameObjectには何が付いている? GetComponentsでComponent一覧を表示してみよう【Unity】」では、1つのGameObjectに付いているComponentをC#から調べました。
今回は調べる範囲を広げて、Sceneの中にどんなGameObjectがあるのかを調べてみます。
Unityでゲームを作っていると、HierarchyにはたくさんのGameObjectが並びます。たとえば、次のようなものです。
Main Camera
Player
Ground
Canvas
EventSystem
普段はHierarchyを見れば確認できますが、「このSceneには、いったいどんなGameObjectが存在しているのだろう?」ということを、C#から調べることもできます。
今回は、Sceneの中のGameObjectをスクリプトから取得して一覧表示します。最後にはComponentまで含めて、次のような構造をConsoleに表示してみましょう。
Scene
├─ Player
│ ├─ Transform
│ ├─ SpriteRenderer
│ └─ Rigidbody2D
└─ Ground
├─ Transform
└─ BoxCollider2D
Unityの構造は、Scene → GameObject → Componentという並びになっています。これをC#から確認していきます。
- 1. 1. UnityのSceneの中にはGameObjectがある
- 2. 2. Scene内のGameObjectを取得してみる
- 3. 3. GameObject[]とは?
- 4. 4. FindObjectsSortMode.Noneとは?
- 5. 5. 非アクティブなGameObjectはどうなる?
- 6. 6. 今いるSceneの名前も表示してみる
- 7. 7. Hierarchyと同じように親子関係も見てみたい
- 8. 8. SceneのGameObjectをHierarchy風に表示する
- 9. 9. さらにComponentまで表示してみよう
- 10. 10. Unityの画面とC#の処理を対応させる
- 11. 11. FindObjectsByTypeとGetRootGameObjectsは何が違う?
- 12. 12. 今回理解してほしいこと
- 13. 13. まとめ
1. UnityのSceneの中にはGameObjectがある
まず、Unityの構造を簡単に整理します。Sceneの中にはGameObjectがあり、GameObjectにはComponentが付いています。
Scene
│
├─ GameObject
│ ├─ Component
│ ├─ Component
│ └─ Component
│
├─ GameObject
│ ├─ Component
│ └─ Component
│
└─ GameObject
普段Hierarchyで見ているのが、主にGameObjectです。Inspectorを開いたときに並んでいる、次のようなものがComponentです。
- Transform
- Sprite Renderer
- Rigidbody 2D
- Box Collider 2D
- 自分で作ったスクリプト

2. Scene内のGameObjectを取得してみる
まずは一番単純な方法です。次のスクリプトを作ります。
using UnityEngine;
public class SceneObjectList : MonoBehaviour
{
void Start()
{
GameObject[] objects =
FindObjectsByType<GameObject>(FindObjectsSortMode.None);
foreach (GameObject obj in objects)
{
Debug.Log(obj.name);
}
}
}
このスクリプトを適当なGameObjectに付けて実行してみます。Consoleには、たとえば次のように表示されます。
Main Camera
Player
Ground
Canvas
EventSystem
SceneObjectList
最後のSceneObjectListは、スクリプトを付けたGameObjectの名前です。スクリプトを付けたGameObjectも、Scene内のGameObjectの1つなので一覧に含まれます。
これで、読み込まれているScene内からGameObjectを探して、その名前を表示できました。
Unity 6では、オブジェクトを探すAPIとしてFindObjectsByTypeが用意されています。
FindObjectsByType<GameObject>(FindObjectsSortMode.None);
ここではGameObjectを探しているので、GameObjectの一覧が返ってきます。なお、複数のSceneを同時に読み込んでいるときは、読み込まれているSceneすべてが対象になります。
3. GameObject[]とは?
今回のコードには、GameObject[] objectsという部分が出てきました。
[]が付いていることに注目してください。これは、GameObjectを複数まとめて入れる箱(配列)だと考えると分かりやすいでしょう。前回のComponent[]と同じ考え方です。
たとえばSceneに、Player、Enemy、Ground、Main Cameraが存在していれば、次のように複数のGameObjectが格納されます。
objects[0]
objects[1]
objects[2]
objects[3]
そのため、foreach (GameObject obj in objects)を使って、1つずつ取り出しています。
4. FindObjectsSortMode.Noneとは?
次の部分も、初めて見ると分かりにくいかもしれません。
FindObjectsSortMode.None
これは、見つけたGameObjectを並べ替えなくてよいという指定です。Noneを指定した場合、Unityは結果を並べ替える処理を行わないので、そのぶん負荷を抑えられます。
ただし、表示されるGameObjectの順番は保証されません。Hierarchyと同じ順番になるとは限らないため、次のように表示されることもあります。
Player
Main Camera
Ground
今回の目的は、SceneにどんなGameObjectが存在するか確認することなので、順番は特に問題ありません。
5. 非アクティブなGameObjectはどうなる?
Hierarchyでは、GameObjectのチェックを外して非アクティブにすることがあります。たとえば、次のようなSceneを考えます。
Player
Enemy
SecretDoor ← 非アクティブ
Ground
先ほどのFindObjectsByType<GameObject>(FindObjectsSortMode.None)では、非アクティブなGameObjectは含まれません。
非アクティブなGameObjectも含めたい場合は、次のようにFindObjectsInactive.Includeを指定します。
GameObject[] objects =
FindObjectsByType<GameObject>(
FindObjectsInactive.Include,
FindObjectsSortMode.None
);
これなら、SecretDoorのような非アクティブなGameObjectも対象になります。
6. 今いるSceneの名前も表示してみる
どのSceneを調べているのかも表示してみましょう。Sceneを扱うので、using UnityEngine.SceneManagement;を追加します。
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneObjectList : MonoBehaviour
{
void Start()
{
Scene scene = SceneManager.GetActiveScene();
Debug.Log("Scene : " + scene.name);
GameObject[] objects =
FindObjectsByType<GameObject>(FindObjectsSortMode.None);
foreach (GameObject obj in objects)
{
Debug.Log(obj.name);
}
}
}
SceneManager.GetActiveScene()を使うと、現在アクティブになっているSceneを取得できます。実行すると、次のように表示されます。
Scene : SampleScene
Main Camera
Player
Ground
Canvas
EventSystem
7. Hierarchyと同じように親子関係も見てみたい
ここまでの方法では、GameObjectの名前は分かります。ただし、Player、Weapon、Enemy、Main Cameraと表示されても、次のような親子関係までは分かりません。
Player
└─ Weapon
UnityのHierarchyに近い形で表示したい場合は、Sceneの一番上にあるGameObjectから順番に調べる方法があります。現在のSceneはSceneManager.GetActiveScene()で取得でき、そのSceneのGetRootGameObjects()を使うと、ルートGameObjectを取得できます。
ルートGameObjectとは、親GameObjectを持っていない、一番上のGameObjectのことです。たとえば、次のSceneを考えます。
Player
└─ Weapon
Enemy
Environment
├─ Ground
└─ Tree
この場合、Player、Enemy、Environmentがルートです。Weapon、Ground、Treeは、ルートではなく子GameObjectです。

8. SceneのGameObjectをHierarchy風に表示する
では、少し発展させて、ルートGameObjectから子GameObjectまで順番にたどって表示してみましょう。
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneHierarchyList : MonoBehaviour
{
void Start()
{
Scene scene = SceneManager.GetActiveScene();
Debug.Log("Scene : " + scene.name);
GameObject[] rootObjects = scene.GetRootGameObjects();
foreach (GameObject rootObject in rootObjects)
{
ShowGameObject(rootObject.transform, 0);
}
}
void ShowGameObject(Transform target, int depth)
{
string indent = new string(' ', depth * 2);
Debug.Log(indent + target.name);
foreach (Transform child in target)
{
ShowGameObject(child, depth + 1);
}
}
}
たとえばHierarchyが次のようになっているとします。
Player
├─ Weapon
└─ CameraTarget
Environment
├─ Ground
└─ Tree
Consoleにも、似た構造で表示できます。
Scene : SampleScene
Player
Weapon
CameraTarget
Environment
Ground
Tree
ここで行っていることは、次の流れです。
- Sceneの一番上のGameObjectを取得する
- GameObjectの名前を表示する
- 子GameObjectを調べる
- さらにその子も調べる
foreach (Transform child in target)のように、Transformに対してforeachを使うと、直下の子GameObjectを1つずつ取り出せます。
そしてShowGameObjectが、子に対して自分自身をもう一度呼び出しています。これは再帰処理と呼ばれる書き方です。ただし、今回は再帰そのものを理解することが目的ではありません。まずは、GameObjectの中に子GameObjectがあり、Scene全体が木のような構造になっていることが分かれば十分です。
9. さらにComponentまで表示してみよう
ここまで来たら、前回の記事で学習したGetComponentsと組み合わせることができます。
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneHierarchyList : MonoBehaviour
{
void Start()
{
Scene scene = SceneManager.GetActiveScene();
Debug.Log("Scene : " + scene.name);
GameObject[] rootObjects = scene.GetRootGameObjects();
foreach (GameObject rootObject in rootObjects)
{
ShowGameObject(rootObject.transform, 0);
}
}
void ShowGameObject(Transform target, int depth)
{
string indent = new string(' ', depth * 2);
Debug.Log(indent + target.name);
Component[] components =
target.gameObject.GetComponents<Component>();
foreach (Component component in components)
{
if (component == null)
{
continue;
}
Debug.Log(
indent +
" └ Component : " +
component.GetType().Name
);
}
foreach (Transform child in target)
{
ShowGameObject(child, depth + 1);
}
}
}
実行すると、たとえば次のように表示されます。
Player
└ Component : Transform
└ Component : SpriteRenderer
└ Component : Rigidbody2D
└ Component : PlayerController
Ground
└ Component : Transform
└ Component : BoxCollider2D
GetComponents<Component>()は、指定したGameObjectに付いているComponentをまとめて取得します。if (component == null)は、スクリプトを読み込めないComponentが含まれていた場合に、表示処理が止まるのを防ぐための確認です。
ここまで来ると、HierarchyとInspectorの情報をC#から読み取っていることが分かると思います。
10. Unityの画面とC#の処理を対応させる
普段Unity Editorでは、Hierarchyを見てGameObjectを確認し、Inspectorを見てComponentを確認しています。今回C#で行ったことを対応させると、次のようになります。
| Unity Editorで見ているもの | C#で行った処理 |
|---|---|
| Hierarchy(GameObjectの一覧と親子関係) | FindObjectsByType / GetRootGameObjects() |
| Inspector(付いているComponent) | GetComponents<Component>() |
つまり、Unity Editorが表示してくれている情報を、自分のプログラムから取得しているわけです。

11. FindObjectsByTypeとGetRootGameObjectsは何が違う?
今回、GameObjectを調べる方法が2つ登場しました。違いを整理します。
FindObjectsByType | GetRootGameObjects() | |
|---|---|---|
| 調べる範囲 | 読み込まれているScene全体(複数Sceneを読み込んでいれば、すべてが対象) | 指定した1つのScene |
| 取得できるもの | 条件に合うGameObject(子GameObjectも含む) | ルートGameObjectだけ(子はtransformからたどる) |
| 向いている使い方 | 「どんなGameObjectが存在する?」と手早く調べる | Hierarchyの親子構造をたどる |
今回のようにUnityのScene構造を学習するという目的なら、GetRootGameObjects()から親子をたどる方法のほうが、Unityの仕組みを理解しやすいでしょう。
12. 今回理解してほしいこと
今回、一番大切なのはAPI名を暗記することではありません。UnityのSceneを、次のような構造として考えられるようになることです。
Scene
│
├─ GameObject
│ ├─ Component
│ ├─ Component
│ └─ Component
│
└─ GameObject
├─ Component
└─ Component
普段Unity Editorで見ているHierarchyとInspectorも、実はこの構造を見やすく表示してくれているだけです。C#から調べてみることで、Unityの画面に表示されているものには、ちゃんとプログラムからアクセスできることが見えてきます。
13. まとめ
今回はScene内のGameObjectをC#から調べました。使ったメソッドを整理します。
FindObjectsByType<GameObject>(FindObjectsSortMode.None):GameObjectの一覧を取得するSceneManager.GetActiveScene():現在アクティブなSceneを取得するscene.GetRootGameObjects():Sceneの一番上にあるGameObjectを取得するGetComponents<Component>():GameObjectに付いているComponentを取得する
GameObjectとは何か、Componentとは何かを言葉だけで覚えるより、実際にUnity自身に「何を持っているの?」と聞いてみるのも一つの学習方法です。HierarchyとInspectorを見るだけだったUnityが、少し違って見えてくるかもしれません。
学習順としては、次のように進めると、Unityの構造を整理しやすくなります。
- GameObjectを作る(new GameObject()から作ってみよう)
- Componentを追加する(同上)
- GameObjectのComponentを調べる(前回の記事)
- SceneのGameObjectを調べる(今回)
- Scene → GameObject → Componentを見る(今回)










ディスカッション
コメント一覧
まだ、コメントがありません