子オブジェクトの取得

2019年2月14日

子ゲームオブジェクトの検索

ゲームのシーンでは、敵、ウェイポイント、障害物など、同じ種類の多くのゲームオブジェクトを使用することがしばしばあります。これらのオブジェクトは、監視または反応する特定のスクリプトによって追跡されることがあります (例えば、すべてのウェイポイントは、経路探索スクリプトで使用可能です)。変数を使用してこれらのゲームオブジェクトを関連付けることは可能ですが、新しいウェイポイントを 1 つずつスクリプト上の変数にドラッグする必要がある場合、設計面での処理が面倒になります。同様に、ウェイポイントを削除する場合に、欠けているゲームオブジェクトへの変数の参照を削除する必要があります。このような場合、ゲームオブジェクトの群をすべて 1 つの親ゲームオブジェクトの子にすることによって管理するほうが良いことがあります。子のゲームオブジェクトは親の Transform コンポーネントを使用して取得できます (なぜなら、すべてのゲームオブジェクトに暗黙的に Transform があるからです)。

次にいくつかのサンプルを示します。子オブジェクト、孫オブジェクトを取得する方法について具体的に見ていきましょう。

シーンの構成

  1. 5つのオブジェクト(Cube)をCreateします。
  2. Hierarchyウィンドウのように親子関係を作ります。
  3. テスト用にProjectウィンドウに4つのスクリプトを作成します。(後述)
  4. テストしたいスクリプトをenebleにします。

いろいろな方法

子オブジェクトの全てを配列で取得

Transform型の配列waypointsを用意します。これに子オブジェクトを代入していきます。
gameObjectとして使いたい場合、
waypoints[インデックス番号].gameobject
で取得することができます。

スクリプト

using UnityEngine;

/// <summary>
/// 子オブジェクトの全てを配列で取得します。
/// </summary>
public class ChildGet_Array : MonoBehaviour
{
    [SerializeField]
    Transform[] waypoints;

    // Start is called before the first frame update
    void Start()
    {
        waypoints = new Transform[transform.childCount];
        int i = 0;

        foreach (Transform t in transform)
        {
            waypoints[i++] = t;
        }

        foreach (var t in waypoints)
        {
            Debug.Log(t.name);
        }
    }
}

実行結果

子オブジェクトの全てをコレクション(List)で取得

スクリプト

using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 子オブジェクトの全てをコレクション(List)で取得します。
/// </summary>
public class ChildGet_List : MonoBehaviour
{
    [SerializeField]
    List<Transform> waypoints;

    // Start is called before the first frame update
    void Start()
    {
        foreach (Transform t in transform)
        {
            waypoints.Add(t);
        }

        foreach (var t in waypoints)
        {
            Debug.Log(t.name);
        }
    }
}

実行結果

子オブジェクトの1つを取得

スクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 子オブジェクトの取得
/// Transform.Findメソッドを使います。
/// </summary>
public class ChildFind : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        //  これは旧形式なので使わない
        //   var obj = transform.FindChild("child1");
        var obj = transform.Find("Child1");
        Debug.Log(obj.name);

    }
}

実行結果

子、孫オブジェクトの全てをコレクション(List)で取得

スクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GetHierarchy : MonoBehaviour
{
    [SerializeField]
    List<Transform> waypoints;

    // Start is called before the first frame update
    void Start()
    {
        foreach (Transform t in transform.GetComponentsInChildren<Transform>())
        {
            waypoints.Add(t);
        }

        foreach (var t in waypoints)
        {
            Debug.Log(t.name);
        }
    }
}

実行結果

公式参考

2019年2月14日Unity,小技

Posted by hidepon