寻路建模的三种方式比较

概述

本文对于游戏寻路中主流的三种建模方式做了比较,分析各自的适用范围和优缺点。这三种建模方式包括:格子(Grid)、路点(Waypoint)、导航网格(Navmesh)

写这篇的原因是项目里需要选择一种合适的寻路实现方案,查阅了大量的文章和算法后,结合着自己的思考和实践,在此做个小结。

这里的建模指的是为地图寻找一个空间表征(spatial representation)1,即把原始地图转换成计算机数据结构表示的模型,用于后面的寻路。注意它与寻路算法2是不同的概念,例如:Grid和Navmesh是两种不同的建模方式,但是建模完成后,都可以用到A*算法。

下面是三种建模方式的图形化表示,一目了然,分别是:(a) 原版地图,(b) 格子,(c) 路点,(d) 导航网格。

这里写图片描述

先来一个简单而粗略的比较,后面再分头细说:

  • 实现复杂度:导航网格 > 格子 > 路点
  • 内存和计算开销3:格子 > 导航网格 > 路点
  • 表达精确性:导航网格 > 格子 > 路点

格子(Grid)

这种方法将原始地图分割成许多的小格子,在计算机中表示为一个二维数组,用0和1分别表示障碍和可行走区域。

格子的优点
  • 容易实现
  • 容易动态修改。如果需要动态加入障碍,只需要确定障碍物会占用哪些格子,再重新寻路即可。
格子的缺点
  • 内存和计算开销大。越大的地图,所需格子就越多,相应的内存占用和寻路计算开销就会越大。另外,格子的大小选择也是一个问题,定得小了,内存和计算开销大;定得大了,又会缩减可行走区域,导致可行走边界不够精确。
  • 可能需要做额外平滑。如果按照格子来寻路,最后生成的路线很可能会出现90度的拐角,甚至可能有连续的多个,这种急转弯会使得游戏寻路表现得“不够自然”。这时还需要做额外的平滑。
  • 不太适合3D地图。格子最早是针对2D地图寻路提出的,不涉及高度信息,因此没有导航网格中的maxClimbagentHeight等参数,更没有考虑分层地图。当然也不是完全不能做,只是更复杂。

路点(Waypoint)

这种方法会在地图中标注一些路点,寻路只能发生在路点和路点之间,在计算机中表示为一张连通图。

路点的优点
  • 实现简单
  • 内存和计算开销低。路点只使用到了真实可行走区域的一小部分,与格子相比,牺牲了路线的灵活性,换取较低的内存和计算开销。
路点的缺点
  • 需要人工参与。因为需要人工标注路点位置和可行走路线。
  • 局限性较大。首先,路点的灵活性较低,寻路必须沿着预先定义好的路线前进,使用时有时会发现:明明有看上去更直接的路线,却偏偏只能绕远路走折线;其次,对于起始点不在路点图中的情况,还需要找到最近的路点先移动过去;最后,路点不考虑实际的底层地图,所以在移动过程中有可能出现被物体阻挡卡住的情况。

导航网格(Navmesh)

这种方法使用一系列算法将原始地图转换成三角形网格的集合,网格和网格之间构成连通关系用于寻路。在计算机中表示为顶点的集合,以及三个顶点索引一组(边)的集合。

导航网格的优点
  • 能精确地表征世界。虽然导航网格也做不到百分百还原真实地图,但是它无疑比格子和路点都更精确。首先,它引入了高度信息,使得表示3D地图成为可能;其次,它在应用agentRadiusagentHeight等参数时用到了体素(voxel)4,这是一种比格子更小的计量单元,使得计算可行走范围时更加精确。
  • 内存和计算开销小。导航网格将地图抽象成三角网格,也就是顶点和边的集合。理论上,这种建模方式的复杂度介于路点和格子之间。
导航网格的缺点
  • 复杂,难以实现和修改。自己从头实现一个导航网格系统无疑是非常复杂的,这需要很多几何算法的知识。好在现在有一些开源的实现,如crisis的引擎工程师实现的recast-navigation5。但如果想在它基础上去修改和定制,还是要花费不少功夫。
  • 建立网格的过程耗时耗内存。与格子和路点不同,前两者从原始地图建模的过程几乎是瞬间完成的,而建立导航网格则是一个相对复杂和耗时的过程,其中体素化这一步又会占用不少内存(完成后会释放掉)。好的网格导航实现可以将建网格和动态加入障碍的时间代价控制在几毫秒的级别。通常的程序实现会在第一次寻路前就寻找时机建好网格。

总结

每种建模方式都有自己的优点和缺点,应具体根据应用场景选择合适的方式。

如果开发时间有限,需要在可能动态变化的2D地图中寻路,地图不会太大,内存充足,且对行走区域的精确度没有太高要求,首选格子。

如果开发时间有限,寻路线路相对固定(典型的如塔防游戏),不用考虑真实地形的影响,优先考虑路点。

如果开发时间充裕,地图很大,对表征真实世界的精确度要求很高,那么最好选择导航网格。


  1. 本文写作过程中参考了《游戏人工智能》中的《选择一个寻路空间表征》一文。
  2. 游戏中的常用寻路算法参见文章
  3. 这里只针对寻路本身,不包括建模的过程,否则导航网格的开销会更大
  4. 参见我翻译的有关体素化的文章
  5. 参见我写的专栏:recast源码解析
  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 要实现一个3D寻路算法,首先需要明确3D空间的宽度、长度和高度,以及每个位置的可行性和障碍物的位置。然后,需要开发一个算法来确定从起点到终点的最佳路径,并考虑障碍物的位置。最后,可以使用优化算法来改进寻路结果,以实现更高效的路径规划。 ### 回答2: 实现一个3D寻路算法的关键是将三维空间转化为一个可以表示和处理的数据结构。下面是一个具体的步骤: 1. 创建一个三维网格:将整个三维空间划分为一系列小方块,形成一个三维网格。每个小方块称为一个网格单元,可以表示空地或障碍物。 2. 初始化起点和终点:在网格中确定起点和终点的位置。 3. 标记障碍物:将障碍物标记在网格中,即将对应网格单元设置为障碍物状态。 4. 实现搜索算法:根据所选的搜索算法,对网格进行搜索,找到从起点到终点的路径。 - 一种常见的算法是A*算法,它通过启发式函数评估每个可行解的选择,选择最优路径。 - 在搜索过程中,需要维护一个开放列表和一个关闭列表。开放列表存储待搜索的网格单元,关闭列表存储已经搜索过的网格单元。 - 搜索的过程中,通过计算启发式函数的值选择下一个待搜索的网格单元,直到找到终点或搜索完成。 5. 生成最优路径:根据搜索结果生成从起点到终点的最优路径。 - 通过回溯搜索过程中保存的每个网格单元的信息,从终点开始,依次找到每个前驱网格单元,直到回溯到起点。 - 将这些网格单元连接起来,即可得到最优路径。 6. 优化路径:考虑到实际应用中可能存在限制条件和需求,可以对生成的路径进行优化。 - 可以通过路径平滑算法,比如B样条曲线平滑,去除路径中过多的拐弯。 - 也可以结合地形或其他因素进行路径规划,选择更适合的路径。 以上是一种基本的3D寻路算法实现思路,具体实现时还需要考虑算法的效率和可扩展性,以及合理的数据结构和算法优化策略。 ### 回答3: 要实现一个3D寻路算法,可以按照以下步骤进行: 1. 环境建模:首先需要将3D环境进行建模,包括地图、障碍物、起点和终点等。可以使用图形学相关的库或工具来实现环境的建模,例如OpenGL、Unity等。 2. 寻路算法选择:根据需求选择适合的寻路算法,常用的有A*算法、Dijkstra算法、Floyd-Warshall算法等。选择合适的算法需要考虑运行效率和路径质量等因素。 3. 路径搜索:根据选择的寻路算法,在建模的环境中进行路径搜索。首先根据起点和终点的位置确定搜索起点和搜索终点,并初始化相应的数据结构。然后按照算法的规则逐步搜索,直到找到最优路径或无法找到路径为止。 4. 障碍物处理:在搜索过程中需要考虑障碍物的影响。可以使用碰撞检测算法来判断路径是否与障碍物相交,如果相交则需要调整搜索路径或选择其他路径。 5. 优化处理:为了提高实时性能和路径质量,可以对算法进行优化处理。例如,可以使用空间分割技术将大规模地图分割成小块,只对需要搜索的区域进行路径搜索,减少计算量;可以使用距离估算方法加速搜索过程等。 6. 路径结果展示:最后,将得到的路径结果进行展示。可以使用图形渲染技术将路径在3D环境中可视化展示,让用户可以直观地看到路径。 综上所述,要实现一个3D寻路算法需要进行环境建模、选择合适的寻路算法、路径搜索、障碍物处理、优化处理和路径结果展示等步骤。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值