在Unity中,假设你有一个3D对象,
当然,获得AABB是微不足道的,Unity有直接的功能,
(您可能必须以通常的方式“添加渲染器的所有边界框”,没问题。)
现在,对于相关的摄像机,如同定位,AABB确实覆盖了某个2D边界框......
事实上......是否有某种内置的直接方式在Unity中找到橙色的2D盒子?
(请注意,要手动执行此操作,您只需为AABB的8个点制作光线(或使用世界屏幕空间,如Draco提到的那样);将这些光线封装在2D中以制作橙色框。)
我不需要手动解决方案,我问的是引擎是否在每一帧都以某种方式从管道中提供了这个?
有电话吗?
(事实上,拥有它会更好......)
我的感觉是一个或全部
肯定会知道橙色的盒子,甚至是管道内的蓝色盒子,就在显卡的正上方,就像知道给定网格的AABB一样。
我们知道Unity允许您在给定网格的每一帧中立即点击AABB 3D框:事实上,Unity是否给出了“2D截头”,如图所示?
然而,自己找到极端非常容易。获取网格的边界框(截图中显示的长方体)就是如何完成的,你只是在变换的空间中进行。
您可能还希望首先执行模型的Gift Wrapping,并且仅处理所得到的凸包(因为没有凸出船体的一部分将不会出现在凸包的边界之外)。如果您打算在模型移动,缩放或在屏幕上旋转时绘制此屏幕空间矩形,并且必须重新计算边界框,那么您将要执行此操作并缓存结果。
请注意,如果模型具有动画效果(例如,如果您的人形机器人站起来并且跳跃插孔),则此功能无效。解决动画案例要困难得多,因为你必须将每个动画的每一帧视为原始网格的一部分,以便进行凸包解决(以确保你的动画都不会移动网格的一部分)在凸包外面),通过功率增加复杂性。
函数GUI3dRectWithObject
将在屏幕上返回给定GameObject的3D边界框。
函数GUI2dRectWithObject
将在屏幕上返回给定GameObject的2D边界框。
public static Rect GUI3dRectWithObject(GameObject go)
{
Vector3 cen = go.GetComponent<Renderer>().bounds.center;
Vector3 ext = go.GetComponent<Renderer>().bounds.extents;
Vector2[] extentPoints = new Vector2[8]
{
WorldToGUIPoint(new Vector3(cen.x-ext.x, cen.y-ext.y, cen.z-ext.z)),
WorldToGUIPoint(new Vector3(cen.x+ext.x, cen.y-ext.y, cen.z-ext.z)),
WorldToGUIPoint(new Vector3(cen.x-ext.x, cen.y-ext.y, cen.z+ext.z)),
WorldToGUIPoint(new Vector3(cen.x+ext.x, cen.y-ext.y, cen.z+ext.z)),
WorldToGUIPoint(new Vector3(cen.x-ext.x, cen.y+ext.y, cen.z-ext.z)),
WorldToGUIPoint(new Vector3(cen.x+ext.x, cen.y+ext.y, cen.z-ext.z)),
WorldToGUIPoint(new Vector3(cen.x-ext.x, cen.y+ext.y, cen.z+ext.z)),
WorldToGUIPoint(new Vector3(cen.x+ext.x, cen.y+ext.y, cen.z+ext.z))
};
Vector2 min = extentPoints[0];
Vector2 max = extentPoints[0];
foreach (Vector2 v in extentPoints)
{
min = Vector2.Min(min, v);
max = Vector2.Max(max, v);
}
return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
}
public static Rect GUI2dRectWithObject(GameObject go)
{
Vector3[] vertices = go.GetComponent<MeshFilter>().mesh.vertices;
float x1 = float.MaxValue, y1 = float.MaxValue, x2 = 0.0f, y2 = 0.0f;
foreach (Vector3 vert in vertices)
{
Vector2 tmp = WorldToGUIPoint(go.transform.TransformPoint(vert));
if (tmp.x < x1) x1 = tmp.x;
if (tmp.x > x2) x2 = tmp.x;
if (tmp.y < y1) y1 = tmp.y;
if (tmp.y > y2) y2 = tmp.y;
}
Rect bbox = new Rect(x1, y1, x2 - x1, y2 - y1);
Debug.Log(bbox);
return bbox;
}
public static Vector2 WorldToGUIPoint(Vector3 world)
{
Vector2 screenPoint = Camera.main.WorldToScreenPoint(world);
screenPoint.y = (float)Screen.height - screenPoint.y;
return screenPoint;
}
参考:Is there an easy way to get on-screen render size (bounds)?