unity群聚AI(一群鸟)

2021-05-18  本文已影响0人  忆中异

项目难度:★★★★ (文章结尾有工程地址)

大多数人都喜欢欣赏漂亮的动物,猫、狗、鸟、鱼、虫等等很多。其中最特别的要数鸟和鱼了,因为它们不仅可以单独欣赏,还可以观赏鸟群飞翔、鱼群集体游动的壮观景象。

image image

游戏世界里,模拟鸟群也是开发者们梦寐以求的效果。我们希望能模拟出一个栩栩如生的鸟群,同时还能让它们按照我们的需要向着目标点移动、或者在某个地方盘旋。这篇文章将演示如何制作一个漂亮的鸟群。

image

一、理论基础:

  1. 鸟群本质是由一只一只的鸟组成的,每个鸟是独立行动的,只能通过视觉、听觉与外界进行有限的交互,然后做出合理的行为。有个专有名词“自主主体(Autonomous Agent)”专门描述这种自主行为的个体。
  2. 虽然个体是自发行动的,但是通过遵守某些简单的规则,就可以满足群体的集体目标,比如:不发生碰撞、顺利到达目的地,或是一起在附近周旋觅食。

顺着这种思路,我们就知道了要模拟鸟群,要从每一只具体的鸟入手。让每一只鸟遵循同样的规则来实现群体效果。那么,这种规则的设计就成为了关键问题。首先,集群的模拟分为三个层次:

  1. 行为选择 Action Selection: 最高层。是移动还是盘旋还是躲避敌人呢?我们要确定整体目标以及个体目标。整体目标和个体目标可以是不完全一致的,比如整体目标是移动,个体在发现敌人时要优先进行规避。
  2. 引导 Steering: 中间层。群体中个体的移动和单独个体的移动当然不一样。群体中的个体要考虑的问题多很多,他总是在判断离周围的人是否太近容易碰到?是否太远脱离了队伍?是否和大家的方向一致?是否要同时躲避敌人的攻击?每个时刻,所有的因素互相影响作用,最终得出一个引导的方向和大小。
  3. 行动 Locomotion: 最底层。把引导化为实际行动。在本例中,我们是利用刚体+力这种基本的物理方法来模拟的,引导是一种力,调整行动的速度。

二、搭建Unity工程

1. 新建Unity 3D工程,将Assets Store下载的《Animals Full Pack -- Birds Pack》导入到工程中以便使用。

2. 在鸟的资源的Prefab里面找一种你喜欢的鸟,我选的是海鸥。将它拷贝到Assets目录里准备使用。动画默认是用Animation组件实现的,将它的默认动作调整为fly,还需要添加Rigidbody刚体组件才能使用力Force,参数默认即可:

image image

3. 实现Bird脚本,是本文的主要内容,下面会详解。

三、写代码实现Bird脚本,控制每一只鸟的行为

本文对初学者来说比较有难度。建议从基本行为开始慢慢尝试,我自己写的时候也尝试了很多基本的飞行方式,最终解决了多重问题,最终才得到不错的结果。飞行方式有以下几种:

image

要实现集群效果,Seek、Flocking这两种行为是最必要的,其它行为可以参考工程代码和其他资料。基本数据和初始化如下:

image

a. Seek方式

Seek的方式是最基本的,它返回一个力(向量),引导鸟飞向目标:

image

向量运算自行画图分析,我就不啰嗦了。这个力如何使用呢?只需要在Update的每一桢调用Seek,每一桢算一次Steering引导力即可。

image

然后让引导力生效即可:

image

第一步很简单吧?接下来看终点Flocking方式。

b. Flocking

Flocking的原理不像Seek那么直观,必须参考一些资料。总的来说,集群中的鸟:需要考虑三个基本问题,分散、统一方向、聚合:

image

上图摘自游戏AI的经典书籍《Programming Game AI By Example》。如图,简单来说,只看Separation分散和Cohesion聚合,你会发现其实它俩就像弹簧一样,聚合负责压紧弹簧,分散负责弹开弹簧。当离得太近,弹力就比压力大了,当离得太远,压力又比弹力大。只要合理调整这两个力的大小,就能实现一个大小合适、密度合适的群体。

而Alignment保证大家尽可能朝向一个方向。

Flocking函数全貌如下图,可以看出每一只鸟在决定自己行为之前,要先观察所有周围的鸟,这是通过把周围的鸟加入临时容器实现的。后面的Separation、Alignment、Cohesion要用到这个容器。

image

分散力,思路是远离所有周围的人:

image

聚合力,思路是尽量飞向群体的“质心”:

image

统一方向力,思路是只看别人的速度方向,不看大小。然后向该方向移动:

image

Seek和Flocking原理完成啦!只要同时应用Flocking和Seek两种力,就能实现基本的集群效果。

image

四、关键性调整

如果只做上面的步骤,然后简单限制一下速度,你会发现效果是这样的:

image

动画太一致不算什么问题,关键是鸟在原地悬停这个不能忍,又不是飞碟……所以还要做一些关键内容:

1、最关键的是,鸟是不会倒车的,鸟和飞机是靠转弯再转弯来实现掉头。所以,我们将引导力的向后的分量完全取消:

image

2、引导力有时会剧烈变化方向,但鸟指向的角度不要迅速变化,那样会非常假,平滑处理一下:

image

3、限制最大速度:

image

4、根据引导力的大小来控制扇动翅膀的速度,非常科学:

image

以上用到的参数都是猜想+试验得出的,其原理值得大家思考。再看看最终效果:

image

五、还未结束

以上修改,已经达到了本文演示的目的,而且效果个人觉得还挺好看的,体现了鸟类集群飞行的美感。如果你的游戏中需要用到鸟群作为装饰,稍微优化一下算法也基本够用了。

但是深究的话,余下的问题还有很多,值得思考:

1、当引导力指向后方,我们直接去掉引导力的向后分量,会导致出现很大的转弯半径,作为演示来说挺炫酷,但是不符合实际,思考飞机转弯的例子,如果能模拟鸟类急转弯,就会更好看了。

image

2、动画方面,鸟类会综合使用扑翼、滑翔、爬升等动作,应当根据实际调整。我们目前只实现了调整动画速度,很不完美。

相信解决了以上两个问题,鸟群的模拟效果还能再上一层楼,也更符合实际。小问题总是需要花大力气解决,魔鬼总在细节之中~~

GitHub工程地址:

mayao11/GameAIAdvanced

转载于:https://zhuanlan.zhihu.com/p/30909344

上一篇 下一篇

猜你喜欢

热点阅读