UE4藍圖AI角色製作(七)之追逐玩家

achevery 發表於 2021-10-21
人工智慧

15、追逐玩家

現在我們的AI無法做出任何決策,它總是執行相同的決策。我們先把感知系統中的相關資訊提供給AI,讓AI知道如何做出決策,然後我們會修改行為樹。我們首先需要建立新的黑板鍵,這樣我們就能在行為樹上儲存這些資訊。開啟”BB_EnenmyAI “,在左側的“黑板”選項卡中,點選“新建”按鈕,選擇“物件”型別,將這個新建命名為“Target Actor”。在右側的“黑板詳細資訊”皮膚中,在“鍵”分段中展開“鍵型別”選項,在“基類”下拉選單中將型別從“object”改為“Actor”。回到“黑板”皮膚,再次點選“新建”,這次選擇布林型別,把這個黑板鍵命名為“Has Line Of Sight”。

接下來,首先在內容瀏覽器中找到“AIC ThirPerson Character”然後開啟它,接著建立一些輔助函式以便讓黑板鍵處理起來更加容易。第一個函式有一個Actor輸入,並會把某個黑板鍵設定為相同的Actor值,在“我的藍圖”皮膚中點選“函式”分段中的加號圖示,新建一個函式,將函式命名為“Update Target Actor Key”。在細節皮膚中,點選“輸入”分段中的加號,新建一個輸入,選擇“Actor”作為輸入型別,將此輸入命名為“Target Actor”。第一步是獲取當前的黑板。右鍵事件圖表,搜尋“Get Blackboard”,選擇“AI”>“變數”中的“Get Blackboard”。拖動“黑板”元件物件引用的引腳然後輸入“Set value as Object”,這樣會自動把黑板物件作為“Set value as Object”的目標引數。接下來,我們需要建立一個鍵名,它指向與行為樹相關聯的黑板中的黑板鍵。為此,我們拖動“Set value as Object”的“key name”,選擇提升至變數,將這個新變數命名為“Target Actor Name”。保持選中狀態,移到細節皮膚,找到類別皮膚,新建一個類別,在這個選項框中輸入“Key Names”並以此命名。注意,這樣會把我們的新變數自動歸類到“我的藍圖”皮膚中的“Keys Names”型別。下一步是設定“Target Actor Name”的預設值,在此之前,我們需要編譯藍圖。

 UE4藍圖AI角色製作(七)之追逐玩家

編譯後細節皮膚中“Target Actor Name”的預設值為無,將其設定為與黑板鍵名相同,即“Target Actor”。“Set value as Object”需要的最後一個引數就是傳遞給黑板的數值。這裡就要用到我們此前建立的輸入。將“Target Actor”連到“set values as object”的“object value”,把這個函式的執行引腳連到“Set value as Object”。

我們要建立的下一個函式擁有一個黑板鍵,它能儲存AI當前能否通過感知系統觀察到玩家。和之前一樣,先在“我的藍圖”皮膚中新建一個函式,將它命名為“UpdateHasLineOfSightKey”,在細節皮膚的“輸入”分段中,點選加號新增新的輸入,確保這個輸入是布林型別,將這個新引數命名為“HasLineOfSight”。和之前的函式一樣,我們首先要獲得正確的黑板,右鍵點選事件圖表,然後輸入“Get Blackboard”,選擇“AI”>”變數”中的函式,拖動這個黑板引用的引腳,然後輸入“Set value as Bool”,拖動“Key name”變數,選擇“提升為變數”,將其命名為“HasLineOfSightName”。 下一步是設定“HasLineOfSightName”的預設值,在此之前,我們需要編譯藍圖。編譯後細節皮膚中“HasLineOfSightName”的預設值為無,將其設定為與黑板鍵名相同,即Has Line Of Sight”。然後將兩個函式引腳相連,將“Has Line Of Sight”輸入引腳與“bool value”相連。

現在我們要回到角色的“on target perception updated”事件,然後使用這個時間來更新我們新建的黑板鍵。這意味著每當感知狀態發生改變時,相關的黑板鍵也會更新。

在內容瀏覽器中找到“AICharacter1”,首先在觸發“target lost”事件時,清空“target actor”黑板鍵。當前,這個事件會在目標超出視野5秒後觸發,這表示AI完全遺忘了目標Actor,並放棄進行跟蹤。為了訪問我們剛剛建立的函式,我們首先要獲取AI控制器的引用。右鍵點選事件圖表,然後輸入“Get Controller”,直到出現這個函式,這個函式會返回一個泛型控制器引用。我們需要將這個泛型型別轉換為“AIC ThirdPerson Character”。為此,我們可以拖動返回值,輸入“Cast”,選擇“Cast to AIC ThirdPerson Character”。為了保證圖表條理清晰便於理解,我們可以轉換成純型別轉換,右鍵點選節點選擇“轉換為純型別轉換”。現在拖動“AIC ThirdPerson Character”引腳然後引用我們定義的函式即“Update Target Actor Key”,然後連線設定節點的執行引腳,如圖所示:

 UE4藍圖AI角色製作(七)之追逐玩家

此時,期望的黑板狀態是讓“target actor”的值為空,也就是現在沒有target actor。為此,這個函式不需要提供任何引數。

讓我們來看這個事件的另一種結果。我們需要使用“”line of sight”鍵來表示這種情況,我們利用函式把“HasLineOfSight”鍵設定為假,我們可以複製這兩個節點“Get Controller”和“Cast to AIC ThirdPerson Character”,他們允許我們獲得“AIC ThirdPerson Character”AI控制器。再次拖動“AIC ThirdPerson Character”引腳然後引用我們定義的函式即“update has line if sight key”, 然後連線設定節點的執行引腳,如圖所示:

 UE4藍圖AI角色製作(七)之追逐玩家

複製這三個節點“Get Controller”和“Cast to AIC ThirdPerson Character”和“Update Target Actor Key”,將他們的執行節點連線到“clear and invalidate timer by handle“。這個控制程式碼當前連到分支的”真“值引腳,這種情況下我們需要提供”target actor“。所幸我們之前已經設定好了,找到”我的藍圖“皮膚,找到”PerceivedActor“,按住Ctrl鍵,左鍵點選它並拖到事件圖表中,將”PerceivedActor“連到”target Actor“。”PerceivedActor“是之前在事件中定義的變數,我們獲取了事件和感知系統提供的Actor,然後將”PerceivedActor“賦值給它,最後,複製上面這三個節點 “Get Controller”和“Cast to AIC ThirdPerson Character”和“update has line if sight key”,它們用於獲取“update has line of sight key“函式,將他們連線到“Update Target Actor Key”。注意,分支的這個部分用於定義Actor剛剛被感知系統被感知到時的狀態。這裡要把“has line of sight“設定為真,勾選函式中的核取方塊。

讓我們快速回顧一下做了那些修改。可以看到,這個“on target perception updated“事件為AI定義了三種不同狀態。第一種狀態,Actor被感知時,這個狀態定義了AI看到Actor時的情況。第二種結果,返回值為”假“的結果,定義了看不到Actor時的狀態。即使看不到,我們仍在黑板中保留了被感知Actor的值,這種狀態表示AI記得看到了某個物件,只是當前看不到了。最後是”target lost“事件,它會在物件消失5秒後觸發,這種狀態表示AI當前看不到,當前感知的Actor並且對它喪失了興趣。值得一提的是,我們之所以設定黑板鍵,就是為了提供資訊,並通過黑板鍵將資訊提供給行為,它不做任何決策,這由行為樹決定。

下面我們在行為樹中把所有這些修改內容拼合起來。我們將藉助新的黑板鍵和裝飾器,讓AI有能力決定是追逐玩家還是繼續隨機漫遊。首先,在內容瀏覽器中開啟行為樹資源“BT_EnemyAI“,我們將使用當前儲存在黑板中的資訊,在兩個序列中二選一。刪除第一個序列,拖動根節點,在選單中選擇”選擇器“,把選擇器連至現在的”隨機漫遊“序列。隨機漫遊序列的優先順序比我們建立的序列要低。在行為樹中執行順序是從左到右。通過剛剛建立的選擇器新建一個序列,在細節皮膚中的”描述“分段中,將節點名稱改為”chase player“,拖動”chase player“序列,選擇”move to task“,我們需要將AI移到目標Actor的位置,為此,在右側細節皮膚中的”黑板“分段點選”黑板鍵“,在下拉選單中選擇”Target Actor“。”Target Actor“是我們建立的用於和函式一起更新的黑板鍵。接著,再次拖動追逐玩家序列,在”move to“節點的右側新建一個節點,選擇”Wait“節點,在細節皮膚的”等待“分段中,將等待時間五秒改為一秒。通常在任務結束後會新增一些等待任務,因為這能避免行為樹在不同序列間快速迴圈,從而顯得不自然。新增這兩個序列後,”追逐玩家“序列基本完成了,考慮到行為樹的執行順序,這個新的分支會始終在隨機漫遊序列之前執行。

 UE4藍圖AI角色製作(七)之追逐玩家

接下來,需要使用裝飾器控制這個分支的執行方式,只有當前需要設定目標Actor時才執行它。右鍵點選,”追逐玩家“序列,選擇”新增裝飾器“>”黑板“。接下來,選中這個新的裝飾器,在細節皮膚中的描述段將節點名稱改為”is a target actor set“。我們來看看要使用哪些黑板鍵,由於我們關心的是目標Actor,所以應該在細節皮膚中”黑板“分段中,在”黑板鍵“下拉選單中選中”SetActor“。接下來我們需要思考的是和鍵有關的是什麼內容。”黑板“分段允許我們定義我們期望的結果。上面的”流程控制“分段允許我們控制觀察到期望結果時執行流程會發生什麼。”通知觀察者“下拉選單有兩個選項,預設選項是”on result change“。每當鍵查詢的結果發生變化時,我們會按照”observer aborts“描述的內容更改執行流程。

 UE4藍圖AI角色製作(七)之追逐玩家