【包围盒计算】计算某个对象所有子对象的包围盒

版权声明: https://blog.csdn.net/IT_yanghui/article/details/82499405

版权所有。转载请注明出处: 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;
        }
        
    }

猜你喜欢

转载自blog.csdn.net/IT_yanghui/article/details/82499405