1. 程式人生 > >使用行為樹(Behavior Tree)實現遊戲AI

使用行為樹(Behavior Tree)實現遊戲AI

方便 不同 sequence 理解 and while 記錄 策略 積累

談到遊戲AI,很明顯智能體擁有的知識條目越多,便顯得更智能,但維護
龐大數量的知識條目是個噩夢:使用有限狀態機(FSM),分層有限狀態機(HFSM),
決策樹(Decision Tree)來實現遊戲AI總有那麽些不順意。

試試Next-Gen AI的行為樹(Behavior Tree)吧。

雖說Next-Gen AI,但距其原型提出已有約10年時間,而微軟Halo系列估計
已用了超過8年了,Spore和一些著名遊戲也早已使用行為樹作為它們的AI結構。
如從未接觸,那wikipedia(http://en.wikipedia.org/wiki/Behavior_Trees)
絕對是入門好資料。

———————————————————————

先借用網上的一張圖來詮釋下行為樹到底是怎麽樣的

技術分享

———————————————————————

行為樹(Behavior Tree)具有如下的特性:

它只有4大類型的Node:
* Composite Node  組合節點
* Decorator Node   修飾節點
* Condition Node   條件節點(葉節點)
* Action Node    動作節點(葉節點)

任何Node被執行後,必須向其Parent Node報告執行結果:成功 / 失敗。
這簡單的成功 / 失敗匯報原則被很巧妙地用於控制整棵樹的決策方向。

———————————————————————

先看Composite Node,其實它按復合性質還可以細分為3種:
* Selector Node
當執行本類型Node時,它將從begin到end叠代執行自己的Child Node:
如遇到一個Child Node執行後返回True,那停止叠代,
本Node向自己的Parent Node也返回True;否則所有Child Node都返回False,
那本Node向自己的Parent Node返回False。

* Sequence Node
當執行本類型Node時,它將從begin到end叠代執行自己的Child Node:
如遇到一個Child Node執行後返回False,那停止叠代,
本Node向自己的Parent Node也返回False;否則所有Child Node都返回True,
那本Node向自己的Parent Node返回True。

* Parallel Node
並發執行它的所有Child Node。
而向Parent Node返回的值和Parallel Node所采取的具體策略相關:
Parallel Selector Node: 一False則返回False,全True才返回True。
Parallel Sequence Node: 一True則返回True,全False才返回False。
Parallel Hybird Node: 指定數量的Child Node返回True或False後才決定結果。

Parallel Node提供了並發,提高性能。
不需要像Selector/Sequence那樣預判哪個Child Node應擺前,哪個應擺後,
常見情況是:
(1)用於並行多棵Action子樹。
(2)在Parallel Node下掛一棵子樹,並掛上多個Condition Node,
以提供實時性和性能。
Parallel Node增加性能和方便性的同時,也增加實現和維護復雜度。

PS:上面的Selector/Sequence準確來說是Liner Selector/Liner Sequence。
AI術語中稱為strictly-order:按既定先後順序叠代。

Selector和Sequence可以進一步提供非線性叠代的加權隨機變種。
Weight Random Selector提供每次執行不同的First True Child Node的可能。
Weight Random Sequence則提供每次不同的叠代順序。
AI術語中稱為partial-order,能使AI避免總出現可預期的結果。

———————————————————————

再看Decorator Node,它的功能正如它的字面意思:它將它的Child Node執行
後返回的結果值做額外處理後,再返回給它的Parent Node。很有些AOP的味道。

比如Decorator Not/Decorator FailUtil/Decorator Counter/Decorator Time…
更geek的有Decorator Log/Decorator Ani/Decorator Nothing…

———————————————————————

然後是很直白的Condition Node,它僅當滿足Condition時返回True。

———————————————————————

最後看Action Node,它完成具體的一次(或一個step)的行為,視需求返回值。
而當行為需要分step/Node間進行時,可引入Blackboard進行簡單數據交互。

———————————————————————

整棵行為樹中,只有Condition Node和Action Node才能成為Leaf Node,而也
只有Leaf Node才是需要特別定制的Node;Composite Node和Decorator Node均
用於控制行為樹中的決策走向。(所以有些資料中也統稱Condition Node和Action
Node為Behavior Node,而Composite Node和Decorator Node為Decider Node。)

更強大的是可以加入Stimulus和Impulse,通過Precondition來判斷masks開關。

通過上述的各種Nodes幾乎可以實現所有的決策控制:if, while, and, or,
not, counter, time, random, weight random, util…

———————————————————————

總的來說,行為樹具有如下幾種優點,確實是實現AI框架的利器,甚至是一種
通用的可維護的復雜流程管理利器:

> 靜態性
越復雜的功能越需要簡單的基礎,否則最後連自己都玩不過來。

靜態是使用行為樹需要非常著重的一個要點:即使系統需要某些”動態”性。

其實諸如Stimulus這類動態安插的Node看似強大,
但卻破壞了本來易於理解的靜態性,弊大於利。
Halo3相對於Halo2對BT AI的一個改進就是去除Stimulus的動態性。
取而代之的做法是使用Behavior Masks,Encounter Attitude,Inhibitions。
原則就是保持全部Node靜態,只是根據事件和環境來檢查是否啟用Node。

靜態性直接帶來的好處就是整棵樹的規劃無需再運行時動態調整,為很多優化
和預編輯都帶來方便。

> 直觀性
行為樹可以方便地把復雜的AI知識條目組織得非常直觀。
默認的Composite Node的從begin往end的Child Node叠代方式就像是處理一個
預設優先策略隊列,也非常符合人類的正常思考模式:先最優再次優。

行為樹編輯器對優秀的程序員來說也是唾手可得。

> 復用性
各種Node,包括Leaf Node,可復用性都極高。
實現NPC AI的個性區別甚至可以通過在一棵共用的行為樹上不同的位置來
安插Impulse來達到目的。

當然,當NPC需要一個完全不同的大腦,比如70級大BOSS,
與其絞盡腦汁在一棵公用BT安插Impulse,不如重頭設計一棵專屬BT。

> 擴展性
雖然上述Node之間的組合和搭配使用幾乎覆蓋所有AI需求。
但也可以容易地為項目量身定做新的Composite Node或Decorator Node。
還可以積累一個項目相關的Node Lib,長遠來說非常有價值。

--------------------------------本人補充---------------------------------------

每個節點都應該有以下三種狀態:
Running,
Success,
Failed

Running狀態用於表明該節點的結果不能立刻獲知,比如遊戲中的角色進行“向目標移動”

這個動作,很顯然這個動作不能在這一幀中立刻完成,當行為樹運行到此節點時,並不能

獲知是success或者failed,於是返回running,表示該節點正在運行中,並記錄此節點

的位置,下一幀運行到此節點的父節點時,則從此節點繼續運行,跳過之前的節點。

技術分享

原文地址:http://www.cnblogs.com/jeason1997/p/4803243.html

使用行為樹(Behavior Tree)實現遊戲AI