ゲーム化!tomo_manaのブログ

ゲーム化!tomo-manaのブログ

Unityでゲームを作る方法について紹介しています

Unity学習#26-5 ContentSizeFitter を使って LayoutGroup を Element の合計サイズにフィットさせる (Unity 2019.4.4f1)

#26 の実装にあたって、少しLayoutについて調べた内容を備忘のためにまとめます。#26-2 で、テキストやイメージに合わせて枠がスケールするようにしたい場合に、LayoutGroup を2重にすることで実現できることを書きました。ContentSizeFitter でも同様の挙動を実現できます(こちらの方が一般的?)。

<目次>


#26-2と合わせて読むと分かりやすいです。
tomo-mana.hatenablog.com

概要

ContentSizeFitterを使ってテキストやイメージに合わせて枠がスケールするようにするには、以下のようにします。(コーディング不要です)

f:id:tomo_mana:20210227224754p:plain
Hirarchy
f:id:tomo_mana:20210227225613p:plain
Inspector

LayoutGroupを2段構えにする方法に比べて、ContentSizeFitterでの設定方法はとてもシンプルです。以下に動作イメージを示します。

動作イメージ

ContentSizeFitter は、自分が属しているゲームオブジェクトが持っている ILayoutElement の情報で、自分の RectTransform を更新します。以下の図の場合、LayoutGroup が ILayoutElement を実装しています(ContentSizeFitter 自身は ILayoutElement 情報を持ちません)。

f:id:tomo_mana:20210227093623p:plain
ContentSizeFitter

#26-2 で示した LayoutGroup を2段構えにした時の図と比較すると、ContentSizeFitter は、下の図の親 (Parent) LayoutGroup の代わりをしていることが分かります。

f:id:tomo_mana:20210227093222p:plain
LayoutGroup 2段

RectTransformの更新方法の違い

では、ContentSizeFitter を使用するのと、LayoutGroup を2段構えにするのとでは、何が違うのでしょうか。

ContentSizeFitter: RectTransform の anchor, pivot 情報は変更せず、サイズ (Width, Height)だけを更新します。※FitMode.Unconstrainedの場合は何もしません。

LayoutGroup(2段): RectTransform の anchor, pivot 情報 と サイズ (Width, Height)の両方を更新します。
ただし親側のLayoutGroup は anchor, pivot 情報がそのまま使えるので、この点では ContentSizeFitter と違いはありません。・・・違いがあるとしたら、親側のLayoutGroup が持っている Width, Height が、最大値(クリッピング)の役目を果たすくらいかと思います。(今回は調べていませんが、これもMaskを使用することで解消するのではと思います)


繰り返しになりますが、#26-2 と併せて調べたことで、Layout の処理がよく理解できました。

参考

クラス図

f:id:tomo_mana:20210226080213p:plain
クラス図 - ContentSizeFitter

ContentSizeFitter は、Layout関連のインターフェースのうち、ILayoutSelfController のみを実装したコンポーネントです。そのため、ContentSizeFitter 自体は自身のRectTransform の Width や height を計算するための情報を持っていません。ILayoutElementを持ったゲームオブジェクトと一緒に使うことで効果を発揮します。

f:id:tomo_mana:20210228004122p:plain
UI.ContentSizeFitter - Unity スクリプトリファレンス


シーケンス図

ContentSizeFitter は、VerticalLayoutGroup など、ILayoutElement を内包する ILayoutController と併用することで威力を発揮します。あらかじめILayoutElement の機能である CalculateLayoutInputHorizontal() などのインターフェースで子要素の合計サイズ(preferred)を計算し、その後でVerticalLayoutGroup などの ILayoutController よりも先に自分のサイズを更新します。(各インターフェースのコール順は #26-1 に詳しく書いてあります)

f:id:tomo_mana:20210228001833p:plain
シーケンス - ContentSizeFitter

(以上)