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中。

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

  • 相关阅读:
    webpack2使用ch4-向根目录index.html文件传参并使用参数 使用线上资源 压缩html
    webpack2使用ch3-自动化生成.html和内部引入的js自动更改
    webpack2使用ch2-entry和output简要说明
    webpack2使用ch1-目录说明
    less使用ch1--简单使用
    less使用ch1--认识语法
    vue2购物车ch4-(筛选v-for 点击的那个设置样式 设为默认地址其他 联动 非循环的列表选中和非选中 删除当前选中的列表)
    gulp使用2-gulp-less及watch和错误提示
    gulp使用1-入门指南
    vue2购物车ch3-(过滤器使用 单件商品金额计算 全选全不选 总金额计算 删除商品功能)
  • 原文地址:https://www.cnblogs.com/yzxhz/p/12753670.html
Copyright © 2011-2022 走看看