【问题标题】:Convert a mesh into a graph for navigation将网格转换为图形以进行导航
【发布时间】:2014-03-05 22:01:11
【问题描述】:

旁注:我不确定这个问题是否属于游戏开发堆栈交换网站 - 但是,我觉得它属于这里,因为虽然上下文是一个游戏,但我希望实现的算法本身是公平的应用无关。此外,我不是在寻找一种高级技术,因为我觉得我已经建立了一种,而是我正在寻求针对某个问题的更具体的帮助。无论如何,对于这个问题:

大家好!

我正在开发一个多人游戏,该游戏要求服务器可以为服务器控制的实体执行寻路。服务器是一个直接的 C# 应用程序,客户端使用 Unity 游戏引擎。在服务器上使用 Unity 不是一种选择。此外,我想完全避免使用原生库。

我已经检查了 Detour 的寻路功能,虽然它们确实有 C# 端口,但我宁愿自己实现实际的寻路位;因为这个过程足够简单,我希望它可以根据我的需要进行定制,以便它可以很好地与服务器上的现有组件配合使用。

Unity 内置了对 Recast/Detour 的支持。这很好,因为我可以在 Unity 中使用 Recast 来生成导航网格;然后使用我自己的寻路在服务器上使用它。问题是我似乎找不到合适的方法来根据 Unity/Recast 创建的网格生成图形。

我需要做的是在内存中创建一个图形,其中每个节点都是网格中的一个三角形,图形的每条边连接两个彼此相邻的三角形。

我能够从 Unity 的 API 中提取的唯一数据是生成的网格的顶点和三角形索引,因此我需要重新构建自己的图表。我的第一个实现只是为每个三角形创建一个节点,如果该三角形与另一个三角形共享另外两个点,则在它们之间创建一个链接 - 形成我的图形的边缘。

虽然这对大多数网格很有效,但它的不足之处在于,Unity 似乎吐出了在区域(多边形)之间可以有连接(边)的网格,即使它们不共享两个顶点。这是 Unity 将其生成的导航网格覆盖到我的关卡几何体上的示例(Unity 确实将三角形合并为凸多边形,而我的代码没有 - 但是,无论哪种情况,问题仍然存在)

在此示例中,我生成的图形需要连接由白线分隔的多边形(我找不到任何文档解释为什么它在 Unity 中呈现为白色)但无法这样做,因为它们只共享一个单个顶点。

我想知道是否有一种有效的算法来检测这些情况。我想做的是让多边形被认为是连接的:

if (sharedVertexCount == 2)
    connectPolygons()
else if (sharedVertexCount == 1)
    Vector3[] parallelLine = findParallelLineSharedByBothPolygons()
    if (parallelLine != null)
        Vector3 otherPoint = getUnsharedPointInLine(parallelLine)
        if (isPointInLine(parallelLine, otherPoint))
            connectPolygons()

认为这应该可行,但我没有找到有效地做到这一点的方法。此外,我在“isPointInLine”实现方面遇到了一些麻烦,因为显然我的数学技能比我想象的要生疏。

无论如何,必须有一个更简单的解决方案;但是我在网上找不到任何东西可以将我指向那个方向......这就是为什么我问你们好人是否有什么我可以做的事情来有效地将生成的导航网格转换为连接的多边形图。无论是帮助我实现 isPointInLine 还是为我指出一个更明智的算法的方向,我都会感激不尽。

【问题讨论】:

    标签: c# algorithm unity3d path-finding navmesh


    【解决方案1】:

    当涉及到寻路时,大多数方法都建议使用一个专门用于导航的预制数据结构,这种结构更易于使用(除非您的图形数据结构足够简单,但事实并非如此)。

    我建议你几个解决方案:

    • 基于体素的导航系统:使用 3D 布尔数组(不能通过)实现体素系统,并应用 A 星D 星算法就可以了。

    • 知道 AI 可以通过的路径向量。

    • 两个系统的合并(主路径使用已知的路径向量,而网格标记与 false 相交的体素。- 这可能是您正在寻找的解决方案。

    【讨论】:

    • 好吧,我当然可以放弃 Unity 对 Recast 的使用并编写我自己的自动导航网格生成器;但是随着从 Unity 的导航网格中导出的三角形,我非常接近有一个工作实现,将它用作我的寻路系统的输入。基本上你是在暗示这种方法不值得麻烦?
    • 此方法是封闭的,对于大多数应用程序(游戏等),您不需要封闭的解决方案,您需要一个工作简单、可维护的解决方案。我是软件基础架构设计师,我喜欢密封解决方案,哈哈……
    • D* 已经过时,如果你真的需要它,你应该改用 D*-Lite。然而,即使是 D*-Lite 也很少用于游戏,因为它比 A* 复杂得多。请参阅here 了解更多信息。
    【解决方案2】:

    如果我正确理解了您的问题,基于可见性图的路径规划算法可以提供帮助:

    线索是从现有的多边形地图中提取一个图形,其中的节点在彼此直接可到达时连接。生成的所谓可见性图(参见https://en.wikipedia.org/wiki/Visibility_graph)然后可用于使用常规最短路径算法(https://en.wikipedia.org/wiki/Shortest_path_problem)进行导航。

    有很多现有的算法可以有效地提取路径规划的可见性图。以下是一些相关链接:

    A thesis describing the general procedure and a few tweaks in chapter 4.4

    My python package for visibility based path planning

    Open source C++ library for 2D floating-point visibility algorithms, path planning

    Paper about Lee's algorithm

    C implementation of Lee's algorithm

    【讨论】:

      猜你喜欢
      • 2011-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 2017-01-18
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多