【包围盒计算】计算某个对象所有子对象的包围盒
程序员文章站
2024-03-16 18:20:10
...
版权所有。转载请注明出处: IT_yanghui
在游戏开发中,很多时候不需要知道对象下的子对象是什么,只想给该对象外部加一个物理碰撞或者Collider,或者在开发中需要动态获取该对象添加Collider,然而给每一个子对象分别加,明显不现实,浪费时间且影响帧率。
此时我们需要计算该对象所有子对象的包围盒。其实很简单的计算方法,授之于渔。
计算包围盒,需要拿到该对象下所有Renderer,即Renderer[]。通过Renderer去计算包围盒Bounds以及中心点center :
所有Renderer的bounds通过计算得出一个整体(外部)bounds,所有Renderer的中心点center计算得出整体的中心点,有中心点和包围盒,就OK了。
修改一下,可以添加到Unity-Component下,给策划使用,更加方便。
代码如下:看懂了再复制粘贴。
static public class BoundsCalculate
{
/// <summary>
/// 获取模型包围盒
/// </summary>
public static Bounds BOUNDS(this Transform model)
{
Vector3 oldPos = model.position;
model.position = Vector3.zero;
Bounds resultBounds = new Bounds(model.CENTER(), Vector3.zero);
CalculateBounds(model, ref resultBounds);
model.position = oldPos;
Vector3 scalueValue = ScaleValue(model);
resultBounds.size = new Vector3(resultBounds.size.x / scalueValue.x, resultBounds.size.y / scalueValue.y, resultBounds.size.z / scalueValue.z);
return resultBounds;
}
/// <summary>
/// 获取模型包围盒的中心点
/// </summary>
public static Vector3 CENTER(this Transform model)
{
Vector3 result = Vector3.zero;
int counter = 0;
CalculateCenter(model, ref result, ref counter);
if (counter == 0) return result;
return result / counter;
}
/// <summary>
/// 给模型包围盒添加Collider
/// </summary>
public static Bounds AddBoundsCollider(this Transform model)
{
Bounds bounds = model.BOUNDS();
BoxCollider collider = model.gameObject.AddComponent<BoxCollider>();
collider.center = bounds.center;
collider.size = bounds.size;
return bounds;
}
/// <summary>
/// 计算模型包围盒
/// </summary>
private static void CalculateBounds(Transform model, ref Bounds bounds)
{
Renderer[] renders = model.GetComponentsInChildren<Renderer>();
foreach (Renderer child in renders)
{
bounds.Encapsulate(child.bounds);
}
}
/// <summary>
/// 计算模型中心点
/// </summary>
private static void CalculateCenter(Transform model, ref Vector3 result, ref int counter)
{
Renderer[] renders = model.GetComponentsInChildren<Renderer>();
foreach (Renderer child in renders)
{
result += child.bounds.center;
counter++;
}
}
/// <summary>
/// 获取模型Scale值
/// </summary>
private static Vector3 ScaleValue(Transform model)
{
Vector3 result = model.localScale;
return CalculateScale(model, ref result);
}
/// <summary>
/// 计算模型Scale值
/// </summary>
private static Vector3 CalculateScale(Transform model, ref Vector3 value)
{
if (model.parent)
{
Vector3 scale = model.parent.localScale;
value = new Vector3(value.x * scale.x, value.y * scale.y, value.z * scale.z);
CalculateScale(model.parent, ref value);
}
return value;
}
}
上一篇: 最小包围矩形