zoukankan      html  css  js  c++  java
  • 获取BoxCollider的真实边界(非Bounds)

    之前使用的方法是:

        bool PosInBounds(Transform trans,Bounds bounds)
        {
            return bounds.Contains(transform.position);
        }

    一句话就搞定了,但是!

    在开发防穿过程中发现使用BoxCollider的Bounds有问题:

    当BoxCollider有旋转角度的时候,Bounds会比实际的BoxCollider范围大。

    如下图:

    所以决定自己算一下边界:

        public Vector3[] GetBoxPoints(Collider collider)
        {
    
            Vector3[] allPoints = new Vector3[8];
    
            Quaternion quaternion = collider.transform.rotation;
    
            BoxCollider boxCollider = null;
            try
            {
                boxCollider = (BoxCollider)collider;
            }
            catch
            {
                return new Vector3[0];
            }
            Vector3 c = collider.bounds.center;
            Vector3 size = new Vector3(boxCollider.size.x * boxCollider.transform.lossyScale.x, boxCollider.size.y * boxCollider.transform.lossyScale.y, boxCollider.size.z * boxCollider.transform.lossyScale.z);
            float rx = size.x / 2f;
            float ry = size.y / 2f;
            float rz = size.z / 2f;
    
            allPoints[0] = c + quaternion * new Vector3(-rx, -ry, rz);
            allPoints[1] = c + quaternion * new Vector3(rx, -ry, rz);
            allPoints[2] = c + quaternion * new Vector3(rx, -ry, -rz);
            allPoints[3] = c + quaternion * new Vector3(-rx, -ry, -rz);
    
            allPoints[4] = c + quaternion * new Vector3(-rx, ry, rz);
            allPoints[5] = c + quaternion * new Vector3(rx, ry, rz);
            allPoints[6] = c + quaternion * new Vector3(rx, ry, -rz);
            allPoints[7] = c + quaternion * new Vector3(-rx, ry, -rz);
            return allPoints;
        }

    要是想看到边界可以在Scene场景绘制出来:

        void DrawLine(Collider collider)
        {
            Vector3[] points = GetBoxPoints(collider);
            if (points.Length == 0)
            {
                return;
            }
            #region 底面
            Debug.DrawLine(points[0], points[1], Color.red);
            Debug.DrawLine(points[1], points[2], Color.red);
            Debug.DrawLine(points[2], points[3], Color.red);
            Debug.DrawLine(points[0], points[3], Color.red);
            #endregion
    
            #region 顶面
            Debug.DrawLine(points[4], points[5], Color.red);
            Debug.DrawLine(points[5], points[6], Color.red);
            Debug.DrawLine(points[6], points[7], Color.red);
            Debug.DrawLine(points[4], points[7], Color.red);
            #endregion
    
            Debug.DrawLine(points[0], points[4], Color.red);
            Debug.DrawLine(points[1], points[5], Color.red);
            Debug.DrawLine(points[2], points[6], Color.red);
            Debug.DrawLine(points[3], points[7], Color.red);
        }

    画出来后如图:

    黄色和绿色的线重叠后显示了黄色。 

    这就为判断边界提供了依据。

    获取到八个顶点后计算围成立方体的6个面:

        public bool PosInBounds(Transform trans,Collider collider)
        {
            Vector3[] points = GetBoxPoints(collider);
    
            Plane forward = new Plane(points[0], points[1], points[2]);
            Plane back = new Plane(points[4], points[5], points[6]);
            Plane left = new Plane(points[3], points[2], points[6]);
            Plane right = new Plane(points[0], points[1], points[5]);
            Plane up = new Plane(points[3], points[0], points[4]);
            Plane down = new Plane(points[2], points[1], points[5]);
    
            bool isEnterForwardBack = forward.GetSide(trans.position) != back.GetSide(trans.position);
            bool isEnterLeftRight = left.GetSide(trans.position) != right.GetSide(trans.position);
            bool isEnterUpDown = up.GetSide(trans.position) != down.GetSide(trans.position);
    
            return isEnterForwardBack && isEnterLeftRight && isEnterUpDown;
    
        }

    获取6个面后,直接判断:

      点是不是在两个相对的面中间,即可知道是不是在BoxCollider中。

    实际应用中可以用来计算人物移动、摄像机移动防穿透。

  • 相关阅读:
    [转]iOS应用程序多语言本地化解决方案
    【汇】iOS面试题
    [转]UIView 和 CALayer的那点事
    [转]25个增强iOS应用程序性能的提示和技巧 — 高级篇
    [转]25个增强iOS应用程序性能的提示和技巧 — 中级篇
    [转]25个增强iOS应用程序性能的提示和技巧 — 初级篇
    [转]NSNotification、delegate和KVO、KVC的区别
    [转]ViewController的生命周期
    [QualityCenter]设置工作流脚本-设置不同字段值关联不同列表
    [QualityCenter]设置工作流脚本-缺陷字段值发生变化时的处理
  • 原文地址:https://www.cnblogs.com/yzxhz/p/12753670.html
Copyright © 2011-2022 走看看