unity ScrollRect解读

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wodownload2/article/details/83625651

函数1:GetBounds()

        private readonly Vector3[] m_Corners = new Vector3[4];
        private Bounds GetBounds()
        {
            if (m_Content == null)
                return new Bounds();
            m_Content.GetWorldCorners(m_Corners);
            var viewWorldToLocalMatrix = viewRect.worldToLocalMatrix;
            return InternalGetBounds(m_Corners, ref viewWorldToLocalMatrix);
        }

这里的m_Content为RectTransform,它有一个方法得到的是四个拐角的世界坐标位置。
这个可以测试下:

public class NewBehaviourScript : MonoBehaviour
{
    public RectTransform m_Content;
    public RectTransform[] p;

    void Start()
    {
        Vector3[] m_Corners = new Vector3[4];
        m_Content.GetWorldCorners(m_Corners);

        for (int i = 0; i < p.Length; ++i)
        {
            p[i].transform.position = m_Corners[i];
        }
    }
}

在这里插入图片描述
四个点放在了矩形的四个拐角位置。

var viewWorldToLocalMatrix = viewRect.worldToLocalMatrix;
得到世界到局部的变换矩阵。

函数2:InternalGetBounds()

internal static Bounds InternalGetBounds(Vector3[] corners, ref Matrix4x4 viewWorldToLocalMatrix)
        {
            var vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            var vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);

            for (int j = 0; j < 4; j++)
            {
                Vector3 v = viewWorldToLocalMatrix.MultiplyPoint3x4(corners[j]);
                vMin = Vector3.Min(v, vMin);
                vMax = Vector3.Max(v, vMax);
            }

            var bounds = new Bounds(vMin, Vector3.zero);
            bounds.Encapsulate(vMax);
            return bounds;
        }

这两句代码是普遍的做法:

var vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
var vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);

想找到最小值,初始的值为MaxValue;想找到最大值,初始的值为MinValue。
接下来遍历四个拐角的点。

for (int j = 0; j < 4; j++)
 {
     Vector3 v = viewWorldToLocalMatrix.MultiplyPoint3x4(corners[j]);
     vMin = Vector3.Min(v, vMin);
     vMax = Vector3.Max(v, vMax);
 }

首先是: Vector3 v = viewWorldToLocalMatrix.MultiplyPoint3x4(corners[j]); 是把世界坐标的点,转换为局部坐标。
测试下:

 var viewWorldToLocalMatrix = m_Content.worldToLocalMatrix;
 var vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
 var vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);

 for (int j = 0; j < 4; j++)
 {
     Vector3 v = viewWorldToLocalMatrix.MultiplyPoint3x4(m_Corners[j]);
     Debug.LogError("j=" + j + "  " + v.x + " " + v.y + " " + v.z);
 }

在这里插入图片描述

注意此时的白色矩形的中心的为(0.5, 0.5)。
如果改变其为(0,0.5),则输出的结果又会变化:
在这里插入图片描述

通过for循环四个点,找到最最小的点,最大的点,参考:https://docs.unity3d.com/ScriptReference/Vector3.Min.html

Description
Returns a vector that is made from the smallest components of two vectors.

See Also: Max function.

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    public Vector3 a = new Vector3(1, 2, 3);
    public Vector3 b = new Vector3(4, 3, 2);

    void Example()
    {
        print(Vector3.Min(a, b));     // prints (1.0f, 2.0f, 2.0f)
    }
}

最终得到了左下角的点,以及右上角的点。
在这里插入图片描述

再来:

            var bounds = new Bounds(vMin, Vector3.zero);

以最小的左下角的点为center,宽度高度为0,初始化bounds。
然后:

bounds.Encapsulate(vMax);

看看结果:
在这里插入图片描述

如果pivot在(0,0.5)位置:
在这里插入图片描述

这个也就是上面两个函数的总结了,其实就是求边界。

猜你喜欢

转载自blog.csdn.net/wodownload2/article/details/83625651
今日推荐