unity中寻路方案的讨论

A * 算法

基本的原理

详解
全方位分析
c++实现

A* 算法不是最短路径算法,它找到的路径并不是最短的,它的目标是以最快的速度找到通往目的地的路,它的时间复杂度为O(NlogN)
A* 算法使用的是一种局部最优的策略,它的下一步的选择点,是距离目的地最短的点。以二维数组为例,s点, 取出它周围的8个点(可行走点),然后加入到open_list,然后对队列排序,找到距离最近的点,这个点就是下一个点k, 并将k加入到close_list,然后再取k的周围的没有标记的点,加入到未标记队列中,再对队列排序,直到到达目的地。
它只关注当前最优 的,可能会走弯路。

在排序时的依据,就是点的总代价
F = G + H
F理解为通过这个点的总代价,代价越低,这个就当然更有可能在最短路径上。 G是从起点到这个点的代价, H是从这个点到终点的代价
G的计算,可以通过它的父节点的G来计算
H的计算,只能用估算,有多种算法,可以使用曼哈顿距离, 值计算当前方格横向或纵向移动到达目的所经过的方格数,忽略对角移动,然后总数乘以10 ,并且在统计过程中,忽略障碍物, 是一种估计值。

从open_list中选择F值最小的节点,然后把它从open_list中移除,加入到close_list 。然后检查所有与他相邻的方格,忽略close_list中的,不可行走的, 如果不在open_list中,就把当前方格设置为它的父亲,并记录该方格的F,G, H值。如果邻近节点已经在open_list中, 就要检查经由当前节点到达它那里是否更好,以G来为参考,如果G更小,说明从当前节点过去是更好的路径,就把它的父节点设置为当前方格,并重新计算它的G和F。
这种父子关系,最后用来连接路径。
注意,每次循环查找到下一个路径点,并不一定就是最终的路径点,因为,后面会对节点进行优化,修改父子关系。

直到, 终点加入到open_lsit中,此时路径已经找到了,或者查找终点失败, 并且open_list为空,此时没有路径。
从终点开始,每个方格沿着父节点移动直到起点,就是查找的路径。

A * 算法优化

在地图很大时, 使用A星算法,寻路频率很高,普通的A星算法,消耗大量的CPU计算。
1.对排序算法优化,当距离很远, 未标记队列会越来越大, 排序的时间也会越来越长。由于在插入新的点前,队列是有序的,考虑使用插入排序,而不是每次都使用快排,可以用二分查找,插入。

寻路网格构建

A* 算法只是算法,需要配套的模块来支持, 最重要的就是寻路网格的构建,还有动态障碍物,地图和地形支持,再配上寻路算法,才会形成最终的地图和寻路。

  1. 最简单的就是二维数组构建的方形网格
    将地图与二维数组对应,进行地图的切割。这样就用A星的寻路在数组中结果对应到地图上。但是当地图很大时, 数组如果太小,无法实现细腻的碰撞体;如果数组太大, 就造成内存的消耗。这放方式在2D游戏,或者是横版游戏时,还是可以使用,毕竟比较单一。

  2. 多边形网格的构建-NavMesh。
    能够大大改善寻路的效率。
    它的本质就是三角形网格生成算法+多边形之间的合批和裁切算法+A*
    三角形生成:切耳算法
    网格构建完毕后,需要将A* 与网格数据结合
    A星的特点,必须由邻近的节点可获取,并且邻近的节点与目的地的可以有距离比较。
    在平面三角形网格中,要从一个点到另一个点,则可以使用三角形的邻近三角形来计算路径,与目的地的距离可以用点与点之间的距离来计算。
    知道了路径上需要经过哪些三角形,那么问题来了, 行走的路径是根据点来判断的,三角形怎么定点,三角形的大小不一,如果定位到中心点,行走就很怪异。所以引入了拐点路径算法来优化寻路后的路径。

Flow Field PathFinding 算法

参考
v社提出的场寻路算法 ,针对RTS游戏,多个战斗单位
基于Dijkstra算法
简单介绍

基本方案介绍:

A * Pathfinding Project

下载
也可以从Assetstore下载直接导入到工程,是在A* 算法基础上进行改善的寻路插件
简单教程
有人说它的碰撞有问题 ,待考证
基于网格的是免费的。
自动生成navmesh的工具,只有pro版本有。
不过可以使用其他方法生成navmesh, 然后再利用它的寻路系统,白嫖

路点寻路

预先设置好路径点坐标几何,然后对象按照规定的坐标几何运动。
用于塔防怪物行进路径,鱼群游动路径,AI的巡逻路径等,实现起来也最简单方便,不需要计算量。
但是在MMO中,由于任务太多,如果预先设置,工作量太大了,而且每次调整都是很大的工作量。

Unity自带的Navigation

前面说了,它是将地图转换为三角形网格的集合,网格和网格之间构成连通关系用于寻路。
1.Navmesh寻路快,但不够精确。
2. 不开源,导致游戏服务器无法使用,无法和客户端保持一致的导航寻路逻辑。
3.有人说,在多人寻路时,存在挤压问题。说navigation没有把其他人当作 障碍物,遇到其他人会因为碰撞而减速,变方向。?
4.不适合在帧同步中使用,因为需要确保每个客户端的计算结构都一致。
5.不能动态加载Navmesh, 不能动态的替换和修改navmesh,比如动态的遮挡。

有的项目使用A* pathfinding pro(收费) + Navmesh
1.主体寻路方案使用A * 插件中的传统的网格形式,并进行深度修改扩展。
2.使用navmesh系统作为寻路过程中的碰撞系统,它自带碰撞算法,使用rvo算法,用来实现局部的碰撞规避。
参考uwa

Recast Navigation

客户端和服务器都可以使用 ,自带生成navmesh的方法,而且是开源的,可以学习其中的原理
寻路的核心算法,也还是A*算法。

讨论

在以前的moba中,使用A* Pathfinding pro, 碰撞是自己实现的。王者荣耀好像也是用的这个插件。

MMO中使用Recast Navigation, 用c++编写,可以给服务器使用来寻路,它是untiy的自带navigation的前生。
不过Recast Navigation本身也有一些限制,在后续的文章中会简单介绍。
还可以编译成库,给客户端使用。
它提供的工具可以用来生成navmesh, 或者使用untiy来bake出navmesh,然后导出为recast识别的obj, 在reecast中再生成navmesh。

在横版游戏中,由于地图简单,就是长方形,直接用一个网格生成工具,根据layer,来生成二维数组,标记处碰撞物体,然后保存为二进制文件;给服务器来判断,并且可以动态的修改,比如一些机关,空气墙。客户端本地将二维数组序列化到地图中,这样可以动态判断,某个坐标点是否是可行走的,用来做随机掉落点的计算。

当然可以自己实现一套,实现A* 算法,再结合自己的项目特性。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值