Grid Layout Groupに追加されたGameObjectをソート
概要
ゲーム中のアイテムリスト、カードリスト等、ScrollViewなどでグリッドレイアウトは頻繁に使用されますが、これはUnity標準のコンポーネントであるGrid Layout Groupで解決することができます。
しかし、そういったリストの大半はソート機能が必要になる場合がほとんどです。
調べた限り、UnityにはのGrid Layout Group上に配置された子GameObjectをソートするような機能は、標準で存在しないようです。
本記事はGrid Layout Groupのソートについて、メモレベルで説明します。
Grid Layout Groupの使い方そのものについては、本記事の下部に記載している参考記事などをご参照下さい。
想定
Grid Layout Group(以降Contentと呼ぶ)に対して、以下ように、Prefabを子GameObject(以下セルと呼ぶ)として動的に生成、関連付けている。
var childObj = Instantiate(/* セルのPrefab */); // セルを生成
childObj.transform.parent = contentObj.transform; // セルをContent配下に配置
この状態から昇順/降順にソートしたい、というシチュエーションを想定しています。
やりかた
以下に雰囲気コードを示します。
var childObjs = /* 何らかの方法でContent内のセル(GameObject)の一覧を取得 */;
var siblingIndexes = childObjs.Select(c => c.transform.GetSiblingIndex()).Reverse().ToArray();
for (var i = 0; i < childObjs.Count; i++) {
childObjs[i].transform.SetSiblingIndex(siblingIndexes[i]);
}
コード解説
- セルをSelectし、全SiblingIndexを取得(GetSiblingIndex)します。
- 前項で取得したSiblingIndexをReverseし、逆順のSiblingIndexを取得します。
- セルを元の順番で順次参照し、前項のSiblingIndexをセット(SetSiblingIndex)します。
補足
ある階層に並列で配置されたオブジェクト、すなわち兄弟(Sibling)間のオブジェクトの表示順序は、Unityにより管理されるSiblingIndexによって決定されています。
このSiblingIndexは、例えばContent以下の兄弟オブジェクトの場合、Unityのエディタ上の見た目そのまま、Hierarchyの表示順に、0から順に振られています。
例:Hierarchyがこんな感じとした場合のSiblingIndex
...
└ Content // ScrollViewのContentとか
├ childObjA // 0
├ childObjB // 1
├ childObjC // 2
└ childObjD // 3
...
Grid Layout Groupの1セルの表示順(Hierarchyの配置順)はSiblingIndexにより決定しています。
ですので、セルのソートを反転したい場合は、現在のSiblingIndexを逆順で取得(GetSiblingIndex)し、
それを現在のセルの配置順に上書き(SetSiblingIndex)していくことでセルの表示順を反転させることができます。
例:すべてのセルのSiblingIndexをReverseしてセットし直した状態のHierarchy
...
└ Content // ScrollViewのContentとか
├ childObjD // 0
├ childObjC // 1
├ childObjB // 2
└ childObjA // 3
...
応用メモ
単純なソートは昇順/降順ソートは上記のように行うことができますが、
たとえば、セルであるGameObjectにスクリプトをアタッチし、そこに「種別」などの情報をもたせて、より複雑なソートアルゴリズムを適用できるでしょう。
今回例に示したソースはReverseを使用して単純反転させましたが、特にこれを使用しなければならないという事はありません。
参考資料
Grid Layout Groupの使い方
https://qiita.com/t_Kaku_7/items/588fada25cf2d519589d
https://tech.pjin.jp/blog/2016/08/30/unity_skill_3/
SiblingIndexについて
https://forum.unity.com/threads/order-of-elements-in-layout-groups.267668/
https://qiita.com/T_2/items/69c22e649441055d2329