斯坦福UE4C++課程P42-P45自定義任務和EQS的中級AI
這一章我們
在C++中給行為樹添加范圍攻擊Task
在行為樹中創(chuàng)建攻擊行為
用EQS讓AI前往接近玩家的地點(不是正好是玩家的位置)
EQS Query:找到TargetActor周圍位置,讓AI走的最短距離,并且包含對TargetActor的line-of-sight
學會使用Gameplay Debugger,Visual Logger(記錄了AI行為,并反映到編輯器viewboard)
添加PawnSensing(主要是視覺sight上的感知,替代用TargetActor來追尋玩家)
首先我們添加一個BTTask繼承的C++類SBTTask_RangedAttack,包含范圍內(nèi)攻擊角色的邏輯
然后把它添加到行為樹中。

現(xiàn)在AI首先看玩家是否在攻擊范圍內(nèi),如果在,先cooldown5秒,然后發(fā)起RangedAttack任務。
我們接下來修改行為樹如下:

within attack range節(jié)點設置低優(yōu)先級觀察者中止。因為如果設置觀察者中止為None,AI若判斷玩家在范圍外,將走到范圍上,且還需要等5秒才攻擊,這很怪異,所以設置該節(jié)點為低優(yōu)先級觀察者中止,表示一旦AI判斷玩家在范圍內(nèi),將立即執(zhí)行自己及子節(jié)點。
我們還設置了讓AI看向玩家的Focus的service(右鍵add service,選focus)。

現(xiàn)在如果我們多加幾個AI,它們可能會堆成一列,這降低了游戲難度。
我們學習使用環(huán)境查詢EQS來改進AI的運動,讓其更智能。
我們首先新建一個EnvQueryContext_BlueprintBase繼承的藍圖類QueryContext_TargetActor
重載Provide Single Actor函數(shù):

表示我們會獲取到AI黑板的TargetActor,把它作為返回值。
內(nèi)容瀏覽器右鍵選擇Environment Query命名為Query_FindNearbyLocation,彈出的界面和行為樹差不多。從root拖出donut節(jié)點,右鍵點擊該節(jié)點,添加distance的test,filter type選最小值,最小值定為500,(把donut節(jié)點的center選為剛新建的EnvQueryContext_BlueprintBase類)表示讓AI隨機找的位置范圍最小為500。
在AI行為樹添加EQS節(jié)點:

現(xiàn)在AI發(fā)現(xiàn)玩家在攻擊范圍外時,將找到玩家位置以500為下限的范圍的點(而非徑直前往玩家所在位置),并前往該點。
tip:我們可以打開VisualLogger,來看之前一段時間發(fā)生的事情(window->developer tool下)

接下來我們給AI添加PawnSensing(不同于AI Perception,比AI Perception老)
在AICharacter類中:
.h文件添加
.cpp文件:
現(xiàn)在在藍圖中打開AI角色藍圖,多了PawnSensing組件,可以看到許多關于AI感知的內(nèi)容。調(diào)整Peripheral Vision Angle為45°,縮小AI視錐。我們發(fā)現(xiàn)視錐在AI頭上方,所以選中左側self,調(diào)整Base Eye Height為40,讓視錐下移到模型眼睛位置。
另外,我們之前做的是讓AI獲取到TargetActor,前往TargetActor周圍的點;但現(xiàn)在沒有看見玩家之前,TargetActor一直為空。而QueryContext藍圖在Cast失敗時直接返回空節(jié)點,這導致AI無法觸發(fā)OnSeePawn事件,我們直接簡單地添加GetPlayerPawn即可,讓AI始終能夠獲取到TargetActor:


最后我們改進一下AI動畫和C++資產(chǎn)。
AI動畫有兩個問題:沒有旋轉動畫(瞬間轉向)、從wait到移動的動畫混合過程AI有一段滑動過程。
勾選AI角色移動組件的:

取消勾選Self->Pawn下的:

表示我們使用移動組件的Rotation Rate(每秒):

現(xiàn)在AI一秒可繞Z軸旋轉360°。

下面牽扯到動畫藍圖的混合空間Blend Space概念。
我們打開AI角色使用的動畫藍圖,包含事件圖表Event Graph和動畫圖表Anim Graph,我們打開后者,找到IdleToRun節(jié)點,雙擊打開混合空間。移動下方的綠色點可以查看二維混合空間下的任一點的運動狀態(tài)動畫。

我們可以通過調(diào)節(jié)左側Target Weight Interpolation Speed Per Sec的大小來控制一個點到另一個點的過渡速率,從1改成8,過渡就快8倍。

速率為1時有個滑行過程:

速率為8時正常:

最后我們在AIControllerC++類的BeginPlay函數(shù)中添加:
確保行為樹不空。現(xiàn)在我們在AI控制器藍圖設置行為樹為空,運行游戲發(fā)現(xiàn)輸出日志中有報錯信息。