游戲開發(fā)中怪物AI實現(xiàn)方案總結(jié)

前言

????????在游戲開發(fā)中實現(xiàn)怪物AI邏輯的主要技術(shù)有兩種:1、狀態(tài)機(jī)2、行為樹。 他們兩者的實現(xiàn)機(jī)制不一樣,其中狀態(tài)機(jī)是“事件”機(jī)制,行為樹是“輪詢”機(jī)制。在項目開發(fā)中可以根據(jù)具體情況合理的選擇兩者來處理AI編寫問題。

?????????這篇文章分兩個部分對游戲中的AI進(jìn)行講解,1、狀態(tài)機(jī),2、行為樹。

概述

????????開發(fā)游戲AI的目標(biāo)之一就是要找到一個簡單,可擴(kuò)展的編輯邏輯的方案,從而加速游戲開發(fā)的迭代速度。在“行為系統(tǒng)圖”中,行為系統(tǒng)(Behavior System)響應(yīng)游戲中的各種信息,進(jìn)行決策以挑選接下來將要執(zhí)行的行動并且監(jiān)控該行動的執(zhí)行。


????????知識模型(Knowledge Model)是對游戲世界中各種信息的抽象。

????????在行為系統(tǒng)中,有限狀態(tài)機(jī)(FSM,F(xiàn)initeState Machine)最為經(jīng)典,F(xiàn)SM模型的優(yōu)勢之一是簡單。但是FSMs需要用轉(zhuǎn)換(Transition)連接狀態(tài)(State),因此,狀態(tài)(State)失去了模塊性(Modularity)。


????????行為樹,英文是Behavior Tree,簡稱BT,是由行為節(jié)點組成的樹狀結(jié)構(gòu):


????????對于FSM,每個節(jié)點表示一個狀態(tài),而對于BT,每個節(jié)點表示一個行為。同樣是由節(jié)點連接而成,BT有什么優(yōu)勢呢?

????????在BT中,節(jié)點是有層次(Hierarchical)的,子節(jié)點由其父節(jié)點來控制。每個節(jié)點的執(zhí)行都有一個結(jié)果(成功Success,失敗Failure或運(yùn)行Running),該節(jié)點的執(zhí)行結(jié)果都由其父節(jié)點來管理,從而決定接下來做什么,父節(jié)點的類型決定了不同的控制類型。節(jié)點不需要維護(hù)向其他節(jié)點的轉(zhuǎn)換,節(jié)點的模塊性(Modularity)被大大增強(qiáng)了。實際上,在BT里,由于節(jié)點不再有轉(zhuǎn)換,它們不再是狀態(tài)(State),而是行為(Behavior)。



? ??????????????????????????????????????????????第一種-有限狀態(tài)機(jī)

1、有限狀態(tài)機(jī)(FSM)的實現(xiàn)方式有三種

????????1、面向過程的方式的if else

????????2 、用枚舉配合switch case語句。

????????3、用多態(tài)與虛函數(shù)(也就是狀態(tài)模式)

2、狀態(tài)模式的經(jīng)典定義:允許對象在當(dāng)內(nèi)部狀態(tài)改變是改變其行為,就好像對象改變了自己的類一樣。

3、狀態(tài)模式的實現(xiàn)分為三個要點:

????????1、為狀態(tài)定義一個接口

????????2、為每個狀態(tài)定義一個類

????????3、恰當(dāng)?shù)剡M(jìn)行狀態(tài)委托

4、通常來說,狀態(tài)模式中狀態(tài)對象的存放有兩種實現(xiàn)存放思路:

????????1、靜態(tài)狀態(tài)。初始化時把所有可能的狀態(tài)都new好,狀態(tài)切換時通過賦值改變當(dāng)前的狀態(tài)

? ????? 2、實例化狀態(tài)。每次切換狀態(tài)時動態(tài)new出新的狀態(tài)。


關(guān)于FSM的具體案例如下:

????????1、Unity的Mecanim動畫系統(tǒng)就是通過狀態(tài)模式來實現(xiàn)的


????????2、下圖是一個簡單的戰(zhàn)斗過程的狀態(tài)機(jī),如果用狀態(tài)模式實現(xiàn)他的攻擊邏輯就非常的方便,而且支持后期狀態(tài)的擴(kuò)展。

? ??????總結(jié):狀態(tài)模式暫時沒有找到好的開源框架,但是狀態(tài)模式不僅僅在AI方面使用,在游戲的框架中也被廣泛使用,比如:UI框架,游戲主邏輯狀態(tài)框架等等。

?????????????????????????????????????????????????第二種-行為樹

什么是行為樹

????????如果了解過狀態(tài)機(jī),會知道在行為樹之前,在實現(xiàn)AI用得比較多的技術(shù)是狀態(tài)機(jī),狀態(tài)機(jī)理解起來是比較簡單的,即一個狀態(tài)過渡到另一個狀態(tài),通過判斷將角色的狀態(tài)改變即可,如果學(xué)習(xí)過Unity的Mecanim動畫系統(tǒng),會更加直觀的理解。但是狀態(tài)機(jī)在狀態(tài)較多的情況下會使?fàn)顟B(tài)之間的切換變得異常繁瑣,同時狀態(tài)之間很難復(fù)用。在這種情況下,行為樹被發(fā)明出來,行為樹的優(yōu)點如下:

? ??????1、行為樹提供大量的流程控制方法,使得狀態(tài)之間的改變更加直觀;

? ??????2、整個游戲AI使用樹型結(jié)構(gòu),方便查看與編輯;

? ??????3、方便調(diào)試和代碼編寫;

? ??????4、更好的封裝性和模塊性,讓游戲邏輯更直觀,開發(fā)者不會被那些復(fù)雜的連線繞暈。

? ??????5、最重要的:行為樹方便制作編輯器,可以交由策劃人員使用;

行為樹的基本概念:

? ??????1、執(zhí)行每個節(jié)點都會有一個結(jié)果(成功,失敗或運(yùn)行)

? ??????2、子節(jié)點的執(zhí)行結(jié)果由其父節(jié)點控制和管理

? ??????3、返回運(yùn)行結(jié)果的節(jié)點被視作處于運(yùn)行狀態(tài),處于運(yùn)行狀態(tài)的節(jié)點將被持續(xù)執(zhí)行一直到其返回結(jié)束(成功或失?。T谄浣Y(jié)束前,其父節(jié)點不會把控制轉(zhuǎn)移到后續(xù)節(jié)點。

行為樹原理

????????行為樹是一種樹形結(jié)構(gòu),所以其可以分成3種節(jié)點類型:


? ??????1、紅色的節(jié)點:根節(jié)點,沒有父節(jié)點的節(jié)點;

? ??????2、藍(lán)色的節(jié)點:組合節(jié)點,有父節(jié)點和子節(jié)點的節(jié)點;

? ??????3、白色的節(jié)點:葉節(jié)點,沒有子節(jié)點的節(jié)點;

節(jié)點的返回

????????每個節(jié)點都會有一個返回值,可能出現(xiàn)的返回值有3個,如下:

? ??????1、運(yùn)行中:表示當(dāng)前節(jié)點還在運(yùn)行中,下一次調(diào)用行為樹時任然運(yùn)行當(dāng)前節(jié)點;

? ??????2、失敗:表示當(dāng)前節(jié)點運(yùn)行失?。?/p>

? ??????3、成功:表示當(dāng)前節(jié)點運(yùn)行成功;


下面我們來細(xì)說一下這幾個節(jié)點

根節(jié)點

????????行為樹的入口節(jié)點,可以是任意類型的節(jié)點;

組合節(jié)點

????????行為樹的組合節(jié)點是由下面幾種類型來組成的:

1、選擇節(jié)點/優(yōu)先選擇節(jié)點(Selector)

????????該節(jié)點會從左到右的依次執(zhí)行其子節(jié)點,只要子節(jié)點返回“失敗”,就繼續(xù)執(zhí)行后面的節(jié)點,直到有一個節(jié)點返回“運(yùn)行中”或“成功”時,會停止后續(xù)節(jié)點的運(yùn)行,并且向父節(jié)點返回“運(yùn)行中”或“成功”,如果所有子節(jié)點都返回“失敗”則向父節(jié)點返回“失敗”。

2、隨機(jī)選擇節(jié)點(Random Selector)

????????之前的選擇節(jié)點是有優(yōu)先級順序的,而隨機(jī)選擇節(jié)點的執(zhí)行順序是隨機(jī)的。但每個節(jié)點只會執(zhí)行一次,比如包含子節(jié)點:A、B、C、D、E;使用隨機(jī)選擇節(jié)點,執(zhí)行順序可能是:D、E、A、C、B或其他組合。其它規(guī)則同選擇節(jié)點一致。

3、順序節(jié)點(Sequence)

????????該節(jié)點會從左到右的依次執(zhí)行其子節(jié)點,只要子節(jié)點返回“成功”,就繼續(xù)執(zhí)行后面的節(jié)點,直到有一個節(jié)點返回“運(yùn)行中”或“失敗”時,會停止后續(xù)節(jié)點的運(yùn)行,并且向父節(jié)點返回“運(yùn)行中”或“失敗”,如果所有子節(jié)點都返回“成功”則向父節(jié)點返回“成功”。

4、修飾節(jié)點(Decorator)

????????修飾節(jié)點只包含一個子節(jié)點,用來以某種方式來改變這個子節(jié)點的行為。修飾節(jié)點的類型比較多,這里我們說一些比較常見的修飾節(jié)點:

1、Until Success和Until Failure

????????循環(huán)執(zhí)行子節(jié)點,直到返回“成功”或“失敗”為止。

????????比如Until Success在子節(jié)點返回“運(yùn)行中”和“失敗”時都會向父節(jié)點返回“運(yùn)行中”,返回“成功”時向父節(jié)點返回“成功”。

????????Until Failure在子節(jié)點返回“運(yùn)行中”和“成功”時都會向父節(jié)點返回“運(yùn)行中”,返回“失敗”時向父節(jié)點返回“成功”。

2、Limit

????????執(zhí)行子節(jié)點一定次數(shù)后強(qiáng)制返回“失敗”。當(dāng)子節(jié)點運(yùn)行指定次數(shù)后還沒有返回“失敗”則該節(jié)點向父節(jié)點返回失敗。

3、Timer

????????子節(jié)點不會立即執(zhí)行,而會在指定的時間到達(dá)后才開始執(zhí)行。

4、TimeLimit

????????指定子節(jié)點的最長運(yùn)行時間,如果子節(jié)點在指定時間到達(dá)后還在運(yùn)行則強(qiáng)制返回“失敗”。

5、Invert

????????對子節(jié)點的返回結(jié)果取“非”,即子節(jié)點返回“成功”則該節(jié)點返回“失敗”,子節(jié)點返回“失敗”則該節(jié)點返回成功。??????

5、并行節(jié)點(Parallel)

????????不同于選擇和順序節(jié)點依次執(zhí)行每個節(jié)點,并行節(jié)點是“同時”執(zhí)行所有的節(jié)點,然后根據(jù)所有節(jié)點的返回值判斷最終返回的結(jié)果。

????????這里的“同時”會迷惑住不少人,實際上,行為樹是運(yùn)行在單一線程上的,并不會在并行節(jié)點上開多個線程來進(jìn)行真正的同時執(zhí)行,那么“同時”的含義是什么?

????????我們知道選擇或順序節(jié)點會依次執(zhí)行所有的子節(jié)點,當(dāng)子節(jié)點返回“成功”或“失敗”后就會停止后續(xù)節(jié)點的執(zhí)行,而并行節(jié)點也會依次執(zhí)行所有的子節(jié)點,無論子節(jié)點返回“成功”或“失敗”都會繼續(xù)運(yùn)行后續(xù)節(jié)點,保證所有子節(jié)點都得到運(yùn)行后在根據(jù)每個子節(jié)點的返回值來確定最終的返回結(jié)果。

????????并行節(jié)點一般可以設(shè)定退出該節(jié)點的條件,比如:

????????1、當(dāng)全部節(jié)點都返回成功時退出;

????????2、當(dāng)某一個節(jié)點返回成功時退出;

????????3、當(dāng)全部節(jié)點都返回成功或失敗時退出;

????????4、當(dāng)某一個節(jié)點返回成功或失敗時退出;

????????5、當(dāng)全部節(jié)點都返回失敗時退出;

????????6、當(dāng)某一個節(jié)點返回失敗時退出;

葉節(jié)點

1、條件節(jié)點(Condition)

????????條件節(jié)點可以理解為一個if判斷語句,當(dāng)條件的測試結(jié)果為true時向父節(jié)點傳遞success,結(jié)果為false時向父節(jié)點傳遞failure;

????????該節(jié)點搭配一些組合節(jié)點可以完成各種判斷跳轉(zhuǎn),比如搭配順序節(jié)點,可以做出“是否看見敵人”->“向敵人開火”的AI;

2、行為節(jié)點(Action)

????????行為節(jié)點用來完成具體的操作,比如,移動到目標(biāo)點,執(zhí)行開火等代碼邏輯,多種情況下行為節(jié)點會返回running和success;行為節(jié)點也可能會使用多幀來完成;

子樹的復(fù)用

????????我們設(shè)計好的行為樹可以在其他樹中作為一顆子樹來進(jìn)行使用,最大可能的復(fù)用子樹可以減少開發(fā)量。

總結(jié):行為樹的框架,網(wǎng)上有比較好的案例,如騰訊開源的behaviac。

????????Github地址:https://github.com/Tencent/behaviac

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容