Unity UGUI中RectTransfrom中錨點(Anchor)、中心(Pivot)、Rect及座標分析

1 RectTransform.pivot

Pivot:物體的軸心,這裏千萬不要把這個參數理解爲了物體中心,這個跟物體的中心是有區別的,當在設置錨點的位置爲居中時,是根據父物體中心來計算,而不是這裏的Povit計算的,在後面會詳細說明。 
具體這個值的調整方式、方法,太簡單了,這裏就不記錄了。

2 RectTransform.anchoredPosition

anchoredPosition :錨點位置,從錨點中心(這裏不是錨點的中心,後面關於這個地方有更正說明)到本物體的軸心(Pivot)的向量值 
Inspector配置如圖: 


顯示結果如圖:

關於錨點位置,首先是左上角custom的那個小窗口,可以設置默認的錨點位置值,比如居中,居左,stretch(平鋪)等方式。 


這裏選擇的是將錨點設置爲左下角。那麼第一個疑問點出現了,這裏的左下角是指的相對於誰的左下角? 
通過圖中的錨點(左下角那四個白色透明的三角形)可以看出,這裏選擇的左下角、居中、居左甚至stretch,都是以其父窗口爲參考。也就是說,如果設置錨點居中,則是將錨點的位置設置爲其父窗口的幾何中心而不是父窗口的Pivot。 
關於這一點有興趣的同學可以自己做實驗試試,改變父窗口的Pivot,子窗口的錨點位置及值是不會改變的。 
同理,如果將錨點設置爲左下角,則錨點的位置將位於父窗口的左下角,而不是本窗口的左下角。

搞清楚了錨點位置的選取參考物後再來分析錨點的值:RectTransform.anchoredPosition的具體含義。之前一直對這個沒有搞清楚,翻看了幾篇大神的帖子後算是徹底搞明白了。回到第二幅圖,圖中錨點(左下角的四個三角形)的值爲(200,200),也就是RectTransform.anchoredPosition的值爲(200,200)。這個值等於錨點到本控件的Pivot的向量值,如第二幅圖中的紅色箭頭所示。

如果我們固定錨點位置,改變Pivot的值,那麼RectTransform.anchoredPosition的值會跟隨變化,如圖: 
 
將Piovt的x改爲0,則錨點的值變爲了50

這裏,感覺好像完全搞清楚了錨點位置,以及RectTransform.anchoredPosition的意義了,其實不是!!!這裏還有一個問題,錨點不僅可以是這樣的: 
 
還可以是這樣的: 
 
錨點其實不是一個點,其實是四個釘子!!! 
當我們使用Stretch的方式時,錨點就不再是四個聚在一起的點了,而是分開的,那麼這裏RectTransform.anchoredPosition的值怎麼算? 
根據實驗測試結果,這個時候的RectTransform.anchoredPosition值應該是四個釘子的幾何中心到本控件的Pivot的矢量值,如下圖所示。 


其實從程序開發的角度來看,符合美學的軟件應該是用一個抽象的模型,計算出正確的結果,那麼這裏,作爲符合美學的軟件必然不會講這個問題區分成if(集中型錨點)xxx……,if(分散型錨點)xxx……這種醜陋的實現方式。所以,這裏我覺得可以大膽的推測Unity在這裏的實現,始終是取四個釘子的幾何中心點,然後從該點向Povit點做向量,將向量的值記錄在RectTransform.anchoredPosition裏。

所以這裏再回頭看本章第一句話的描述:“anchoredPosition :錨點位置,從錨點中心到本物體的軸心(Pivot)的向量值”其實這裏的錨點中心,就是指的四個釘子的幾何中心點。

之前這裏搞錯了,在此更正 : 

這裏主要更正錨點位置的計算方式,錨點位置的計算方式應該跟物體的軸心計算方式相同,只是軸心的參考物爲本控件的Rect,而錨點的參考物爲錨點的四個釘子組成的Rect。 
anchoredPosition的值不是四個釘子的幾何中心到本控件的Pivot的矢量值,而是四個釘子形成的矩形上的某一個點到控件的Pivot的矢量值。 


錨點的這個點的確定也是依賴Pivot值的,即:錨點的最終位置爲由四個釘子組成的矩形的Pivot位置,假設當前紅色矩形的Pivot爲(0.2, 0.2),則anchoredPosition值如下圖所示: 

 

anchoredPosition的值最終爲(80,-10)。 

3 RectTransform.offsetMax/offsetMin

RectTransform.offsetMax : (x, y) 
RectTransform.offsetMin : (x, y) 
這兩個值表示四個釘子(錨點)(注意這裏的描述,四個釘子!!一定要把錨點理解爲四個點,而不是一個點),到本控件上對應頂點的矢量的最大值與最小值。

怎麼理解這句話? 
1、錨點對應的控件頂點 
這個地方是本人的猜測或者說是假設,但是也是符合實際情況的,同時也是我覺得這裏的代碼如果要優雅的實現,這樣的模型是一個比較優雅的實現方式。 
所謂對應,即:錨點其實是四個釘子,分爲左上,左下,右下及右上四個,每個空間在UI模型中都是一個矩形,也有左上,左下,右下及右上四個頂點,那麼錨點的每個釘子可以關聯一個點,即左上————左上;左下————左下;右下————右下;右上————右上。這樣進行綁定。 
2、offsetMax、offsetMin的值哪裏來 
理解了1中的錨點與控件頂點綁定關係後,那麼offsetMax、offsetMin的求解規則就很簡單了。 
首先計算錨點的每個釘子到其對應的頂點矢量值,分別記作v0,v1,v2,v3,如圖所示: 


然後比較四個向量的x值,將x的最大值賦給offsetMax.x,將x的最小值賦給offsetMin.x;y的值同理。 
這麼說,應該就很好理解爲什麼stretch模式和點模式的時候,offsetMax、offsetMin的值風格完全不一樣的問題了,看上去好像不同,其實本質是一個模型。

4 RectTransform.sizeDelta

這個值沒什麼說的了: 
sizeDelta.x = offsetMax.x - offsetMin.x; 
sizeDelta.y = offsetMax.y - offsetMin.y;

這裏就是要提醒一點,當錨點爲點模式時(非stretch),sizeDelta的值等於RectTransform.rect.size的值,而當錨點爲stretch類型時,sizeDelta的值不等於*RectTransform.rect.size的值,所以我看到有人的博客上說可以通過改變sizeDelta的值來調整控件的size,這個我覺得只說對了一半,另一半是:當控件的佈局爲stretch類型時sizeDelta與控件的size負相關,在調整的時候要謹慎謹慎謹慎*!!!至於原因,就上本文上述的前幾章的吧啦吧啦。

5 RectTransform.rect

RectTransform.rect的各值如圖所示。 


其中RectTransform.rect.position的值爲本控件的pivot點到左下角點的向量的值,size的值的求法如下圖所示:

圖中最下面的公式就是size值的求法,其中p’op’1這條向量的值對應的就是size的值。這裏給出的是一個通用解法,我猜測unity的代碼實現應該是用的類似的思路,這樣一個公式就可以適應所有的情況。但是如果是人來算的話其實不用這麼麻煩,看一眼就知道size有多大了……

6 RectTransform.anchorMax/anchorMin

錨點是四個釘子,再次回到這個話題。 
anchorMax : (x, y) 
anchorMin : (x, y) 
anchorMin.x表示錨點在x軸的起始點位置,anchorMax.x表示錨點在x軸的終點位置,取值0~1,表示百分比值,該值乘以父窗口的width值就是實際錨點相對於父窗口x軸的位置。y軸與x軸同理。 


這個值確定了錨點相對於父窗口的位置,是真正決定錨點位置的值

7 控件位置是如何確計算的

作爲人而言,最直觀的座標位置就是RectTransform.rect.position值,也就是控件的左下角點的位置,再加上控件的長、寬值來確定控件最終的位置,那麼如何計算這些值,最後在這裏總結一下:

父物體rect–>確定本控件錨點位置(由RectTransform.anchorMax/anchorMin決定)–>確定pivot位置(由RectTransform.anchoredPosition決定)–>得到本控件Rect.position的值(由Rect.size及pivot的值計算得出)
--------------------- 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章