SOU·COLLE
イラストレーション/デザイン/3DCG/ゲーム開発のお話

Unity UIのAuto Layoutを使いこなして楽々レイアウト

UnityでUIを組む時はAuto Layout Groupを積極的に使った方が断然良い。Rect Transformだけでは気を配る項目が多く,要素の追加や変更も手数が多くなる。

Auto Layout Groupは少ない変更点で大きな変更を加えることができるので,少しの追加や変更はお手の物。完全とまではいかないが,ある程度フレキシブル・レイアウト対応できるのも強み。

実際にヘッダー,ボディ,フッターを使ったよくあるレイアウトを組みながらポイントを書いていく。

これから組むレイアウトのイメージ

画面全体のレイアウト

子要素には必ずLayout Elementコンポーネント

Auto Layout Groupのひとつ,Vertical Layoutを使って各エリアを縦に並べる。以下の例ではVertical Layoutを持つ親が並びを管理し,子要素が自身のサイズを決定している。

Vertical Layout Groupを使ってヘッダー,ボディ,フッターを縦に並べる様子

Auto Layout Groupを使う時の一番のポイントは,親のグループで子要素のサイズをコントロールしきらないこと。なので基本的にChild Force Expandのチェックはオフにするのがオススメ。

一方,Child Force Controllのチェックはオンにするのがオススメ。Child Force ControllはRect Transformではなく,Auto Layoutのルールに子要素を従わせるための設定。

最後に子要素には必ずLayout Elementをアタッチする。Layout ElementをアタッチするとAuto Layoutのルールに従いつつ,子がある程度レイアウトの裁量を持てる。

固定・可変サイズを使い分け,組み合わせる

各エリアのサイズを決めていく。幅は各要素親いっぱいにまで広げる。ヘッダーとフッターの高さは固定サイズを指定し,ボディの高さだけ確保できる分だけ広がるように設定している。

Layout Elementを使ってCanvas全体を要素で埋める様子

サイズを固定したい場合は,まず最低値であるMin Width / Heightを設定するのがオススメ。親のサイズに関係なく指定したサイズが維持される。

全体を埋めたい時にはFlexible Width / Heightを使う。他にMinやPreferredが設定された子要素がある場合,それらを差し引いたスペース全てを埋める。

ヘッダー

空白部分も要素と考えてレイアウトする

ヘッダーの中身をレイアウトする。Auto Layout Groupの並びには両端揃のような指定方法はない。なので空白部分も要素と見てレイアウトする。

空のゲームオブジェクトで空白をつくる様子

やっていることはさっきの画面全体のレイアウトと全く一緒。Horizontal Layoutをアタッチ。空のゲームオブジェクトを空白に見立て,Flexible Widthで拡張するよう設定している。

大昔のテーブルレイアウトのようで個人的には気がひけるが,これは文書構造ではないので気にしたら負けだと思ってる🙄

内容量に応じて可変も可能

Auto Layout Groupなら子要素の内容量に応じて可変させることも可能。左はアイテムの数に応じて,右はテキスト量に応じて親のサイズが変化。

文字数によって拡張するようヘッダーの要素を組んでいる様子

Auto Layout Groupでコントロールしている場合,内容量に応じて親のサイズを勝手に可変してくれる。さらに,TextコンポーネントはLayout Elementを付けずともPreferred Width / Heightに相当する値が設定されている。

親にビジュアルは持たせない

Auto Layout Groupの親は結構制約がキツくなっているので,親にビジュアルになるコンポーネントはなるべくアタッチしない方が良い。Layout Ignoreを使って背景を子要素として分離する。

Layout Ignoreを使ってAuto Layoutから外れた例外レイアウトを行う様子

Layout ElementのLayout Ignoreは,Auto Layout Groupのルールに従わなくさせるための設定。
レイアウトは通常通りRect Transformで行う。Auto Layout Groupのサイズ変化を擬似的に参照するような状態になる。マイナスの数値を設定すれば親の欄外に出るような例外的なレイアウトも自由にできる。

ゲームではよくある大きな装飾のUIでは,それの大きさのせいでレイアウトの数値にひどく影響する。ビジュアルとレイアウトの数値を分離できれば,細かい自由度を保ったままレイアウトしやすくなるし,メンテナンスコストも下がる。

フッター

Child Force Expandの使い所は等間隔レイアウト

Auto Layout Groupには両端揃えと同じく等間隔揃えという設定方法も無い。
Child Force Expandを使えば一応擬似的に設定することはできる。

フッターの要素を等間隔にレイアウトする様子

Child Force Expandは子要素のサイズに関係なくスペースが拡張され確保される。この時に子要素のサイズを保つためには,Child Controls Sizeをオフにし,子要素のサイズはRect Transformのサイズが維持される,

まとめ

レイアウトがスクリーンサイズに合わせてフレキシブルに変化する様子
Rect Transformでもこのようなレイアウトは可能だが,追加や変更のたびに多くの数値を調整することになる。Auto Layoutなら追加は要素を複製するのみ,レイアウトの調整は親のPaddingやSpacingなどを変更して一括編集が可能

使い始めた頃は要素を縦や横に並べる時以外は使わないかなー?と思っていたけども。今ではこれが無いと困るくらいレイアウトの作業コストを激減させてくれる,UI制作におけるかなり主要なコンポーネントだと思ってる。

Unity UIは巷ではあまり評判は良くないらしいっぽい?けど,Auto LayoutはCSSのような万能性はないものの,ポイントを押さえれば柔軟性の高いレイアウトを実現できるいい機能なので好き😊