Unity

【Unity】Unity UIの自動レイアウトでリスト化されたオブジェクトの並び順を任意に変更する方法

https://ga-review.com

はじめに

Unity UIの自動レイアウト(Horizontal Layout Group)でリスト化されたオブジェクトの並び順をスクリプトを使って任意に変更する方法についての備忘録です。

これを

こんな感じで並び変えるのが目的です。

本記事は以下のバージョンで確認できている情報です。
Unityバージョン:2022.3.9f1
バージョンが異なる場合操作方法やUIに差異がある場合がありますのでご注意ください。

この記事に書いてあること

Unity UIの自動レイアウト(Horizontal Layout Group)でリスト化されたオブジェクトの並び順をスクリプトを使って任意に変更する方法

この記事に書いていないこと

Unity UIの自動レイアウト(Horizontal Layout Group以外)でリスト化されたオブジェクトの並び順を変更する方法
Unity UIの自動レイアウトでリスト化されたオブジェクトの並び順をスクリプト以外で変更する方法

詳細手順

手順① 

プロジェクトの任意の場所に下記二つのスクリプトを準備します。
①ListOrder.cs → リストに表示されるオブジェクトに順位を設定するスクリプト
②SortObjectsByOrder.cs → リストのオブジェクトの順位に合わせてオブジェクトの並び順を変更するスクリプト

スクリプトの作成は、プロジェクトの任意の階層で以下のどちらかの手順で作成できます。
「右クリック」→「作成」→「C#スクリプト」
「"+"ボタンをクリック」→「C#スクリプト」

using UnityEngine;

public class ListOrder : MonoBehaviour
{
    // インスペクターで順位を設定可能にする
    [Range(0, 100)]
    public int order = 0; // 順位
}
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class SortObjectsByOrder : MonoBehaviour
{
    public HorizontalLayoutGroup horizontalLayoutGroup;  // Horizontal Layout Group の参照

    void Start()
    {
        // 子オブジェクトを取得し、ListOrderコンポーネントを持つオブジェクトを並べ替える
        var children = horizontalLayoutGroup.transform
            .Cast<Transform>()  // Transformをキャスト
            .Select(t => t.GetComponent<ListOrder>())  // ListOrderコンポーネントを取得
            .Where(c => c != null)  // ListOrderを持つオブジェクトのみを取得
            .OrderBy(c => c.order)  // 順位に基づいて並べ替え
            .ToList();

        // 並べ替えた順に並べ直す
        for (int i = 0; i < children.Count; i++)
        {
            children[i].transform.SetSiblingIndex(i);  // 並べ替えた順にSiblingIndexを設定
        }
    }
}

手順②

リストに表示されるすべての子オブジェクトに手順①で準備した「ListOrder.cs」をアタッチする。

リストの親オブジェクト(Horizontal Layout Groupがアタッチされているオブジェクト)に手順①で準備した「SortObjectsByOrder.cs」をアタッチする。

手順③

「ListOrder.cs」をアタッチしたオブジェクトに優先順位を設定し、ゲームを動作させて期待通りの並び順に変更されていることを確認する。

スクリプトはゲームを開始してから機能するため、編集中の並び順は変更されません。

複数のオブジェクトの優先順位が同値である場合の動作については未検証です。

本記事は以上となります。

-Unity