UGUI——针对Anchor和Pivot
在RectTransform组件面板中:
Anchor:坐标系是建立在父物体上,属性的Max (控制右边两个三角形的位置) 和Min ==(控制左边两个三角形的位置)==是相对于父物体而言的,以父物体的左下角为(0,0)点,右上角为(1,1)点建立XY平面直角坐标系
Pivot:坐标系是建立在自身上,以自身的左下角为(0,0)点,右上角为(1,1)点建立XY平面直角坐标系
一、Anchor
1、锚点不重合的情况
在面板上会显示Left、Top、Right、Bottom,表示自身左上右下四条边到锚框的左上右下四条边之间的距离
如果将Left、Top、Right、Bottom四个值设置为0的时候,不是将锚框的四条边与自身的四条边重合,而是将自身的四条边与锚框的四条边重合——锚框是不发生改变的
二、属性
1、position与localPosition位置信息
position: 自身pivot相对于画布坐标系的位置(画布坐标系:以左下角为原点)
localPosition: 自身pivot相对于父级坐标系的位置(父级坐标系:以父级元素的pivot为原点)
2、anchoredPosition —— 轴心点相对于锚点的参考位置(能够修改UI元素的位置)
anchoredPosition所表示的是:由锚点为起点,轴心点为终点的一个向量;当我们在对这个属性进行写操作的时候,所修改的UI元素的位置
在读操作的时候:
当锚点和并的情况下,指锚点到轴心点的这个向量
当锚点分开的情况下,指锚框的中心点到轴心点的向量
在写操作的时候:
改变achoredPosition的值,实际上是通过轴心点与锚点的相对位置来改变UI元素的自身位置
坐标系x的最大范围是(-父元素宽度/2,父元素宽度/2),坐标系y的最大范围是(-父元素高度/2,父元素高度/2)
3、anchorMax,anchorMin
这个属性可读可写,反映出了锚点的位置,但是这个属性值是基于标准化的(也就是值是出于0到1的范围内)
anchorMin的x:决定了A、D两个锚点的左右移动,anchorMin的y:决定了D,C两个锚点的上下移动
anchorMax的x:决定了B、C两个锚点的左右移动,anchorMax的y:决定了A、B两个锚点的上下移动
如何通过锚点标准化的值,反推出锚点的实际的位置?
A:(父级元素的宽度 * anchorMin.x, 父级元素的高度 * anchorMax.y)
B:(父级元素的宽度 * anchorMax.x, 父级元素的高度 * anchorMax.y)
C:(父级元素的宽度 * anchorMax.x, 父级元素的高度 * anchorMin.y)
A:(父级元素的宽度 * anchorMin.x, 父级元素的高度 * anchorMin.y)
4、OffsetMin,OffsetMax
通过对这个属性的写操作能够根据锚点,动态的修改UI元素的大小
5、SizeDelta
实际上SizeDelta就是OffsetMax - OffsetMin
当在锚点合并的情况下,根据向量的减法运算(OffsetMax - OffsetMin),得到的结果向量的x分量与UI元素的宽刚好相等,y分量与UI元素的高刚好相等
但是当锚点分开的时候,得到的是一个很奇怪的向量,并不是UI元素的大小,sizeDelta.x值就是锚框的宽度与UI元素的宽度的差值,sizeDelta.y的值就是锚框的的高度与UI元素的高度的差值
6、rect
rect.width和rect.height属性,可以让我们在任何情况下都取得UI元素的大小
rect.x和rect.y表示:以元素pivot为原点UI元素左下角的坐标系
三、方法:
1、SetSizeWithCurrentAnchors(Animations.Axis axis, float size)
通过设置rect中的width和height值来改变UI大小的
2、SetInsetAndSizeFromParentEdge(RectTransform.Edge edge, float inset, float size)
根据父级的某一边设置UI元素的大小
第一个参数就是用于确定基准的边
第二个参数是UI元素的该边界与父物体该边界的距离
第三个元素是设定选定轴上UI元素的大小
private RectTransform rectTransform;
// Use this for initialization
void Start()
{
rectTransform = GetComponent<RectTransform>();
rectTransform.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Right, 200, 400);
//这种情况下我选定父物体的右边界为基准,结果如下图
}
在使用这个方法的时候要注意锚点也会改变,改变的规则为(简单记忆法:设定哪一个轴,哪一个轴上的锚点值为1)
以左边界为基准时,anchorMin 和 anchorMax 的 y 不变 x 变为0.
以右边界为基准时,anchorMin 和 anchorMax 的 y 不变 x 变为1.
以上边界为基准时,anchorMin 和 anchorMax 的 x 不变 y 变为1.
以下边界为基准时,anchorMin 和 anchorMax 的 x 不变 y 变为0.
3、获取元素四个顶点的坐标(左下角,左上角,右上角,右下角):
(1)GetLocalCorners(Vector3[4] corns)
所参考的坐标系是:自身坐标系,坐标系原点是在pivot所在的位置为原点,最大范围是(自身元素的宽度,自身元素的高度)
(2)GetWorldCorners(Vector3[4] corns)
所参考的坐标系是:画布的坐标系,坐标系原点在画布的左下角,最大范围即画布的大小
UGUI小案例
一、设定锚点自动吸附到自身顶点位置
private void AnchorAdsorbentSelfConers()
{
RectTransform parentRectTrans = this.transform.parent.GetComponent<RectTransform>();
RectTransform selfRectTrans = this.GetComponent<RectTransform>();
Vector2 parentSize = new Vector2(parentRectTrans.rect.width, parentRectTrans.rect.height);
Vector2 selfSize = new Vector2(selfRectTrans.rect.width, selfRectTrans.rect.height);
Vector2 selfLocalPosition = selfRectTrans.localPosition;
//偏移值
//在进行设置锚点的时候:由于锚点的(0,0)是在父级元素的左下角,所以在找偏移值得时候需要以父级元素的左边界和下边界为基准
//父元素左边界与子元素左边的之间的距离 / 整个父元素的宽 = 属于0到1之间的小数
float anchorMinX = (parentSize.x / 2 + selfLocalPosition.x - (selfSize.x * selfRectTrans.pivot.x)) / parentSize.x;
float anchorMinY = (parentSize.y / 2 + selfLocalPosition.y - (selfSize.y * selfRectTrans.pivot.y)) / parentSize.y;
float anchorMaxX = (parentSize.x / 2 + selfLocalPosition.x + (selfSize.x * (1 - selfRectTrans.pivot.x))) / parentSize.x;
float anchorMaxY = (parentSize.y / 2 + selfLocalPosition.y + (selfSize.y * (1 - selfRectTrans.pivot.y))) / parentSize.y;
selfRectTrans.anchorMin = new Vector2(anchorMinX, anchorMinY);
selfRectTrans.anchorMax = new Vector2(anchorMaxX, anchorMaxY);
selfRectTrans.offsetMin = Vector2.zero;
selfRectTrans.offsetMax = Vector2.zero;
}