sizeDeltaはサイズと覚えたけど、期待通りの結果にならない事があるの…
RectTransformのsizeDeltaは正確にはサイズではないわ。サイズとアンカーサイズとの差分を意味するものなの。
Unity UI(uGUI)などで使われるRectTransform.sizeDeltaプロパティは、そのRectTransform自体の矩形サイズではなく、矩形サイズからアンカーサイズを引いたものです。
sizeDeltaはサイズと説明される場合がありますが、これは不正確な表現です。sizeDeltaが矩形サイズとして振る舞うのは、アンカーサイズが0の場合に限ります。
試しにUIのアンカーをstretch(アンカーサイズが0でない)に設定すると、RectTransform.sizeDeltaプロパティが実サイズとは異なる結果になる事が確認できます。
本記事では、このRectTransform.sizeDeltaプロパティの仕様を正しく理解するところを目指して解説します。サイズを取得したり指定する方法にも触れます。
本記事では、4点で定義されるアンカーの縦横のサイズを便宜上「アンカーサイズ」と表記することとします。
- Unity 2023.2.0f1
- Unity UI 2.0.0
目次 非表示
前提条件
次のように、親のUI要素の下に子要素が配置されているものとします。
この子要素のアンカーとサイズとsizeDeltaの関係に着目して解説します。
アンカーについて
RectTransform.sizeDeltaプロパティは矩形サイズとアンカーに密接に関わるため、まずアンカーについて軽く触れておきます。
アンカーは、あるUI要素を親要素に対してどのように位置付けるかを決めるためのもので、親要素の左下を(0, 0)、右上を(1, 1)に正規化した4点の位置で構成されます。
データ上では、アンカー領域の左下(Min Anchor)、右上(Max Anchor)の2点で表現されます。
アンカー領域を親要素を基準に正規化した位置で表現することにより、親要素に対して相対的な割合でサイズが変化させることが可能です。
アンカーの4点を同じ位置にまとめると、次のようにサイズを固定しながら左揃えや中央揃えなどが行えるようになります。
アンカーのプリセット
UI要素を配置する場合は、RectTransformのインスペクターからはアンカーのプリセットを選択できます。
プリセットはそれぞれ次のような値になっています。
RectTransform.sizeDeltaの仕様
要素のサイズからアンカーのサイズを引いたものです。Vector2型であり、xy軸方向それぞれの結果がx,yに格納されたものとなります。
参考:RectTransform-sizeDelta – Unity スクリプトリファレンス
sizeDeltaは要素のサイズとアンカーを用いると次式のようになります。
sizeDelta = 要素のサイズ – 要素のアンカーサイズ
要素のアンカーサイズ = (anchorMax – anchorMin) × 親要素のサイズ
sizeDeltaは要素のサイズからアンカー領域のサイズを引いた値です。単位はピクセルです。
アンカー領域のサイズはアンカーの右上座標(anchorMax)から左下座標(anchorMin)を引いて求められますが、これは親サイズを1(単位)とした値です。
そのため、アンカーサイズの単位をピクセルに変換するために、親要素のサイズを掛ける必要があります。
上記の関係式より、RectTransformの矩形サイズはアンカーサイズにsizeDeltaを足した結果となります。
要素のサイズ = 要素のアンカーサイズ + sizeDelta
アンカー設定による挙動の比較
代表的なアンカー設定によるサイズの振舞いについて見ていきます。
ストレッチでない場合
次のプリセットが指定されている場所、アンカーサイズが0になります。
この場合、minAnchorとmaxAnchorは等しくなるため、sizeDeltaは要素のサイズと一致します。
sizeDelta = 要素のサイズ
UIのデフォルトのアンカー設定はminAnchor、maxAnchor共に(0.5, 0,5)であり、上記の挙動をとります。
sizeDelta = 要素サイズという関係は、このようにminAnchorとmaxAnchorが一致している場合に限る点に注意が必要です。
ストレッチされた場合
次のプリセットが設定されている場合、親要素のサイズが変わると子要素のサイズもそれに追従して変わります。
ストレッチされている軸のアンカーはminAnchor = 0、maxAnchor = 1となり、アンカーサイズ(ピクセル)は親要素のサイズ(ピクセル)と一致します。
この時のsizeDeltaの関係式は以下のようになります。
sizeDelta = 要素のサイズ – 親要素のサイズ
実際に親要素のサイズを変えた様子です。
子要素の4隅からの相対位置が維持されています。
RectTransformの矩形サイズの取得
特定要素の矩形サイズはRectTransform.rect.sizeプロパティから取得できます。
要素の矩形領域(位置とサイズ)の情報はRectTransform.rectプロパティからRect構造体として得られ、Rect.sizeプロパティからxy軸方向のサイズを取得出来ます。
参考:RectTransform-rect – Unity スクリプトリファレンス
参考:Rect-size – Unity スクリプトリファレンス
RectTransform.sizeDeltaプロパティを用いても親要素のサイズやアンカーから計算できますが、rectプロパティを用いた方が手軽です。
RectTransformの矩形サイズの指定
逆に特定要素のサイズを指定したい場合、RectTransform.SetSizeWithCurrentAnchorsメソッドを使うと簡単です。
第1引数にはサイズ指定する軸、第2引数には変更後のサイズ(ピクセル)を指定します。
このメソッドは、内部的にアンカーの設定値に基づいて計算し、それをsizeDeltaプロパティに反映しています。
参考:RectTransform-SetSizeWithCurrentAnchors – Unity スクリプトリファレンス
もしRectTransform.sizeDeltaプロパティに直接指定したい場合は、指定したいサイズからアンカー領域のサイズを引いた結果を反映すれば良いです。
サイズ指定のより詳しい内容は、以下記事で解説しています。
さいごに
RectTransform.sizeDeltaプロパティは、実際のサイズからアンカーサイズを引いたVector2型の値です。
sizeDeltaがサイズと等しくなるのはアンカーサイズが0の場合に限ります。UIのデフォルト設定ではアンカーサイズが0となっているので、サイズと誤解しやすい点に注意する必要があります。
サイズ取得したい場合はRectTransform.rect.sizeプロパティをリードすれば良いです。サイズ指定はRectTransform.SetSizeWithCurrentAnchorsメソッドを使うかサイズからアンカーサイズを引いた計算結果をsizeDeltaに指定するのが正しい方法です。