はじめに
私の中で果てしなく分かりづらいと評判のUnityのRectTransform。
ようやく完全に(自称)理解できたので自分の考えの整理も含めて残しておきます。
なお、Scriptからの操作はここでは扱いませんのでご注意ください。
PositionやScale、Rotationは通常のTransformとほぼ同じなので、ここでの説明は割愛します。
ここではRectTransform特有の要素である、PivotとAnchorsに重点を置いて説明します。
本記事の最後に私が理解しづらかった要因と考えた点(理解の妨げ その1,その2)をまとめておきましたので、そちらを先に読んでおいたほうが理解しやすいかもしれません。
ベースとするサンプル
こちらの状態をサンプルとして説明します。
640✕360の親のGameObjectがあり、その下に100✕100のImageを置いています。
今、Imageは画面中央にあり、PosXYは共に0となっていて、Width、Heightは100となっています。
これを基準として、Pivot、Anchorsを調整したとき、これがどのように変化するのかを見ていきます。
また、あらかじめ下記設定をしておくとCanvas上のオブジェクトが見やすくなると思います。
Pivot
まずは比較的わかりやすいPivotから説明します。
Pivotは自分のどの位置を基準点にいるかを0から1の値に正規化して(丸めて)示しています。
先程の画像ではPivotは(X,Y)=(0.5,0.5)と設定されています。これはImageの中心が基準点として扱われることを示しています。
基準点は左下が(0,0)で右上が(1,1)となっているため、左上、右上、右下、左下を基準点としたいときには以下のようにします。
■左上(0,1)
■右上(1,1)
■右下(1,0)
■左下(0,0)
例として元々中心が基準点となっていたPivot(0.5,0.5)を左上が基準点になるように(0,1)に変更してみます。
Imageの見た目は変わらないですが、PosX,Yの値が変わったことがわかります。これはImageの基準点が左上になり、且つ、元の位置と変わらないようにするためにUnityがPosXを-50、Yを50に補正したということです。
今、基準点が左上になっているため、PosX、PosYを0にしてやると、Imageの左上が画面の中央になるようにImageが移動することになります。
やってみたのが以下の画像です。
同様にPivotを変化させたうえで、PosXYを0にすると、Imageの基準点になっている位置が画面中央に来るようになります。
例えば、Pivotを(1,1)にして、PosXYを0にするとImageの右上が画面中央に来るようになります。
Anchors その1
次にAnchorsの説明です。
Pivotは子の基準点を示していました。
最初に提示した下記のサンプルではImageのPosX、Yが0のときに画面中央に来るようになっています。
このように、PosX,Yを0にしたときに、子(自分)の基準点が来る位置を示しているのがAnchorsです。
Anchorsは親のサイズ(Width、Height)を基準にを0から1の範囲に正規化して(丸めて)示しています。
AnchorsはSceneビュー上で表示されていて、下記のリボンのようなマークがAnchorsを示しています。
AnchorsはXYのMinとMaxをそれぞれ指定することができ、今はXYのMin、Maxともに0.5となっているため、親の中心=画面中央が親の基準点となっています。
例えば子の位置指定を左上基準で行いたい場合にはAnchorsのX、Yを(0,1)にしてやります。
※このとき必ずXのMin,Maxともに0、YのMin、Maxともに1となるようにしてください。
すると、このように親の基準位置が左上に移動し、それに合わせて子要素であるImageのPosXYも画面中央の表示のままとなるよう自動的に補正されています。
このように親のどの位置を基準として子の位置を指定するかを示したものがAnchorsとなります。
この状態からPosX、Yを0にするとImageの中心位置が、Anchorsのマークの位置(左上)に移動することを確認できると思います。
Anchors その2
さて、Anchorsは親の基準位置を決めるものという説明をしましたが、これはMin、Maxの値に同じ値を指定した場合の挙動です。
AnchorsのMin、Maxに異なる値を指定すると、一致している時とは全く挙動が異なるので、注意が必要です。
AnchorsのMinとMaxに異なる値を指定すると、その範囲に自分をストレッチ(引き伸ばす)するという挙動になります。
例としてXのMinを0.3、Maxを0.7にしたものを見てみましょう。
このようにPosXとWidthだった項目がLeftとRightに変わっています。
Anchorsを変更したときUnityはPivotと同様に、見た目が変わらないように補正を入れます。
そして、これはLeftとRightが基準となる位置からどれだけ離れているかを示しています。
なので、Left、Rightそれぞれに0を入れてやると、基準とした位置(Xの0.3~0.7)までImageがストレッチされるようになります。
このようにMinとMaxに異なる値をいれると、その範囲に引き伸ばすという挙動となるため、
XYのMin、Maxをともに(0,1)として、Left、Right、Top、Bottomをすべて0にすると、
親要素の範囲全体にImageを引き伸ばすという挙動になります。
Anchors プリセット
Anchorsを理解した上で、プリセットを開くとその意味がわかる。
ここを操作するとPosX,Yの値などが色々変わるのだが、実際に操作しているのはAnchorsの値で、
それに伴ってPositionに変化が入っている。
(プリセットの表示に隠れてAnchorsが見えないので混乱しやすい)
以降は(これのせいで分かりづらかったという)私の愚痴
理解の妨げ その1 Anchorsの値によって(しれっと)数値の意味が変わる
AnchorsではXとYそれぞれでMinとMaxが設定できるが、この値によって数値の意味が(しれっと)変わる。
これが(個人的に)めちゃくちゃ分かりづらかった。
具体的に言うと
MinとMaxの値が完全に一致しているとき:Anchorは子要素位置の親の基準点を示す。
MinとMaxに異なる値を入れたとき:Anchorはストレッチの基準となる範囲を示す。
これが本当にしれっと変わる。ゆるすまじ。
Anchor XのMinとMaxが一致しているときはPosXとWidth
Anchor XのMinとMaxが不一致のときはLeftとRight
上記のようにしれっと変わる。まじでこれは初見殺し。完全に理解した今でも許しがたい所業。
理解の妨げ その2 PivotやAnchorsを変更したときに見た目が変わらずPosition値が変わる
PosXYZやScale、Width、Heightは値を変更するとそれに応じて見た目も変わる。
だから、値を変更することによって何が起こっているのかがわかりやすく、値が何を意味しているのかも理解しやすい。
が、PivotとAnchorsは値を変更しても見た目は変わらない。
見た目を維持するようにUnityがPosition(とWidth、Height)側の値を親切心で補正する。
そして、前述(理解の妨げ その1)の通り、PivotとAnchorsの変更に応じてPosやWidth、Heightの値がしれっと変わっている。(なんなら項目自体が変わる)
見た目ではなく数値が変わるため、所見だと何が起こっているのか全く理解不能に陥る(陥った)。
まとめ
Pivotは自分自身のオブジェクトの基準位置を0から1に正規化して示すもの。
Anchors(Min、Maxが同じ時)は親の基準位置を示すもの。
Anchors(Min、Maxが異なる時)は親の基準位置をベースにストレッチ範囲を示すもの。
という形になります。
なるべくわかりやすいように書いたつもりですが、自分がかなり理解に苦労したので、この記事がどなたかの理解の助けになれば幸いです。
コメント