UGUI-Pivot与Anchor详解以及localPosition和anchoredPosition的区别

2,646 阅读4分钟

pivot轴心。

旋转、大小和缩放修改都是围绕轴心来进行的,因此轴心会影响旋转、大小和缩放修改的结果,工具栏pivot按钮设置为轴心模式时,可在scene视图中移动矩形变换的轴心。 注意: Pivot是相对于自身的,X控制的是Pivot左右移动,Y控制的是Pivot上下移动,(0,0)为自己左下角,(1,1)为自己的右上角,如图:

5.gif

旋转

  • 当pivot设置为(0.5,0.5)时,物体围绕自身中心点旋转,如图:

6.gif

  • 当pivot设置为(0,0)时,旋转效果如图:

7.gif

大小

我们知道,当我们改变大小时同时按住alt键,可对称进行改变大小。

  • 当pivot设置为(0.5,0.5)时,物体围绕自身中心点对称改变大小,如图:

8.gif

  • 当pivot设置为(0.2,0.2)时,改变大小效果如图:

9.gif

缩放

  • 当pivot设置为(0.5,0.5)时,物体围绕自身中心点缩放,如图:

10.gif

  • 当pivot设置为(0,0)时,缩放效果如图:

11.gif


anchor锚点

锚点是矩形变换(RectTransform)包含的一种布局概念,它显示为4个小三角形的控制柄,锚点信息也在inspector中。如果矩形变换的父项也是矩形变换(RectTransform),那么子矩形变换可以通过各种方式锚定到父矩形变换。

  • anchor由四个小三角形的控制柄组成,其中Min(左下)的X控制的是左边两个控制柄在X轴上移动,Y控制的是下面两个控制柄在Y轴上面移动;Max(右上)的X控制的是右边两个控制柄在X轴上移动,Y控制的是上面两个控制柄在Y轴上移动。在值为[0,1]的范围内相对于父物体移动,如果所示:

12.gif

  • 当所有锚点控制柄在一起时,显示的字段为posx,poxy,height,width,其中posx,poxy表示的是物体本身轴心距离的父物体的锚点位置。

  • 当锚点分开时,字段可能部分或者完全为left,right,top和bottom。如果锚点水平分开则显示为left和right,垂直分开则显示为top和bottom。left代表物体本身左边两个控制柄距离自身左边框的距离;right代表物体本身右边两个控制柄距离自身右边边框的距离;top代表上面两个控制柄距离自身上边框的距离;bottom代表物体本身下面两个控制柄具体自身下边框的距离。 如图:

13.gif


localPosition和anchoredPosition的区别

RectTransform继承自Transform,用于描述矩形的坐标(Position),尺寸(Size),锚点(anchor)和中心点(pivot)等信息,每个2D布局下的元素都会自动生成该组件。当我们在处理UI组件时,往往容易混淆localPosition与anchoredPosition(3D)的概念和用法。

测试案例

  • 确定两个矩形,父节点:红色矩形200 * 200,子节点:白色矩形100 * 100。先设置两个矩形的中心点Pivot是(0.5, 0.5),锚点Anchor重合(0.5, 0.5),此时子矩形的localPosition是(0.0, 0.0, 0.0),anchoredPositon是(0.0, 0.0),如图:

11.png

  • 测试1:父矩形不变,把子矩形锚点Anchor设置为父节点左上角。此时子矩形的localPosition是(0.0, 0.0, 0.0),anchoredPositon是(100.0, -100.0),如图:

12.png

  • 测试2:父矩形不变,把子矩形锚点Anchor设置为父节点左下顶点和右下顶点。此时子矩形的localPosition是(0.0, 0.0, 0.0),anchoredPositon是(0.0, 100.0),如图:

13.png

测试小结1:localPosition与自身锚点无关。anchoredPosition会随锚点的设置不同而改变。

  • 测试3:父节点不变,子节点锚点不变,中心点设置为左下角位置(0, 0)。此时子矩形的localPosition是(-50.0, -50.0, 0.0),anchoredPositon是(-50.0, -50.0),如图:

14.png

  • 测试4:父节点不变,子节点锚点不变,中心点设置为右边中心位置(1, 0.5)。此时子矩形的localPosition是(50.0, 0.0, 0.0),anchoredPositon是(50.0, 0.0),如图:

15.png

测试小结2:localPosition与自身中心点有关。anchoredPosition也与自身中线点有关。

anchoredPosition计算源码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript1 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        RectTransform rect = GetComponent<RectTransform>();
        Debug.Log(rect.rect.min);
        Debug.Log(rect.rect.max);
        RectTransform parentRect = transform.parent.GetComponent<RectTransform>();
        // 通过OffsetMin、OffsetMax,将anchoredPosition和localPosition联系起来
        Vector2 localPosition2D = new Vector2(rect.localPosition.x, rect.localPosition.y);
        Vector2 anchorMinPos = parentRect.rect.min + Vector2.Scale(rect.anchorMin, parentRect.rect.size);
        Vector2 rectMinPos = rect.rect.min + localPosition2D;
        Vector2 offsetMin = rectMinPos - anchorMinPos;

        Vector2 anchorMaxPos = parentRect.rect.max - Vector2.Scale(Vector2.one - rect.anchorMax, parentRect.rect.size);
        Vector2 rectMaxPos = rect.rect.max + localPosition2D;
        Vector2 offsetMax = rectMaxPos - anchorMaxPos;

        Vector2 sizeDelta = offsetMax - offsetMin;

        Vector2 anchoredPosition = offsetMin + Vector2.Scale(sizeDelta, rect.pivot);
        Debug.Log(anchoredPosition);
    }
}

总结

  • localPositon表示的是自身物体pivot相对于父物体piovt(轴心)的坐标,与自身锚点无关

  • anchoredPositon与物体本身的pivot(轴心)和自身anchor(锚点)中心的坐标有关,计算方法:

    • anchoredPositon = 自身矩形左下点相对于父节点轴点坐标 - 自身锚点左下点相对于父节点轴点坐标 + sizeDelta* 自身轴点
    • 其中sizeDelta = (自身矩形宽 - 锚点的宽, 自身矩形高 - 锚点的高) 例如下面这种情况:

父节点:父节点

子节点:子节点

那么此时子节点的anchoredPostition为 anchoredPostition = (-50.0, -50.0) - (0.0, 50.0) + (0.0, 50) * (0.8,0.2) = (-50.0, -100.0) + (0.0, 10.0) = (-50.0, -90.0)

  • 当子物体的anchor与父物体的pivot重合时,localpositon和anchoredPosition的值相等。

参考引用

# RectTransform的localPosition与anchoredPosition(3D)的区别