Sceneには何がある? GameObject一覧をC#から表示してみよう【Unity 6】

2026年10月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. 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
  • 自分で作ったスクリプト
UnityのScene、GameObject、Componentの関係を示した図

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です。

UnityのScene内のルートGameObjectと子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

ここで行っていることは、次の流れです。

  1. Sceneの一番上のGameObjectを取得する
  2. GameObjectの名前を表示する
  3. 子GameObjectを調べる
  4. さらにその子も調べる

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が表示してくれている情報を、自分のプログラムから取得しているわけです。

UnityのHierarchyとInspectorをC#のGameObject取得とComponent取得に対応させた図

11. FindObjectsByTypeとGetRootGameObjectsは何が違う?

今回、GameObjectを調べる方法が2つ登場しました。違いを整理します。

FindObjectsByTypeGetRootGameObjects()
調べる範囲読み込まれている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の構造を整理しやすくなります。

  1. GameObjectを作る(new GameObject()から作ってみよう)
  2. Componentを追加する(同上)
  3. GameObjectのComponentを調べる(前回の記事)
  4. SceneのGameObjectを調べる(今回)
  5. Scene → GameObject → Componentを見る(今回)
訪問数 13 回, 今日の訪問数 1回

広告

C#

Posted by hidepon