本文发表于程序员刘宇的个人博客,转载请注明来源,博客园同步更新:https://www.cnblogs.com/xiaohutu/p/10504586.html
某个神秘的时间,我接到了一项神秘的任务,最核心的难度是要求实现:引擎是Unity3D,在手机端可以流畅运行为前提,在一个实时战斗的过程里,地图有地形(而且是会被动态改变的地形),数百个单位独立AI寻路、要实现忽略掉部分单位的筛选寻路、动态避障、满足帧同步需求并可以被服务器验证。可以说这个需求是集合了各种难点于一身。在这个任务的过程里,发现网上这样的文章比较少,所以想总结分享一下。着重于算法和思路这一块,不涉及图形上的问题。
一. 通常怎么做
需要寻路,又需要避障,先说一些常规的解决思路:
1.1 寻路
寻路就是基于既有的数据寻找到符合条件的一条路线:
1. 拿来主义类:用unity3d自己的NavMesh、自己的A* project,包含了寻路数据的生成和计算。
2. 进阶类:格子寻路可以用:
自己写A* 算法,进行常见的优化(二叉堆优化、HOT优化等等等等), 分层A*
JPS以及各种优化(位运算,剪枝,预处理等)
Dijkstra(扩展Dynamic A*)
DFS, BFS
。。。
(后续开文详解)
1.2 避障部分
合理的通过改变自己的行为(速度,方向)来避免穿插:
0. 真实物理
1. 在引擎里使用射线判定是否碰撞,并等待/重新寻路(耗时)
2. 根据距离判断是否碰撞,并等待/重新寻路,最简单的是直接用距离计算(耗时)
3. 在2的基础上使用算法优化距离判断,减少计算量,一般来说可以:
3.1 九宫格,分区查找计算目标
3.2 根据需求四叉树/八叉树来对目标列表进行分区分块,提高查询的速度
3.3 十字链表来存储格子对应的单位,提高查询速度
3.4 双向链表的视野管理思路
4. 其他思路:
4.1 Steer类、使用作用力思路计算
4.2 VO、RVO、ORCA等避障算法、通过速度与距离整体计算