版权声明:本文为博主原创文章,未经博主允许不得转载。 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)位置:
这个也就是上面两个函数的总结了,其实就是求边界。