简化道路系统的碰撞网格? [英] Simplify collision mesh of road-like system?

查看:161
本文介绍了简化道路系统的碰撞网格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于在Unity中以3d形式显示的基于瓷砖的道路或人行道系统,如图所示,我在其接缝上移动了一些微型刚体(即使对于相同的垂直位置和比例,以及为每个瓷砖使用盒子对撞机时) .是否有一个很好的方法例如将碰撞网格合并为一个超级简化的&全平面网格?我没有运气,例如导出为对象(都不使用我的网格简化程序),因为在重新导入并摆脱单个盒对撞机时,明显的微型凸点仍然存在.我的要求不是必须是实时的(尽管如果没有缺点,那将是一个加号).谢谢!

Given a tile-based road or sidewalk system in Unity in 3d like shown, I'm getting mini-bumps of rigidbodies moving over their seams (even for same vertical position & scale and when using box colliders for each tile). Is there a good way to e.g. combine the collision mesh into one super-simplified & all-flat mesh? I've had no luck with e.g. exporting as Object (neither with my mesh simplifier), as the apparent mini-bumps persist when re-importing and getting rid of the individual box colliders. My requirement isn't that it has to be real-time (though that would be a bit of a plus, if no downsides). Thanks!

推荐答案

您可以尝试 Mesh.CombineMeshes 可以在所有小的碰撞器中构成一个大型碰撞器.

You can try Mesh.CombineMeshes to make a big collider out of all the small ones.

[RequireComponent(typeof(MeshCollider))]
public class MeshCompositeCollider : MonoBehaviour
{
    void Start()
    {
        var meshColliders = GetComponentsInChildren<MeshCollider>();
        var combine = new CombineInstance[meshColliders.Length];

        for (int i = 0; i < meshColliders.Length; i++)
        {
            combine[i].mesh = meshColliders[i].sharedMesh;
            combine[i].transform = meshColliders[i].transform.localToWorldMatrix;
            meshColliders[i].enabled = false;
        }

        var compositeMesh = new Mesh();
        compositeMesh.CombineMeshes(combine);
        //WeldVertices(compositeMesh);
        GetComponent<MeshCollider>().sharedMesh = compositeMesh;
        GetComponent<MeshCollider>().enabled = true;
    }
}

要注意的一件事:组合的网格位于世界空间坐标中,因此,如果附加到该对象上的gameObject有任何变换更改,它们也将被应用.

One thing to note: the resulting combined mesh is in world space coordinates, so if the gameObject this gets attached to has any transform changes they will be applied too.

如果您拥有MeshCollider->烹饪选项-> 焊接共置,这可能就足够了启用了顶点,该顶点应该合并具有相同位置的顶点.

This might be enough if you have the MeshCollider -> Cooking Options -> Weld Colocated Vertices enabled which should combine the vertices that have the same position.

否则,您可以尝试焊接自己查看顶点是否可以解决问题.

If not, you can try to weld the vertices yourself to see if that fixes the problem.

public static void WeldVertices(Mesh aMesh, float aMaxDistDelta = 0.01f)
{
    var aMaxDelta = aMaxDistDelta * aMaxDistDelta;
    var verts = aMesh.vertices;    
    List<int> newVerts = new List<int>();
    int[] map = new int[verts.Length];
    // create mapping and filter duplicates.
    for (int i = 0; i < verts.Length; i++)
    {
        var p = verts[i];

        bool duplicate = false;
        for (int i2 = 0; i2 < newVerts.Count; i2++)
        {
            int a = newVerts[i2];
            if ((verts[a] - p).sqrMagnitude <= aMaxDelta)
            {
                map[i] = i2;
                duplicate = true;
                break;
            }
        }
        if (!duplicate)
        {
            map[i] = newVerts.Count;
            newVerts.Add(i);
        }
    }
    // create new vertices
    var verts2 = new Vector3[newVerts.Count];    
    for (int i = 0; i < newVerts.Count; i++)
    {
        int a = newVerts[i];
        verts2[i] = verts[a];        
    }
    // map the triangle to the new vertices
    var tris = aMesh.triangles;
    for (int i = 0; i < tris.Length; i++)
    {
        tris[i] = map[tris[i]];
    }

    aMesh.Clear();       
    aMesh.vertices = verts2;
    aMesh.triangles = tris;                
}


这是一个示例(之前和之后):6个对撞机上方有明显的间隙,1个对撞机下方没有任何间隙.


Here is an example (before and after): Above 6 colliders with clear gaps, below 1 collider with no gaps.

这篇关于简化道路系统的碰撞网格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆