【Unity】ContentSizeFitterについて調べてみた

UnityでUIを作っていくときに便利なコンポーネントがあります。 ContentSizeFitterと呼ばれる自動でUIのレイアウトを行ってくれます。 複雑なUIを組みたいときに、このContentSizeFitterを使えば専用のスクリプトを書くことなく実装ができる場合があります。

 

ContentSizeFitter

ContentSizeFitterはUIの横幅と縦の高さをコンテンツのサイズを自動調整してくれます。

使い方

Inspector上から「ContentSizeFitter」と検索をすればコンポーネントが表示されますので、これを必要なGameObject上に追加します。

f:id:albatrus:20210306143754p:plain:w300
InspectorからContentSizeFitterを検索する

設定項目があるのでこちらで必要なタイプを選択します。

f:id:albatrus:20210306144110p:plain
ContentSizeFitterのInspector上の見た目

設定項目

設定項目は2つ

  • Horizontal Fit : 横幅の設定
  • Vertical Fit : 縦の高さの設定

設定できるタイプは3つあります。

  • Unconstrained
  • Min Size
  • Preferred Size

Unconstrainedは特に何も行わないので説明は省きます。

Content Size Fitter - Unity マニュアル

Min Size

Min Sizeは該当のUIの最小サイズに拡縮させます。 普通UIを実装する場合、widthやHeightを触ることはあると思うのですが、最小サイズについては設定するところはないかと思います。 Min Sizeは「Layout Element」というコンポーネントを使って設定をします。

Layout Element - Unity マニュアル

もし「Layout Element」でMin Sizeを設定しなかった場合、ContentSizeFitterを設定するとサイズが0になってしまいますので注意をしてください。

f:id:albatrus:20210306151604p:plain:w300
Horizontal FitでMinSizeを設定した時(Layout ElementでMin Width設定済み)

Preferred Size

Preferred Sizeは該当のUIの推奨幅に拡縮させます。 Preferred SizeもLayout Element」というコンポーネントを使って設定できますが、Textの幅がPreferred Sizeに該当します。

f:id:albatrus:20210306152535p:plain:w200
HorizontalとVerticalをPreferred Sizeした場合

f:id:albatrus:20210306152711p:plain:w200
文字数に応じで幅が自動的に調整されます

仕組み

このContentSizeFitterはどうやってUIを自動生成しているのでしょうか? 簡単ですが中身を少し調べてみました。

サイズの計算

サイズの計算はLayoutUtilityクラスのGetLayoutPropertyメソッドで行われています。 該当のGameObjectにILayoutElementを持つコンポーネントがないかを探し、ある場合にはMin SizeやPreferred Sizeを調べてサイズを計算します。 もしILayoutElementがなければサイズは0になります。

計算タイミング

ContentSizeFitterクラスにあるLayoutRebuilder.MarkLayoutForRebuild()を呼ばれた時にサイズの計算が行われます。

LayoutRebuilder.MarkLayoutForRebuild (transform as RectTransform);

マニュアルによるとサイズの計算タイミングはフレームの最後に行われるみたいです。

再構築は直ちに起こるわけではなく、レンダリングの起こる直前、現在のフレームの最後に発生します。直ちに発生しない理由は、これにより、レイアウトが同じフレームで何度も再構築される可能性があり、パフォーマンスへ悪影響を与えるためです。

このメソッドは次のタイミングで呼び出されます。

  • OnEnable
  • OnValidate
  • Horizontal Fit もしくは Verticel Fitをセットした時
  • OnRectTransformDimensionsChange (RectTransformが変更されたとき)

docs.unity3d.com

最後に

これまであまり調べずにContetnSizeFitterを使っていたので、今回ブログに書くにあたり色々勉強になることが多かったです。 ContentSizeFitterに関しては、LayoutGroupと呼ばれる別のコンポーネントと組み合わせることで複雑なUIを実装できますので、そのあたりは後日またまとめようかと思っています。