从零点五开始用Unity做半个2D战棋小游戏(十)
好久不见。
这是第27篇与游戏开发有关的文章。
| 写在最前
这次想要做一个简单且传统的战棋小游戏,大概的玩法是:在2D世界里创建一张由六边形地块组成的战斗地图,敌我双方在地图上轮流行动,并向对方发动攻击,先消灭掉所有敌人的一方将获得胜利。
预计将分为以下几篇(未完成前可能会调整...):
1、创建战场(已完成)
根据预定尺寸生成战场地图,并随机一些障碍物。
2、添加地图功能 (已完成)
实现战场格子点击反馈,地图导航及范围选定。
3、添加对战双方(已完成)
向战场中添加作战单位,作战单位轮流行动,可进行移动、攻击。
4、加入玩家控制(已完成)
玩家可控制一个战斗单位,手动选择移动目标及攻击单位。
5、添加常用的界面(已完成)
建立界面管理器,加入一些常用的界面。
6、添加常用的战场显示(已完成)
为战斗单位添加血条,加入伤害文字特效。
7、扩展作战单位(已完成)
丰富战斗元素,加入并实现手动释放不同类型的技能。
8、加入AI系统(上)(已完成)
建立超级简单的AI系统。
9、加入AI系统(中)(已完成)
调整AI系统的决策方式。
10、加入AI系统(下)
总结AI系统。
11、扩展战场地图
丰富战场地图,加入地形及道具等元素。
12、规范战斗配置
可以通过规范化的数据结构配置战场、职业、技能、道具等。
本次的主题是:总结AI系统。
项目使用的Unity版本为:Unity2018.3.0f2。
代码会上传至我的Github:https://github.com/elsong823/HalfSLG 中,有兴趣的同学请自取。
| 目标
在上一篇中,我对AI系统进行了重构,实现了一个简单的用数值配置影响决策的AI系统。
本篇,将简单介绍另一种AI系统的实现方式,并对近期三篇关于AI系统的文章做出总结。
| 一种新的AI系统
在设计AI系统之初,我拜托了好友Aillieo在工程中用另一种方法实现AI。
果然,他所采用的方法跟我的相比,有不小的差异,这也验证了鲁迅先生的一句话:
尽管大家的脑袋都差不多大,但所思所想却各不相同。
鲁迅先生的名言 (图源网络)
所以,本篇的上半部分,将会主要介绍Aillieo所设计的AI系统。
需要提前声明的是,由于时间原因,在工程中并没有实现这个AI的细节逻辑。
但是,虽然只是完成了基本结构,但仍可以对设计思路有一个较为清晰的认识。
| 系统的开始
一个连接了所有AI决策系统(Brain)的数据交换中心,是这个系统的基础。
这个数据交换中心负责向所有战斗单位广播战斗行为信息。
一个连接了所有AI大脑的数据交换中心
比如,当一个AI做出动作时,这个动作会通知到交换中心,并且广播给其他所有AI:这个家伙行动了!
| 信息的输入
当战斗数据从数据中心,被发送到某一个AI的Brain后,Brain会将信息进行处理为直接数据和间接数据。
战斗行为信息从数据中心传入Brain
直接数据是第一手的战场数据,包括战场上各个单位的位置、状态、生命值、攻击力等。
间接数据是根据策略的不同而去保存和监听的数据,如战场上造成伤害最高的单位,任意单位某个属性达到某个临界值,某个单位和自己的敌对程度等。
比如,当Brain接到了上面的行动信息后,首先会更新这个行动者移动后的位置(直接数据);接下来还会发现:咦,这不就是刚才揍过我的家伙么(间接数据)。
| 战斗状态及切换
每一个战斗单位同一时间只能存在一种状态,战斗状态直接影响了行动时的行为。
当Brain接到的战斗信息被分别处理为直接和间接数据后,它将考虑是否需要切换战斗状态。
比如,当上面的Brain发现他的敌人已经进入了自己的“攻击范围”,就会将自己的状态切换为“战斗状态”;当然,如果他本身就是战斗状态的话,那就不需要切换了。
| 行为树与信息的输出
其实,在每一个状态的背后,都对应了一个行为树,而真正做出决策、产生行为的家伙,是这个行为树上的节点。
Brain决策了一个战斗行为信息,并传给数据中心进行广播
比如,当轮到上面那个处在“攻击”状态的AI行动时,他行为树中“仇恨优先”节点,会将仇恨值最高的单位选择为目标单位,并向他发动攻击。
行为树是如今AI设计中较为常用的方法。由于它本身就是个十分庞大且复杂的话题,加之网上介绍它的资料又非常丰富,这里就不做过多的展开了。
| AI系统的总结
我以为,此前的使用数值配置驱动AI决策的系统,在描述一个AI的多种类型的行为时,是很吃力的。
比如,尝试让一个AI做出非战斗的行为判断:拾取道具、解除机关、与场景互动等,很难用数值来对不同类型的行为进行换算。
之所以可以在战斗里得到验证,是因为这里只是把它用在了对战斗行为的决策上,而且这个战斗行为本身也是很简单的。
而本篇介绍的状态机 + 行为树的系统,稍加扩展,便可以在除战斗以外的其他地方发挥作用,十分通用。
那么是否就说明数值配置驱动就一定没有意义呢?
我不这么认为。
我所理解的状态机、行为树,是尝试从人类解决问题的角度出发,将人在现实中处理问题的思考、行为过程梳理出来,并把这种流程化的结果编织成机器可以执行的逻辑,来进行行为的决策。而上篇的数值配置驱动的驱动方式,则是在决策具体一个或一系列问题时,对内因、外因共同作用产生结果的一个模拟,因此我认为两者是可以结合在一起使用的。
| 写在最后
最近事情太多,挤来挤去后,留给自己写东西的时间还是非常有限,导致这个总结拖的太久。久到提笔写时,居然都忘了之前的系统是怎么做的,上一篇又是怎么写的了...无奈只能通过翻看之前的文章进行回忆...
行文至此,还是要感叹一下自己对AI相关的内容知之甚少。实事求是的讲,在动手搭建系统之前,对网上的资料,特别是对已经很成熟的“状态机”、“行为树”设计,也只是停留在概念上知道(现在也差不多)。
当然,这是我秉性使然的结果;对于一些不了解、感兴趣、却已经有较为成熟体系或总结的知识,在学习时反而会故意回避;宁愿多花些时间,用自己的方式摸索,等到有了自己的一套思路后,再翻看“答案”,看看谁的更有意思(虽然每次都输)。虽然这是一种效率极低的学习方式,但是这种“游戏”带来的乐趣,我是十分享受的。
好了,AI系统篇就暂告一段落,下一篇将继续丰富游戏内容:加入地形及道具等元素。
愿不忘初心。
下回见。
非常感谢您能读到这里,详细的代码可以移步Github(https://github.com/elsong823/HalfSLG)下载。
文章会在我的公众号 偶尔学学Unity 中不定期更新,欢迎关注,谢谢。