Unity mesh.bounds/meshrenderer.bounds

Mesh.bounds is the axis-aligned bounding box of the mesh in its local space (that is, not affected by the transform). Note that the Renderer.bounds property is similar but returns the bounds in world space.

https://docs.unity3d.com/ScriptReference/Mesh-bounds.html

mesh.bounds返回本地坐标的bounds,不随旋转等变化,renderer/collider.bounds返回世界坐标bounds;

如果求多个物体集合的bounds,最好获取renderer的bounds,再encapsulate(https://answers.unity.com/questions/17968/finding-the-bounds-of-a-grouped-model.html);用mesh.bounds去encapsulate不准确(encapsulate不应该传入本地坐标,

// UnityEngine.Bounds
public void Encapsulate(Bounds bounds)
{
    this.Encapsulate(bounds.center - bounds.extents);
    this.Encapsulate(bounds.center + bounds.extents);
}
public void Encapsulate(Vector3 point)
{
	this.SetMinMax(Vector3.Min(this.min, point), Vector3.Max(this.max, point));
}
public void SetMinMax(Vector3 min, Vector3 max)
{
	this.extents = (max - min) * 0.5f;
	this.center = min + this.extents;
}

 

renderer.bounds

mesh.bounds

     private void CalculateLocalBounds()
     {
         Quaternion currentRotation = this.transform.rotation;
         this.transform.rotation = Quaternion.Euler(0f,0f,0f); //先重置角度
 
         Bounds bounds = new Bounds(this.transform.position, Vector3.zero);
 
         foreach(Renderer renderer in GetComponentsInChildren<Renderer>())
         {
             bounds.Encapsulate(renderer.bounds);
         }
 
         Vector3 localCenter = bounds.center - this.transform.position;
         bounds.center = localCenter;
         Debug.Log("The local bounds of this model is " + bounds);
 
         this.transform.rotation = currentRotation;//恢复旋转
     }

可视化脚本:

using UnityEngine;
using System.Collections;

[ExecuteInEditMode()]

public class ShowMeshBounds : MonoBehaviour
{
    public Color color = Color.green;
    public bool _useMeshBounds = true;
    private Vector3 v3FrontTopLeft;
    private Vector3 v3FrontTopRight;
    private Vector3 v3FrontBottomLeft;
    private Vector3 v3FrontBottomRight;
    private Vector3 v3BackTopLeft;
    private Vector3 v3BackTopRight;
    private Vector3 v3BackBottomLeft;
    private Vector3 v3BackBottomRight;

    void Update()
    {
        CalcPositons();
        DrawBox();
    }

    void CalcPositons()
    {
        Bounds bounds;
        if (_useMeshBounds)
        {
            //bounds = GetComponent<MeshFilter>().mesh.bounds;

            //multi
            if (GetComponent<MeshFilter>())
                bounds = GetComponent<MeshFilter>().mesh.bounds;
            else
                bounds = new Bounds(transform.position, Vector3.zero);
            MeshFilter[] _mfs = GetComponentsInChildren<MeshFilter>();
            foreach(var m in _mfs)
            {
                if (m != GetComponent<MeshFilter>())
                    bounds.Encapsulate(m.mesh.bounds);
            }

        }
        else
        {
            //bounds = GetComponent<MeshRenderer>().bounds;
            //bounds = GetComponent<BoxCollider>().bounds;
            //bounds = GetComponent<MeshCollider>().bounds;

            if (GetComponent<MeshRenderer>())
                bounds = GetComponent<MeshRenderer>().bounds;
            else
                bounds = new Bounds(transform.position, Vector3.zero);
            MeshRenderer[] _mrs = GetComponentsInChildren<MeshRenderer>();
            foreach (var m in _mrs)
            {
                if (m != GetComponent<MeshRenderer>())
                    bounds.Encapsulate(m.bounds);
            }
        }
        //BoxCollider bc = GetComponent<BoxCollider>();
        //if (bc != null)
        //    bounds = bc.bounds;
        //else
        //return;

        Vector3 v3Center = bounds.center;
        Vector3 v3Extents = bounds.extents;

        v3FrontTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z);  // Front top left corner
        v3FrontTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z);  // Front top right corner
        v3FrontBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z);  // Front bottom left corner
        v3FrontBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z);  // Front bottom right corner
        v3BackTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z);  // Back top left corner
        v3BackTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z);  // Back top right corner
        v3BackBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z);  // Back bottom left corner
        v3BackBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z);  // Back bottom right corner
        if (_useMeshBounds)
        {
            v3FrontTopLeft = transform.TransformPoint(v3FrontTopLeft);
            v3FrontTopRight = transform.TransformPoint(v3FrontTopRight);
            v3FrontBottomLeft = transform.TransformPoint(v3FrontBottomLeft);
            v3FrontBottomRight = transform.TransformPoint(v3FrontBottomRight);
            v3BackTopLeft = transform.TransformPoint(v3BackTopLeft);
            v3BackTopRight = transform.TransformPoint(v3BackTopRight);
            v3BackBottomLeft = transform.TransformPoint(v3BackBottomLeft);
            v3BackBottomRight = transform.TransformPoint(v3BackBottomRight);
        }
    }

    void DrawBox()
    {
        //if (Input.GetKey (KeyCode.S)) {
        Debug.DrawLine(v3FrontTopLeft, v3FrontTopRight, color);
        Debug.DrawLine(v3FrontTopRight, v3FrontBottomRight, color);
        Debug.DrawLine(v3FrontBottomRight, v3FrontBottomLeft, color);
        Debug.DrawLine(v3FrontBottomLeft, v3FrontTopLeft, color);

        Debug.DrawLine(v3BackTopLeft, v3BackTopRight, color);
        Debug.DrawLine(v3BackTopRight, v3BackBottomRight, color);
        Debug.DrawLine(v3BackBottomRight, v3BackBottomLeft, color);
        Debug.DrawLine(v3BackBottomLeft, v3BackTopLeft, color);

        Debug.DrawLine(v3FrontTopLeft, v3BackTopLeft, color);
        Debug.DrawLine(v3FrontTopRight, v3BackTopRight, color);
        Debug.DrawLine(v3FrontBottomRight, v3BackBottomRight, color);
        Debug.DrawLine(v3FrontBottomLeft, v3BackBottomLeft, color);
        //}
        //local pivot position
        Debug.DrawLine(transform.position, transform.position + transform.forward * 10, Color.blue);
        //not bounds center?
        if (transform.GetComponent<MeshFilter>())
        {
#if UNITY_EDITOR
            Vector3 _meshboundCenter = transform.GetComponent<MeshFilter>().sharedMesh.bounds.center;
            Debug.DrawLine(_meshboundCenter, _meshboundCenter + transform.forward * 10, Color.magenta);
#else
        Vector3 _meshboundCenter = transform.GetComponent<MeshFilter>().mesh.bounds.center;
        Debug.DrawLine(_meshboundCenter, _meshboundCenter + transform.forward * 10, Color.magenta);
#endif
        }
        //local center position
        if (transform.GetComponent<MeshRenderer>())
        {
            Vector3 _boundCenter = transform.GetComponent<MeshRenderer>().bounds.center;
            Debug.DrawLine(_boundCenter, _boundCenter + transform.forward * 10, Color.black);
        }//draw intsect ray
        //Debug.DrawLine(v3FrontTopLeft, v3FrontTopLeft-transform.forward*10, Color.red);
        //Debug.DrawLine(v3FrontTopRight, v3FrontTopRight- transform.forward * 10, Color.red);
        //Debug.DrawLine(v3FrontBottomRight, v3FrontBottomRight+transform.right*10, Color.red);
        //Debug.DrawLine(v3FrontBottomLeft, v3FrontBottomLeft-transform.right*10, Color.red);
        //
        //Debug.DrawLine(v3BackTopLeft, v3BackTopLeft+transform.forward*10, Color.red);
        //Debug.DrawLine(v3BackTopRight, v3BackTopRight+transform.right*10, Color.red);
        //Debug.DrawLine(v3BackBottomRight, v3BackBottomRight+transform.right*10, Color.red);
        //Debug.DrawLine(v3BackBottomLeft, v3BackBottomLeft-transform.up*10, Color.red);
        //if(Input.GetKeyDown(KeyCode.Space))
            Detect(v3FrontTopRight, v3FrontBottomRight, v3BackBottomRight, v3BackTopRight, transform.right, 8,0.05f);
    }

    void Detect(Vector3 p1,Vector3 p2,Vector3 p3,Vector3 p4,Vector3 _direction,float _maxDectDis,float _step)
    {
        int _STEP1 = (int)(Vector3.Distance(p2, p1) / _step);
        int _STEP2 = (int)(Vector3.Distance(p4, p1) / _step);
        float _min=float.PositiveInfinity;
        RaycastHit _hit;
        Vector3 _validVec=Vector3.negativeInfinity;
        for (int i = 0; i <= _STEP1; i++)
        {
            for(int j = 0; j <= _STEP2; j++)
            {
                Vector3 _tmp = p1 + (p2 - p1) / _STEP1 * i + (p4 - p1) / _STEP2 * j;
                Ray _ray = new Ray(_tmp, _direction);
                if(Physics.Raycast(_ray, out _hit, _maxDectDis))
                {
                    float _tmpdis = Vector3.Distance(_hit.point, _tmp);
                    //_min = _min < _tmpdis ? _min : _tmpdis;
                    if (_min > _tmpdis)
                    {
                        _min = _tmpdis;
                        _validVec = _tmp;
                    }
                }
                //Debug.DrawLine(_tmp, _tmp + _direction * _maxDectDis, Color.yellow);
            }
        }
        if (_min > 0)
        {
            Debug.DrawLine(_validVec, _validVec + _direction * _min, Color.yellow);
            Debug.Log(_min);
        }
        //Debug.DrawLine(p1, p1 + _direction * _maxDectDis, Color.yellow);
        //Debug.DrawLine(p2, p2 + _direction * _maxDectDis, Color.yellow);
        //Debug.DrawLine(p3, p3 + _direction * _maxDectDis, Color.yellow);
        //Debug.DrawLine(p4, p4 + _direction * _maxDectDis, Color.yellow);
        //Vector3 _center = (p1 + p2 + p3 + p4) / 4;
        //Debug.DrawLine(_center, _center + _direction*_maxDectDis, Color.yellow);
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值