RectTransform详解
示意图
1) anchor区域
2) 节点坐标: 是相对anchor区域的
Vector2 offsetMin;
节点左下角的坐标(以anchor区域左下角为原点)
Vector2 offsetMax;
节点右上角的坐标(以anchor区域右上角为原点)
上面的图中:
offsetMin=(left, bottom)=(40, 30)
offsetMax=(-right, -top)=(-10, -30)
3) Vector2 sizeDelta;
节点自身大小与anchor区域大小的差值,计算公式: sizeDelta=offsetMax-offsetMin=rectTransform.rect.size - anchorAreaSize
上面的图中:
sizeDelta=(-10, -30) - (40, 30)=(-50, -60)
4) Vector2 anchoredPosition;
计算公式: anchoredPosition = offsetMin + sizeDelta * pivot
上面的图中: anchoredPosition = (40, 30) + (-50, -60) * (0.4, 0.5) = (20, 0)
根据sizeDelta=offsetMax-offsetMin, 还可以推导出: anchoredPosition = offsetMin + (offsetMax-offsetMin)*pivot = offsetMin*(1-pivot) + offsetMax*pivot
5) Rect rect;
节点与parent的边距计算
1) 不考虑节点自身缩放时
left边距 = anchorMin.x * parent宽度 + offsetMin.x = 0.2 * 300 + 40 = 100
bottom边距 = anchorMin.y * parent高度 + offsetMin.y = 0.1 * 200 + 30 = 50
right边距 = (1 - anchorMax.x) * parent宽度 - offsetMax.x = (1 - 0.7) * 300 + 10 = 100
top边距 = (1 - anchorMax.y) * parent高度 - offsetMax.y = (1 - 0.9) * 200 + 30 = 50
2) 考虑节点自身缩放
根据边距设置节点坐标
1) 根据上面的推导,我们自己实现的
public static void SetLocalPosByLeftTopMargin(RectTransform rtf, float leftMargin, float topMargin, Rect parentRect) { var rect = rtf.rect; var pivot = rtf.pivot; var localScale = rtf.localScale; var offsetMin = rtf.offsetMin; var offsetMax = rtf.offsetMax; var anchorMin = rtf.anchorMin; var anchorMax = rtf.anchorMax; offsetMin.x = leftMargin - anchorMin.x * parentRect.width - rect.width * pivot.x * (1 - localScale.x); offsetMax.x = leftMargin + rect.width - anchorMax.x * parentRect.width; offsetMin.y = parentRect.height - topMargin - rect.height - anchorMin.y * parentRect.height; offsetMax.y = (1 - anchorMax.y) * parentRect.height + rect.height * (1 - pivot.y) * (1 - localScale.y) - topMargin; rtf.offsetMin = offsetMin; rtf.offsetMax = offsetMax; }
2) RectTransform上其实也有类似的函数
SetInsetAndSizeFromParentEdge
void Start() { var rtf = GetComponent<RectTransform>(); var rect = rtf.rect; rtf.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, 100, rect.width); rtf.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Top, 50, rect.height); }
注意:这个函数执行后,会修改anchorMin和anchorMax的值
参考
Unity3D RectTransform使用详解:布局、属性、方法 - 知乎 (zhihu.com)