uGUIで要素の高さがバラバラのリストUIを作りたい
たとえば、以下のようなリスト形式のUIを、UnityのuGUIで作りたいとします。
CheryBlossom
の行の高さが、ボタンクリックによって変わっています。
つまり、ユーザー操作によって、リスト内要素の高さが動的に変化します。
CheryBlossom
の高さの変化に合わせて、その下にある Water Daytime
と [Skybox] EpicSky
の行は、表示位置が上下に変化しています。
こういうUIは、Editor系のツールではよく見かけるものです。
ただ、uGUIで実装するのは意外と難しいので、本記事で解説します!
要素の Height
, Pos Y
を計算するコードを自前で書くのは大変すぎる
まず、要素の高さ調整は、 Rect Transform
の Height
を計算すればできます。
同様に、Pos Y
を動的に計算すれば、上下位置の調整もできます。
リスト内の全要素の Height
と Pos Y
を計算するスクリプトを書けば、実は目標は達成できるのです。
しかし、この方法は非常に工数がかかります。
要素の追加機能・削除機能・ソート機能等を今後実装する計画があるとしたら、そのすべてで Height
, Pos Y
の調整処理を考慮する必要があります。
HTMLの <ul>
<li>
みたいに、自動で Height
, Pos Y
を調整してくれる方法はないのでしょうか?
要素の Height
, Pos Y
は Vertical Layout Group
が自動で調整してくれる!
自動で Height
, Pos Y
を調整してくれる仕組みがちゃんとuGUIにもあります。
それが Vertical Layout Group
です!
まずは説明のため、要素の高さが動的に変化せず、 Pos Y
の計算のみを自動化する方法をご紹介します。
はじめに、要素の親となるGameObjectに Vertical Layout Group
をアタッチします。これは、HTMLで例えるなら、 <ul>
の役割です。
次に要素となるGameObjectに Layout Element
をアタッチします。HTMLで例えるなら、 <li>
の役割です。
Preferred Height
と Min Height
に数値を設定することで、要素の高さを固定化できます。
ここまでスクリプトを一切書いていませんが、これだけで、 Pos Y
の自動計算は実現できます!
リスト内にリストがある場合
次に、 Height
の自動化を考えます。
リスト内要素の Height
を自動的に調整したいというのは、ようするに、リスト内の要素がさらにリストを持っているような状況だと想定できます。
以下の図のような状況です。
このように、リスト内リストがある場合は、 Vertical Layout Group
をネストしましょう!
上図のように、 Layout Element
と並列で Vertical Layout Group
を設置しても問題ありません。
私が確認した限り、ネストは3階層までやっても問題なく動作しました。
これで、リスト内要素の Height
の自動調整もできました!
リストの高さを要素にフィットさせるには
たとえば以下のように、リスト内要素の数が動的に変化するUIを作るとします。
上記のように、要素数に応じて、リストの高さをフィットさせなければならないケースがあります。
Vertical Layout Group
を使えばできそうな気がしますが、実はそれだけでは実現できません。
こういう時は、 Content Size Fitter
を使いましょう!
Vertical Layout Group
を付けているGameObjectに Content Size Fitter
を付けるだけで、要素にピタッとフィットします!
組み合わせたい時はどうすればいいのか?
ここまでご紹介した Vertical Layout Group
, Layout Element
, Content Size Fitter
を組み合わせたくなるケースが出てくると思います。
その際、適切にコンポーネントを設定しないと、互いのコンポーネントの機能が競合して、わけのわからない挙動をするようになります。
それを防ぐためにも、以下の点を見直す必要があります。
高さが変化しない要素には Layout Element
を設定しよう!
まずは、高さが変化しない要素に Layout Element
をアタッチして、 Min Height
, Preferred Height
を設定しましょう!
高さが変化する要素には Vertical Layout Group
を設定しよう!
リストがあるなら、 Vertical Layout Group
をアタッチしましょう!
リスト内リストがあるなら、そこにもアタッチしましょう!
リスト内リスト内リストがあるなら、そこにもアタッチしましょう!
つまり、配下要素によって高さが変化する要素すべてに Vertical Layout Group
をアタッチしましょう!
Content Size Fitter
はリストの一番親にのみ設定しよう!
最後に、 リストの一番親のGameObjectに Content Size Fitter
を付けましょう。
それ以外の箇所に設定する必要はありません。(設定すると、Unityから警告が出ます。)
ここまでをまとめると、以下の図のようになります!
おまけ: UI Toolkit
なら自動でレイアウトされる
ここまでuGUIで自動レイアウトをする方法をご紹介してきましたが、 Unity2020.1以降で利用できるUI Toolkitであれば、とくに意識しなくても自動で寸法・配置が調整されます!便利ですね!
さいごに
本記事作成にあたり、以下のサイトを参考にさせていただきました。ありがとうございました。
また、本記事に利用しているスクリーンショットは、弊社で運営しているSTYLY Studioというサイトのものです。興味があれば覗いてみてください!