【高级AI】用Unity实现一群鸟
项目难度:★★★★ (文章结尾有工程地址)大多数人都喜欢欣赏漂亮的动物,猫、狗、鸟、鱼、虫等等很多。其中最特别的要数鸟和鱼了,因为它们不仅可以单独欣赏,还可以观赏鸟群飞翔、鱼群集体游动的壮观景象。
游戏世界里,模拟鸟群也是开发者们梦寐以求的效果。我们希望能模拟出一个栩栩如生的鸟群,同时还能让它们按照我们的需要向着目标点移动、或者在某个地方盘旋。这篇文章将演示如何制作一个漂亮的鸟群。
一、理论基础:
鸟群本质是由一只一只的鸟组成的,每个鸟是独立行动的,只能通过视觉、听觉与外界进行有限的交互,然后做出合理的行为。有个专有名词“自主主体(Autonomous Agent)”专门描述这种自主行为的个体。虽然个体是自发行动的,但是通过遵守某些简单的规则,就可以满足群体的集体目标,比如:不发生碰撞、顺利到达目的地,或是一起在附近周旋觅食。
顺着这种思路,我们就知道了要模拟鸟群,要从每一只具体的鸟入手。让每一只鸟遵循同样的规则来实现群体效果。那么,这种规则的设计就成为了关键问题。首先,集群的模拟分为三个层次:
行为选择Action Selection: 最高层。是移动还是盘旋还是躲避敌人呢?我们要确定整体目标以及个体目标。整体目标和个体目标可以是不完全一致的,比如整体目标是移动,个体在发现敌人时要优先进行规避。引导Steering: 中间层。群体中个体的移动和单独个体的移动当然不一样。群体中的个体要考虑的问题多很多,他总是在判断离周围的人是否太近容易碰到?是否太远脱离了队伍?是否和大家的方向一致?是否要同时躲避敌人的攻击?每个时刻,所有的因素互相影响作用,最终得出一个引导的方向和大小。行动Locomotion: 最底层。把引导化为实际行动。在本例中,我们是利用刚体+力这种基本的物理方法来模拟的,引导是一种力,调整行动的速度。
二、搭建Unity工程
1. 新建Unity 3D工程,将Assets Store下载的《Animals Full Pack -- Birds Pack》导入到工程中以便使用。
2. 在鸟的资源的Prefab里面找一种你喜欢的鸟,我选的是海鸥。将它拷贝到Assets目录里准备使用。动画默认是用Animation组件实现的,将它的默认动作调整为fly,还需要添加Rigidbody刚体组件才能使用力Force,参数默认即可:
3. 实现Bird脚本,是本文的主要内容,下面会详解。
三、写代码实现Bird脚本,控制每一只鸟的行为
本文对初学者来说比较有难度。建议从基本行为开始慢慢尝试,我自己写的时候也尝试了很多基本的飞行方式,最终解决了多重问题,最终才得到不错的结果。飞行方式有以下几种:
要实现集群效果,Seek、Flocking这两种行为是最必要的,其它行为可以参考工程代码和其他资料。基本数据和初始化如:
a. Seek方式
Seek的方式是最基本的,它返回一个力(向量),引导鸟飞向目标:
向量运算自行画图分析,我就不啰嗦了。这个力如何使用呢?只需要在Update的每一桢调用Seek,每一桢算一次Steering引导力即可。
然后让引导力生效即可:
第一步很简单吧?接下来看终点Flocking方式。
b. Flocking
Flocking的原理不像Seek那么直观,必须参考一些资料。总的来说,集群中的鸟:需要考虑三个基本问题,分散、统一方向、聚合:
上图摘自游戏AI的经典书籍《Programming Game AI By Example》。如图,简单来说,只看Separation分散和Cohesion聚合,你会发现其实它俩就像弹簧一样,聚合负责压紧弹簧,分散负责弹开弹簧。当离得太近,弹力就比压力大了,当离得太远,压力又比弹力大。只要合理调整这两个力的大小,就能实现一个大小合适、密度合适的群体。
而Alignment保证大家尽可能朝向一个方向。
Flocking函数全貌如下图,可以看出每一只鸟在决定自己行为之前,要先观察所有周围的鸟,这是通过把周围的鸟加入临时容器实现的。后面的Separation、Alignment、Cohesion要用到这个容器。
分散力,思路是远离所有周围的人:
聚合力,思路是尽量飞向群体的“质心”:
统一方向力,思路是只看别人的速度方向,不看大小。然后向该方向移动:
Seek和Flocking原理完成啦!只要同时应用Flocking和Seek两种力,就能实现基本的集群效果。
四、关键性调整
如果只做上面的步骤,然后简单限制一下速度,你会发现效果是这样的:
动画太一致不算什么问题,关键是鸟在原地悬停这个不能忍,又不是飞碟……所以还要做一些关键内容:
1、最关键的是,鸟是不会倒车的,鸟和飞机是靠转弯再转弯来实现掉头。所以,我们将引导力的向后的分量完全取消:
2、引导力有时会剧烈变化方向,但鸟指向的角度不要迅速变化,那样会非常假,平滑处理一下:
3、限制最大速度:
4、根据引导力的大小来控制扇动翅膀的速度,非常科学:
以上用到的参数都是猜想+试验得出的,其原理值得大家思考。再看看最终效果:
五、还未结束
以上修改,已经达到了本文演示的目的,而且效果个人觉得还挺好看的,体现了鸟类集群飞行的美感。如果你的游戏中需要用到鸟群作为装饰,稍微优化一下算法也基本够用了。
但是深究的话,余下的问题还有很多,值得思考:
1、当引导力指向后方,我们直接去掉引导力的向后分量,会导致出现很大的转弯半径,作为演示来说挺炫酷,但是不符合实际,思考飞机转弯的例子,如果能模拟鸟类急转弯,就会更好看了。
2、动画方面,鸟类会综合使用扑翼、滑翔、爬升等动作,应当根据实际调整。我们目前只实现了调整动画速度,很不完美。
相信解决了以上两个问题,鸟群的模拟效果还能再上一层楼,也更符合实际。小问题总是需要花大力气解决,魔鬼总在细节之中~~
GitHub工程地址:
mayao11/GameAIAdvanced
参考书籍:
Programming Game AI By Example, by Mat Buckland.译名:《游戏人工智能编程案例精粹》
对游戏开发感兴趣的同学,欢迎围观我们:【皮皮关】 ,会定期更新各种教程干货,更有别具一格的线下小班教育。
我们的官网地址:http://levelpp.com/
我们的游戏开发技术交流群:610475807
我们的微信公众号:皮皮关
页:
[1]