4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Unity】Grid Layout Groupに追加されたGameObjectをソートする

Last updated at Posted at 2019-12-10

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]);
}

コード解説

  1. セルをSelectし、全SiblingIndexを取得(GetSiblingIndex)します。
  2. 前項で取得したSiblingIndexをReverseし、逆順のSiblingIndexを取得します。
  3. セルを元の順番で順次参照し、前項の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

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?