【Unity】LayoutGroupについて

LayoutGroupについて

LayoutGroupのコンポーネント配下のGameObjectを自動的に配置します。 位置の調整や要素の大きさなど、LayoutGroupの設定項目に合わせてレイアウトします。

種類

LayoutGroupは次の3つ種類が用意されています。

  • Horizontal Layout Group (水平)
  • Vertical Layout Group (垂直)
  • Grid Layout Group (グリッド)

設定項目

Padding

要素の位置関係をPaddingで設定します。

  • Left
  • Right
  • Top
  • Bottom
  • Spacing

Child Alignment

要素の配置位置を設定します。

f:id:albatrus:20210307154114p:plain:w300
Upper Leftの場合
f:id:albatrus:20210307154038p:plain:w300
Middle Centerの場合

Reverse Arrangement

要素の並び順を逆転させます。

Control Child Size

自身のサイズとPaddingの設定に合わせて、要素のLayout Element大きさを変更します。 Layout Element - Unity マニュアル

Use Child Scale

要素のScaleを加味して位置や大きさを調整します。

f:id:albatrus:20210307153115p:plain:w300
Use Child Scaleを使わない場合、Scaleを無視して要素が配置される

f:id:albatrus:20210307153202p:plain:w300
Use Child Scaleを使わう場合、Scaleを加味して要素が配置される

Child Force Expand

要素をFlexible Sizeに合わせて変更を行います。 Flexible SizeとはLayoutGroupコンポーネントがアタッチされているGameObjectのwidthとHeightになります。

f:id:albatrus:20210307152728p:plain:w300
Child Force Expandを使わない場合、Preferred Sizeに要素が配置される

f:id:albatrus:20210307152835p:plain:w300
Child Force Expandを使った場合、Flexible Sizeに合わせて要素が配置されます

できること

実装例

実際にLayoutGroupを使った実装例を紹介します。

可変Textを加味してUIを並べる

次の2つのコンポーネントをアタッチします。 PaddingやChild Alignmentなどは好きなように設定をします。

f:id:albatrus:20210307155227p:plain:w350
Inspector

要素はImage、Text、Imageの順番に配置しています。 (ImageにはLayout ElementコンポーネントをアタッチしてMin Sizeを設定しています)

f:id:albatrus:20210307155320p:plain:w350
要素の配置

Textの文字数を変更しても要素の位置関係はそのままです。(画像ではわかりにくいですが...)

f:id:albatrus:20210307155617p:plain:w350
Textの文字を変えても、Imageの位置関係はそのままです。

パフォーマンス

公式にも書かれていますが、このLayoutGroupはパフォーマンスが良くありません。

自身のレイアウトをダーティとしてマークする UI 要素は、少なくとも GetComponents を 1 つ以上呼び出します。この呼び出しは、まずレイアウト要素から、親の有効なレイアウトグループを検索します。該当するレイアウトグループが見つかった場合は、検索を停止するか、ヒエラルキーのルート階層に到達するかのいずれか早い方で、ヒエラルキー内の Transform を上っていきます。したがって、各レイアウトグループは、それぞれの子レイアウト要素のダーティ化処理に GetComponents の呼び出しを 1 回追加することになり、ネスト化されたレイアウトグループのパフォーマンスを極度に悪化させます。

forpro.unity3d.jp

LayoutRebuilder.MarkLayoutForRebuild

LayoutGroupのコードを見てみると、このメソッドが重い処理のようです。 このメソッドは、OnRectTransformDimensionsChange、OnEnable時にも呼び出されているで、何かしらの更新があったときに、その都度UIの再構築処理が走るのが原因っぽいです。

最後に

処理は重いのは確かなのですが、複雑なUIが実装できるのがLayoutGroupの良いところです。 ですので、使わないと判断するよりも要所要所パフォーマンスを見て使っていくのが個人的には良いと思っています。 例えば3DゴリゴリのSceneでは利用を控えるとか、ほぼUIだけで構成されているのであれば必要に応じて使うなどです。 スマートフォンの性能も年々上がっているので、多少LayoutGroup使ってもそれほど全体のパフォーマンスには影響が出ないというのがこれまでの経験上あります。