首页 > 解决方案 > MeshRenderer 旋转时边界错误

问题描述

当我尝试获取模型的边界(在 Blender 中创建)并在 Inspector 中显示它们时:

在此处输入图像描述

如您所见,当对象未旋转时,边界是正确的。但是当它们是(最左边的对象)时,边界开始变得完全错误。

这是一个显示/获取边界的脚本:

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);
    }
}

我怎样才能解决这个问题?

标签: unity3d

解决方案


这个线程中,我遇到了这张图片,它几乎解释了它

在此处输入图像描述

Unity 不会Mesh.bounds一直重新计算,除非您第一次添加网格或“手动”调用Mesh.RecalculateBounds

然后它使用这个局部空间Mesh.bounds来计算Renderer.bounds基于Mesh.bounds. 这样,它总是必须迭代边界框的固定数量的 8 个顶点。

如果您想直接从顶点计算出确切的边界,还提供了一个解决方案。我收养并清理了一下

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);
    }
}

结果:

  • 白色:MeshRenderer.bounds

  • 绿色:“正确”计算的顶点边界

在此处输入图像描述


推荐阅读