[Unity] ヒエラルキーのGameObjectの順序をスクリプトから取得・操作する
ヒエラルキーに表示されるGameObjectの並び順を取得したり操作したりする方法の紹介です。
同じ階層のGameObjectは順番も保存されるようになっており、次回シーンを開き直したときも順番が変わることはありません。
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」を選択するとコンソール上に以下のような出力結果が表示されます。
ObjA~Cの順序をヒエラルキー上で変更して再表示してみると、
対応したインデックスに変わっていることが確認できます。
この順序はスクリプトから指定することも出来ます。
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()); } }
Transform.SetSiblingIndex()を実行した時点で順序が反映されるので注意が必要です。
たとえば同階層のGameObjectを座標やDepth順でソートしたい場合などに活用できるでしょう。
■参考サイト
Unity – Scripting API: Transform.GetSiblingIndex
Unity – Scripting API: Transform.SetSiblingIndex