首页 > 解决方案 > 在 Unity 中创建自定义凸包和网格

问题描述

我目前正在尝试将复杂的搜索字段实现到我正在从事的统一项目中,用户可以在其中将点生成到场景中。我的目标是根据他们创建的点为该用户创建一个自定义形状,然后我想检测其他对象是否在该形状内,类似于检测复杂船体内的点(仍然不稳定关于这背后的理论,但可以在这里找到一个例子)。如果可能的话,如果点稍后移动,我还希望形状能够自行更新,给它一种几乎有弹性、有弹性的感觉。

到目前为止,我在网上找到的每个教程或资源都使用完全相同的基本示例,其中脚本将新的顶点、UV 和三角形分配给自定义网格,以使用两个三角形制作平面,但这非常简单,而且毫无帮助当我根本不知道最终的形状会是什么样子,或者即使用户在场景中只有五个点时实际绘制的三角形。

截至目前,我能想到的最接近的视觉表示有一个 List 跟踪用户的点,以及一个脚本,它使用 LineRenderers 绘制一堆伪三角形来连接每个点,即使是那些不在外部的点面,通过多次遍历列表。虽然这看起来接近我想要的,但它实际上并没有任何用处,因为我不知道如何“填充”这些面孔,而且当涉及到一个物体是否是时,我仍然比较迷茫在该船体内部,如下例所示的红色球体。

角度 1

角度 2

我还可以在 Update() 方法期间反复破坏和重绘这些线条,这使我可以抓取一个点并移动它,从而导致形状动态变化,但这会导致不希望的闪烁效果,我会尽快避免现在。

由于这是一个如此广泛的问题,我还包括了我用来在下面绘制这些线的方法,它将一堆形状像三角形的线放在一个空的游戏对象上,以便于破坏和重新创建:

void drawHull()
{
    if (!GameObject.Find("hullHold"))
    {
        hullHold = new GameObject();
        hullHold.name = "hullHold";
    }

    foreach(GameObject point in points)
    {
        for (int i = points.IndexOf(point); i < points.Count - 2; i++)
        {
            lineEdge = Instantiate(lineReference);
            lineEdge.name = "Triangle" + i;
            lineEdge.GetComponent<LineRenderer>().startColor = Color.black;
            lineEdge.GetComponent<LineRenderer>().endColor = Color.black;
            lineEdge.GetComponent<LineRenderer>().positionCount = 3;
            lineEdge.GetComponent<LineRenderer>().SetPosition(0, points[points.IndexOf(point)].transform.position);
            lineEdge.GetComponent<LineRenderer>().SetPosition(1, points[i + 1].transform.position);
            lineEdge.GetComponent<LineRenderer>().SetPosition(2, points[i + 2].transform.position);
            lineEdge.GetComponent<LineRenderer>().loop = true;
            lineEdge.SetActive(true);
            lineEdge.transform.SetParent(hullHold.transform);
        }
    }
}

如果有人在其他地方遇到过我根本找不到的类似问题,请告诉我!从创建自定义网格的更多知识到确定一个点是否在凸包内的更深入和对初学者友好的解释都将非常有帮助。如果它完全相关,我正在使用 VR 并运行版本 2018.2.6f1 以确保 Oculus rift 包和 Unity 运行良好,但我在几个月后的环境中工作并没有遇到任何问题。

谢谢!

标签: c#unity3dmeshconvex-hull

解决方案


您确实提到了将顶点和三角形分配给网格-这是统一执行此操作的“正确”方法,因为它与高度优化的 MeshRenderer 相关联,而且我相信碰撞器能够在给定形状的情况下使用网格,这样,所以你应该能够插入 PhysX 并查询它是否有与你的网格重叠的碰撞器。手动完成,也就是遍历面并建立对象的实际边界实际上很难有效地完成


推荐阅读