Unity3d之A*算法在游戏中的应用(一)

A-   star算法在游戏寻路中的应用和优化

摘要

 在即时战略游戏(简称RTS)中,玩家可以用鼠标选定一组单元,然后单击地图上某个位置,或者某个要攻击的敌人,这时寻路模块便会为这组单元找到一条能够避开障碍物的路径,让这组单元能够通过这条路径到达指定位置。这个功能就是路径规划,也称之为“寻路”。

 本文先介绍A*寻路的基本算法,然后通过示例一步步观察A*寻路是如何工作的。在了解了算法原理后,我从最小运行时间和运行效率两方面对算法进行了优化,结果证明优化后的A*算法具有更快的运行速度。

关键词:游戏寻路   A*算法      优化

 

 

 

 

 

 

 

1.     绪论

A*寻路方式通常有三种:基于单元的导航图、基于可视点导航图和导航网格。

1.1基本术语

地图:“地图”是一个空间,也可以称为“图”,它定义了场景中相互连接的可行区域,形成一个可行走网络,A*在这个空间内寻找两个点之间的路径。

目标估计:是指在寻路过程中估算代价的方法。通过采用不同的目标估计方法,可以实现更为智能、有趣的AI角色。

代价:在寻路过程中,有许多影响因素,例如时间,能量,金钱、地形、距离等。对于起始节点和目标节点之间的每一条可行路径,都可以用代价的大小来描述。

节点:节点与地图上的位置相对应,可以用它来记录搜索进度。节点中存放了A*算法的关键信息,首先,节点的位置信息是不可少的,除此之外,每个节点还记录了这条路径的上一个节点,即它的父节点,这样在达到目标节点后,可以通过反向回溯确定最终路径。另外,每个节点还有三个重要的属性值,分别是g、h、f。

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

h:从当前节点到目标节点的估计代价。

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

导航图:要进行寻路,首先需要将游戏环境用一个图表示出来,这个图就称为导航图。导航图可以有多种形式,这里将介绍其中最重要的三种,即基于单元的导航图、可视点导航图和导航网格。它们各有特点,应用时,需要根据实际情况进行选择。

2.     数学模型

为了更好地理解A*寻路算法法,我们来看一个实例。图1可以看做一个基于单元的导航图,其中白色方格表示可行走区域,黑色方格含有障碍物,是不可行走区域。节点存储了每个可行走方格的中心位置以及相关的寻路数据。

如果用方格所在的行和列来表示位置,则左上角坐标为(1,A),起点为(4,C),终点为(2,I)。


图1 A*寻路示意图

这里应用A*算法找出起始位置与目标位置之间的最短路径,并且避开障碍物。首先,它会从起始节点开始,逐步扩散到相邻节点,直到抵达目标位置所在节点,或因无法找到可达路径而终止。

开始搜索前,需要记录待考察的节点,将这些记录在一个表中,称为Open表。最初的Open表只有一个节点,就是起始节点。

除了Open表,还需要一个Closed表,来记录已经被考察过,不需要再做考察的那些节点。起初这个表为空。在寻路过程中,每当每个节点的相邻节点都已经检查过,就会将这个节点加入Closed表中。

2.1        A*算法执行步骤

 

 


 

Unity3d之A*算法在游戏中的应用(一)_第1张图片 


Step1:取出Open表中当前代价最小的节点(4,C),检查它的8个相邻节点,看它们是否能够行走,由于它们都时可行走的,因此,将这8个节点都加入Open表,如图2所示。

图2.A*算法第一步

因此,这一步执行的结果是将8个新节点加入Open表中,而起始节点从Open表中移除,加入Closed表中。

Step2:接下来,开始第二轮循环,这需要从Open表中选出新的节点进行检查。首先我们需要计算这8个节点的行走代价。

g:从起点到当前节点的欧氏距离。

h:从当前起点到目标节点的曼哈顿距离。

f=g+h:从起始位置到该位置,再从该位置到目标节点的估算距离。

如图2所示,(3,C)是当前代价最小的节点,我们选中(2,C)。计算其相邻节点代价:


图3.A*算法第二步

将节点(2,C)放入Closed表中,更新节点信息。

重复以上步骤,直到找到目标节点。

 

2.2        A*算法优化

从上面计算过程中可以发现,从起点到终点只需经过8个节点,而A*算法却需要搜索33个节点,这浪费了大量的时间,而且占用了很多内存,我们需要对算法进行优化。

分层寻路是一种比较有效的优化A*算法的方法。其基本思想是把二维地图按不同的复杂层次来划分,如图4所示。图中有4个屋子,标号为1、2、3、4,屋子之间有门,如虚线所示。假设要从1号屋子里的起始点走到3号屋子的目的地,首先可以把地图分为两层:第一层只包括屋子和屋子之间的关系(门),不考虑屋子里的细节,这层最简单,第二层是屋子内部的细节,比如桌椅等,这层比较复杂,所以采取的步骤为:

(1)对各个屋子之间整体使用A*算法,找到屋子1到屋子3的路径为1-2-4-3;

(2)在2号4号屋子之间设定中间目的地“子目的地1”,对1号和2号屋子内部细节使用A*算法,找到从起始点到“子目的地1”之间的路径;

(3)让游戏角色走到2号屋子门外。

(4)再确定中间目的地“子目的地2”,以此类推。

3.算法仿真

上一节已经构建出A*寻路算法的数学模型,并讨论了优化方法,现在我们需要在游戏中对A*算法进行仿真。考虑10x10m2的二维平面区域,如图5,图中白色区域是障碍物,我们需要用A*算法让游戏角色通过这些障碍物。


图5.A*仿真区域图

在场景中添加一个游戏角色如下图(黄色的是角色,红色的是目的地),可以看到,运行游戏后,角色准确的找到了路径(绿色的线)。


图6.A*算法仿真结果

 

4.总结

本文讨论了A*算法在游戏寻路中的应用与优化,并给出了具体的仿真实例。A*算法是游戏人工智能领域最为常用的算法之一,A*算法在效率与寻路准确性方面性能都不错,本文针对经典A*算法进行了进一步优化,使其性能有了一定提升。通过这篇论文,我对游戏领域有了进一步认识,希望有后能成为优秀的游戏程序员。

 

 

你可能感兴趣的:(unity3d菜鸟笔记)