基于NavMesh寻路、漏斗寻路、RVO动态避障自创的服务器大规模寻路+动态避障算法的实现

一、描述
        TW项目是一个拥有较广阔野外空间的SLG游戏,玩家的军队方阵可以在野外进行长距离行军、短距离自由行军、占领要塞、驻扎、形成战斗阵型战斗等行为。其中,野外的山脉、河流等会产生静态阻挡;而由玩家迁城、把守要塞、驻扎等行为,会在野外地图上产生动态阻挡。
        每个服务器活跃军队方阵目标5万个,每天产生的长距离寻路请求可能达几十万或者百万个,并且都需要在服务器端计算,用常规的A*寻路、navmesh寻路、ROV避障算法计算量巨大,影响服务器效能。所以我们可以采用两种解决方案:第一是做一个寻路服务器;第二是选择优化算法。本文给出了第二种优化算法方案。

二、需求
1、长、短距离寻路
2、寻路校验(如果有前端寻路,那么后端需要校验)
3、动态避障
注:以上所有需求是2D寻路

三、寻路
1、首先用navmesh寻路算法作为第一步,为野外地图创建静态寻路面片;

2、然后用“小边剔除”、“凸多边形合并”的算法尽量合并面片(这样做可以使内存占用最小),如下图;

基于NavMesh寻路、漏斗寻路、RVO动态避障自创的服务器大规模寻路+动态避障算法的实现_第1张图片

左边的线段BC被剔除,用BE+CE取代。右侧HG、GJ线段被剔除,用HJ取代。

基于NavMesh寻路、漏斗寻路、RVO动态避障自创的服务器大规模寻路+动态避障算法的实现_第2张图片

KN线段被直接剔除,两个凸多边形合并


3、用漏斗寻路算法离线计算所有的面片到所有其他非相邻面片的最优路径,并记下途径面片索引、面片重心距离边的垂线的平均长度、路程距离、权重等参数,形成“路径数据”保持到文件(最优路径可以不止一条);
4、后端在计算寻路请求的时候,算法如下:
        4.1)起点终点在同一个面片内,直接返回;
        4.2)起点终点所在面片相邻(没有途经面片),直接返回;
        4.3)起点终点所在面片途径一个面片,并且有多个这样的最优路径,需要分别计算起点、终点到相邻面片交点的长度+途径面片重心距离边缘长度,选择最短的;
        4.4)起点终点所在面片途径一个面片,并且有多个这样的最优路径,需要分别计算起点、终点到相邻面片交点的长度,选择最短的;
5、后端校验,只需要看路径是否在“路径数据”即可。
6、前端收到后端穿来的路径后,只需要按“漏斗寻路”算法,在需要的时候进行计算即可。

四、避障

由于我们的障碍物是可能突然出现在前方的,我们并不能像ROV那样预先计算,选择一个另外路径,所以我们躲避障碍物的方式为:不会提前改变路径,而是到障碍物面前后才改变。

下图是RVO避障算法,蓝点方阵知道障碍物(红球)的存在,会与红球相撞的蓝点会提前改变路径

基于NavMesh寻路、漏斗寻路、RVO动态避障自创的服务器大规模寻路+动态避障算法的实现_第3张图片

下图是我们的动态避障算法,本来obj要从C点移动到K点,但是由于有障碍物的出现,于是到快与障碍物相撞的D点时转向,走D-E-F-H-K各点,到达目标点与障碍物包围圆切线位置时走直线奔向目标点

基于NavMesh寻路、漏斗寻路、RVO动态避障自创的服务器大规模寻路+动态避障算法的实现_第4张图片

此算法依赖于如下几点前提条件:

  1. 障碍物都可以被圆包围,不会无限大,按照圆(折线)躲避不会违和。
  2. 紧贴着障碍物的周围是可以走的,也就是障碍物不能连起来形成更大的障碍。

基于NavMesh寻路、漏斗寻路、RVO动态避障自创的服务器大规模寻路+动态避障算法的实现_第5张图片

本来要从N走到P点,结果走到O点时发现障碍物A。

1、将A的包围圆分成12份,每份30度。
2、由于已知A点位置,圆半径(基本都是固定半径),AB与AC夹角度数(30度),所以可知B,C,D,E,,,M等12个点的位置
3、由于绕开障碍物只需要绕最多90度,所以最多只需要走3个点。
4、当对象走到O点,发现障碍物时,首先计算A点在直线NP的位置,如果A点在直线下方,则从上面绕;相反如果A点在直线上方,则从下面绕
5、计算AO夹角如果小于AD角则走折线OD,其他以此类推
6、计算C点在直线DP的上方,则需要走折线DC
7、计算B点在直线CP的上方,则需要走折现CB
8、此时已经走了3个点了,可以直接走BP奔向目的地。如果不满3个点,则计算下一个点M在直线BP下方,则不需要走M了。

复杂度分析

  1. 当A已知时,由于包围圆的半径是固定值,所以B,,M点通过加减法就可以得到
  2. 接下来在计算一次AO夹角(两次浮点数乘法)
  3. 接下来最多计算3此点与直线的关系(每次是两次浮点数乘法)

五、总结
        寻路的算法有很多,各自应用在不同的场景。通过筛选了十几种不同的寻路算法后,本文参考、采用或者部分采用了其中4,5种,也将一些算法拆解只用其中一部分,然后还自创了一些寻路算法,自创部分是最大化的用空间换取时间,最终达到了后端的长距离行军粗路径寻路CPU消耗很低的优化效果,不需要增加新的硬件就可以支持服务器端大规模寻路。

你可能感兴趣的:(基于NavMesh寻路、漏斗寻路、RVO动态避障自创的服务器大规模寻路+动态避障算法的实现)