【高級AI】用Unity實現一群鳥

項目難度: (文章結尾有工程地址)

大多數人都喜歡欣賞漂亮的動物,貓、狗、鳥、魚、蟲等等很多。其中最特別的要數鳥和魚了,因為它們不僅可以單獨欣賞,還可以觀賞鳥群飛翔、魚群集體遊動的壯觀景象。

遊戲世界裡,模擬鳥群也是開發者們夢寐以求的效果。我們希望能模擬出一個栩栩如生的鳥群,同時還能讓它們按照我們的需要向著目標點移動、或者在某個地方盤旋。這篇文章將演示如何製作一個漂亮的鳥群。

一、理論基礎:

  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,參數默認即可:

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. 譯名:《遊戲人工智慧編程案例精粹》


對遊戲開發感興趣的同學,歡迎圍觀我們:【皮皮關】 ,會定期更新各種教程乾貨,更有別具一格的線下小班教育。

我們的官網地址:levelpp.com/

我們的遊戲開發技術交流群:610475807

我們的微信公眾號:皮皮關

推薦閱讀:

人工智慧進擊之路 | 品途創投深度
華為mate10的AI具體有哪些實際應用?
除了深度學習,你需要知道AI技術的23個方向 | 機器之心首份技術報告
睡前消息【18-01-19】比狠 比下限
如何看待剛發布的中文版Bixby?

TAG:Unity游戏引擎 | 游戏 | AI技术 |