首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简化路状系统的碰撞网格?

简化路状系统的碰撞网格?
EN

Stack Overflow用户
提问于 2020-01-18 01:31:47
回答 3查看 780关注 0票数 6

在三维的Unity中给出一个基于瓷砖的道路或人行道系统,如图所示,我得到了刚体在接缝上移动的微小凹凸(即使是在相同的垂直位置和比例,以及在对每个瓷砖使用盒子碰撞器时)。有没有一个很好的方法来将碰撞网格合并成一个超简化的全平面网格?例如,我没有幸运地导出为对象(也不是我的网格简化器),因为当重新导入和摆脱单独的长方体对撞器时,明显的小凹凸仍然存在。我的要求并不是它必须是实时的(尽管如果没有缺点,这将是一个小小的优势)。谢谢!

EN

回答 3

Stack Overflow用户

发布于 2020-01-23 21:39:31

你可以试着用Mesh.CombineMeshes把所有的小东西做成一个大的对撞机。

代码语言:javascript
复制
[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具有任何变换更改,则这些更改也将被应用。

如果启用了MeshCollider -> Cooking Options -> Weld Colocated Vertices,这可能就足够了,该选项应合并具有相同位置的顶点。

如果没有,您可以尝试自己对顶点执行weld操作,以查看这是否解决了问题。

代码语言:javascript
复制
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个以下的对撞机没有空隙。

票数 5
EN

Stack Overflow用户

发布于 2020-01-18 02:08:11

您正在寻找一种称为Composite Collider的东西。2D Tilemaps甚至有一个“由复合地图使用”的复选框。如果您附加了一个复合碰撞器2D组件到您的地平图对象,并勾选“由复合使用”,它会将所有的碰撞器合并为一个大型碰撞器。

这就是说,看起来你是在使用预制地图生成道路的碎片,而不是使用tilemap构建地图。你仍然可以通过在对撞机上勾选“由合成使用”来为一堆不同的gameobjects使用合成对撞机,但这比简单地在一个组件上勾选一个按钮要复杂一些,因为你必须配置所有的游戏对象。如果你可以简化到在你的道路上使用tilemap,它应该会简单得多。

票数 0
EN

Stack Overflow用户

发布于 2020-01-23 21:03:13

也许,你不需要改变电路,而是改变汽车碰撞系统:

  • 用真实的碰撞器和输入反馈制作了一个“看不见的虚拟汽车”,然后制造了真实的汽车(可能只有模型,或者用额外的碰撞器进行其他类型的碰撞检测?)但我认为在虚拟汽车中有一个碰撞器就足够了)
  • 使模型遵循虚拟位置,但插值垂直毛刺(例如。每一帧更新你的真实模型位置都是当前位置+ 1/10的"y“差异(也许只有当它太大时)或类似的东西,夹紧位置的时间或百分比将需要手动测试以获得良好的感觉)
  • 如果你使用两个对撞机,玩他们的层和碰撞系统来完善系统(真实模型只与环境或汽车碰撞),假碰撞器忽略环境。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59792261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档