unity-AI设计理念和编程思想(三)

    前两个模块大致讲了讲AI角色的感知和自主决策,决策之后呢?当然就要开始行动了。比如AI角色发现一个目标,并决定去攻击它,但它与目标之间可能还有一段距离,AI角色需要先到达目标点,这就需要AI角色自主寻路了,还有玩家点击地图上的某点,寻路模块需要找到一个最佳路线赶过去。最常用的便是A*寻路了,当然unity自带的Navmesh导航网络也是基于此算法。

    A*寻路常用术语:

    地图:它是一个空间,定义了场景中相互连接的可行走区域。A*在这个空间内寻找两个点之间的路径。

    目标估计:寻路过程中估算代价,显得更智能。

    代价:寻路过程中,可能有很多影响因素,包括时间、地形、距离等等,它们都会有不同的代价,我们要做的是寻找到一条代价最小的路径。

    节点:节点与地图上的位置相对应,用来记录搜索进度。它存放的有当前节点的位置信息,还有父节点(上一个节点)。每个节点有三个属性值,分别是g,h,f。

        g: 起始节点到当前节点的代价

        h:从当前节点到目标节点的估计代价(不考虑障碍物)。

        f:是经过当前节点这条路径代价的最好估计值,f值越小路径越好。f=g+h

    导航图:要进行寻路,需要将游戏环境用一个图表示出来,最重要的有三种格式:基于单元的导航图、可视点导航图、导航网络。

三种导航图的建立以及优缺点:

    基于单元的导航图:将游戏地图划分为多个正方形单元或六边形单元组成的规格网络,网格点或网格中心点可以看作节点。    

        优势:结构简单,易于动态更新,动态增加建筑物或障碍物,所以常用在塔防游戏等频繁更新场景的游戏中。

        缺点:节点太多,消耗内存,RTS游戏寻路物体多时会消耗大量CPU,对于复杂地形效果不佳。

    创建可视点导航图:场景设计者在场景中放置一些路径点,如果两点之间没有障碍物,说明两点之间可以“看见”,可以用一条线段把两个点连接起来,生成边,很多这样的边就可以组成导航网络。

        优势:灵活,场景设计者可以精心选择,对于复杂地形会有比较好的效果。

        缺点:场景很大时,手工放置工作量大且易出错;由于AI角色是沿着“边”走,可能不是最佳路线,会走“Z"字形路线。而且如果路径点之间是悬崖时,它可能会跌落悬崖。

    导航网络:它将游戏场景可行走区域划分为凸多边形,每个凸多边形代表一个节点,代价可以把多边形的质心之间的线段长度。

    优势:可以进行精确的点到点的移动,由于凸多边形面积可以任意大,所以占用的内存小,搜索速度很快。

    缺点:生成导航网络(烘培)时间较长,特别是地形复杂且多的地图。虽然unity添加了动态避障的功能,但每次都得重新烘培一次,所以多用于静态场景中。

————————————————————————————————————————————————————

   A*寻路算法是如何工作的?

    A*算法使用两个状态表来存储不同的节点,分别是Open表,由待考察的节点组成。Closed表由已经考察过的节点(算法检查过与它相邻的所有节点,计算出它们之间的f,g,h值,并放入Open表中待考察)组成。 开始时,Closed表为空,Open表只包括起始节点。每次迭代中,将Open表中代价最小的点取出来检查,如果不是目标节点,那么考虑该节点的相邻节点,对相邻节点做如下处理:

    1. 不在Open表和Closed表中,则加入Open表中。

    2. 已经在Open表中,且新路径具有更低代价,更新它的信息。

    3. 在closed表中,检查新路径是否有更低的代价,是的话将其加入Open表中,否则忽略。

重复上述步骤,直到达到目标点,如果到达目标点之前,open表已经变空,说明没有可达路径。

A*算法实现战术寻路:

    很多时候,最短路径并不是最好的选择,一些情况下,我们希望AI角色更聪明灵活,需要用到战术寻路。怎么实现呢?我们需要给一些区域赋予不同的代价值,比如高危区域代价加100,普通危险区域代价加50,安全区域代价不变。A*就会尽量避免这些高代价区域。

A* Pathfinding Project插件:大佬贡献的插件,可以修改代码,当你彷徨无措是总会有大佬把饭端到你嘴边。感谢!这里不多介绍这个插件了。

猜你喜欢

转载自blog.csdn.net/scopperil/article/details/80428929