MeshRenderer has wrong bounds when rotated

拥有回忆 提交于 2021-01-07 03:26:06

问题


When I try to get the bounds of my models (created in Blender) and show them in Inspector:

As you can see the bounds are correct when the objects are not rotated. But when they are (left-most object) bounds start getting totally wrong.

Here is a script that shows / gets the bounds:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GetBounds : MonoBehaviour
{
    public MeshRenderer mesh_renderer = null;

    public bool show_bounds = false;

    private void OnDrawGizmos()
    {
        if (!show_bounds) return;

        Gizmos.DrawWireCube(mesh_renderer.bounds.center, mesh_renderer.bounds.size);
        Gizmos.DrawWireSphere(mesh_renderer.bounds.center, 0.3f);
    }
}

How can I fix this?


回答1:


In this thread I have come across this image which explains it pretty much

Unity dos not recalculate the Mesh.bounds all the time except when you add a mesh for the first time or "manually" invoke Mesh.RecalculateBounds.

It then uses this local space Mesh.bounds in order to calculate the translated, scaled and rotated Renderer.bounds in global space based on the Mesh.bounds. This way it always has to iterate a fixed amount of 8 vertices of the bounding box.

There was also a solution provided if you want to get the exact bounds calculated directly from the vertices. I adopted and cleaned it up a bit

public class GetBounds : MonoBehaviour
{
    public MeshRenderer mesh_renderer;
    public bool show_bounds;

    public MeshFilter meshFilter;
    public Mesh mesh;

    private void OnDrawGizmos()
    {
        if (!mesh_renderer) return;
        if (!show_bounds) return;

        if (!meshFilter) meshFilter = mesh_renderer.GetComponent<MeshFilter>();
        if (!meshFilter) return;

        if (!mesh) mesh = meshFilter.mesh;
        if (!mesh) return;

        var vertices = mesh.vertices;
        if (vertices.Length <= 0) return;

        // TransformPoint converts the local mesh vertice dependent on the transform
        // position, scale and orientation into a global position
        var min = transform.TransformPoint(vertices[0]);
        var max = min;

        // Iterate through all vertices
        // except first one
        for (var i = 1; i < vertices.Length; i++)
        {
            var V = transform.TransformPoint(vertices[i]);

            // Go through X,Y and Z of the Vector3
            for (var n = 0; n < 3; n++)
            {
                max[n] = Mathf.Max(V[n], max[n]);
                min[n] = Mathf.Min(V[n], min[n]);
            }
        }

        var bounds = new Bounds();
        bounds.SetMinMax(min, max);

        // ust to compare it to the original bounds
        Gizmos.DrawWireCube(mesh_renderer.bounds.center, mesh_renderer.bounds.size);
        Gizmos.DrawWireSphere(mesh_renderer.bounds.center, 0.3f);

        Gizmos.color = Color.green;
        Gizmos.DrawWireCube(bounds.center, bounds.size);
        Gizmos.DrawWireSphere(bounds.center, 0.3f);
    }
}

Result:

  • In WHITE: The MeshRenderer.bounds

  • In GREEN: The "correct" calculated vertex bounds



来源:https://stackoverflow.com/questions/57711849/meshrenderer-has-wrong-bounds-when-rotated

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!