UGUI 有它的實用性, 但是也存在理解上的困難, 由於它在面板上的顯示內容根據佈局而變更, 若是不深刻理解它的設計原理, 估計每次要進行程序上的修改都須要進行一次換算和測試過程.函數
1. 設置某UI的尺寸.佈局
它並無提供一個直接設置尺寸的API, 由於想要改變UI大小根據需求有不一樣的方法, 不一樣的方法會形成不一樣的結果. 好比能夠修改 anchorMin / anchorMax , 或是修改 offsetMax / offsetMin, 又或是修改 sizeDelta, 有多種可能的方案, 但是某些修改是會對子節點的UI形成很大影響的, 咱們須要找到一個比較穩定的修改方法. Anchors相關的變量會形成子節點變化, 不該該修改它, 而offsetMax / offsetMin 跟 sizeDelta 其實能夠當作是相同的表達, 只不過表現形式不同. 那麼簡化的函數就是 :測試
public static void SetSize(RectTransform rect, Vector2 targetSize) { var originSize = rect.rect.size - rect.sizeDelta; var makeSizeDelta = targetSize - originSize; rect.sizeDelta = makeSizeDelta; }
只須要幾回減法便可設置很是方便, 它的邏輯就是依據sizeDelta的性質來計算的 : sizeDelta 表明的是Rect如今的大小與原始Rect的大小的差, 公式應該是:spa
RectSize(原始大小) + sizeDelta = RectSize(當前大小)設計
那麼咱們要設置一個目標大小, 只須要先計算出原始大小, 而後用 RectSize(目標大小) - RectSize(原始大小) = sizeDelta 便可得出要獲得目標大小時的sizeDelta, 直接設置給rect的sizeDelta 便可, 這樣計算又簡單, 又不須要改動錨點等, 保證修改過程的穩定性... 順帶一提 sizeDelta 絕對不是UI的大小, 是UI如今的大小跟UI的原始大小的差, 只有在錨點 anchorMin , anchorMax 相等時, UI 的原始大小爲0, sizeDelta纔跟UI大小相等.code
2. 用UI的某個 Pivot 去跟父節點UI的某個 Pivot去對齊orm
看起來很亂來的需求, 看圖理解:blog
子UI紅色的 Pivot爲 (0, 1), 而咱們要把它的 (0.5, 1.0) 與父UI 的(0, 1) 的位置對齊, 也就是紅色UI的中間頂部跟白色UI的左上角對齊, 修改方式也有不少種, 經過修改 anchoredPosition 應該是最穩健的方法了, 由於它不會修改任何形成子節點UI變化的變量. 簡化的計算方法以下: ip
public static Vector2 SyncPovitToParent(RectTransform rect, Vector2 pivot, Vector2 parentPivot) { var parent = rect.parent as RectTransform; var offsetInParent = MathTools.Multiple(MathTools.Multiple(rect.pivot, rect.rect.size) - MathTools.Multiple(pivot, rect.rect.size), rect.localScale); var parentOffset = MathTools.Multiple(parentPivot, parent.rect.size) - MathTools.Multiple(rect.pivot, parent.rect.size); return MathTools.VectorAdd(parentOffset, offsetInParent); }
MathTools 只是作了Vector對應變量的乘法加法等功能.get
這個方法的好處在於你不須要修改 Pivot 變量, 只經過移動UI的方式來進行對齊, 沒有用到距離, 除法等...
rect.anchoredPosition = SyncPovitToParent(rect, new Vector2(0.5f, 1), new Vector2(0, 1));
rect 就是要對齊的紅色UI, new Vector2(0.5f, 1) 是選定紅色UI的Pivot位置( rect的原始Pivot爲(0, 1), 計算先後不變 ), new Vector2(0, 1) 是選定父節點UI的Pivot位置, 計算後rect相應的位置與父節點相應位置重合. 邏輯以下 :
1. 計算在當前Pivot下怎樣移動rect才能使當前 Pivot 與父節點相應 Pivot 點重合
var parentOffset = MathTools.Multiple(parentPivot, parent.rect.size) - MathTools.Multiple(rect.pivot, parent.rect.size);
直接用 parent.rect.size 做爲座標系, 乘上 parentPivot, rect.pivot 做爲向量, 相減得出 rect 要移動的向量 parentOffset.
2. 計算在當前Pivot下, 怎樣移動rect 才能讓當前Pivot 與選定紅色UI的 Pivot 位置重合
var offsetInParent = MathTools.Multiple(MathTools.Multiple(rect.pivot, rect.rect.size) - MathTools.Multiple(pivot, rect.rect.size), rect.localScale);
使用當前UI大小做爲座標系, 乘上 rect.pivot, pivot 做爲向量, 相減獲得 rect 座標系中的偏移量, 而後再乘以當前座標的縮放 rect.localScale 就獲得在父UI中 rect 要移動的向量 offsetInParent.
兩個向量相加獲得最後要偏移的量 anchoredPosition ...