[Unity] ヒエラルキーのGameObjectの順序をスクリプトから取得・操作する

ヒエラルキーに表示されるGameObjectの並び順を取得したり操作したりする方法の紹介です。

同じ階層のGameObjectは順番も保存されるようになっており、次回シーンを開き直したときも順番が変わることはありません。

obj-order

GameObjectの同階層における順序はTransform.GetSiblingIndex()で取得できます。
戻り値は0から始まるインデックスです。

実際の使い方は以下の通りです。

IndexTest.cs

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

public class IndexTest : MonoBehaviour {
    [ContextMenu("Show game object")]
    private void ShowGameObjects() {
        // 子階層のGameObjectをすべて表示
        foreach ( var obj in GetComponentsInChildren<Transform>() ) {
            ShowGameObject(obj.gameObject);
        }
    }

    // 指定されたGameObjectの名前とインデックスを表示
    private static void ShowGameObject(GameObject obj) {
        Debug.Log("name = " + obj.name + ", index = " + obj.transform.GetSiblingIndex());
    }
}

上記スクリプトを試しにParentという名前のGameObjectにアタッチし、コンテキストメニューから「Show game object」を選択するとコンソール上に以下のような出力結果が表示されます。

getindex1

ObjA~Cの順序をヒエラルキー上で変更して再表示してみると、

getindex2

対応したインデックスに変わっていることが確認できます。

この順序はスクリプトから指定することも出来ます。
Transform.SetSiblingIndex()を使います。
引数には変更後のインデックスを0始まりで指定します。

先ほどのスクリプトIndexTest.csを以下のように変更してコンテキストメニューから「Shuffle game object」を選択すると、GameObjectの順序が変わります。
(Shuffleと書いてますが、厳密なShuffleではありません)

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

public class IndexTest : MonoBehaviour {
    [ContextMenu("Show game object")]
    private void ShowGameObjects() {
        // 子階層のGameObjectをすべて表示
        foreach ( var obj in GetComponentsInChildren<Transform>() ) {
            ShowGameObject(obj.gameObject);
        }
    }

    [ContextMenu("Shuffle game object")]
    private void ShuffleGameObjects() {
        foreach ( var obj in GetComponentsInChildren<Transform>() ) {
            obj.SetSiblingIndex(0);
        }
    }

    // 指定されたGameObjectの名前とインデックスを表示
    private static void ShowGameObject(GameObject obj) {
        Debug.Log("name = " + obj.name + ", index = " + obj.transform.GetSiblingIndex());
    }
}

setindex

Transform.SetSiblingIndex()を実行した時点で順序が反映されるので注意が必要です。
たとえば同階層のGameObjectを座標やDepth順でソートしたい場合などに活用できるでしょう。

■参考サイト
Unity – Scripting API: Transform.GetSiblingIndex
Unity – Scripting API: Transform.SetSiblingIndex