官方給出的AI實例是實現一個跟隨着玩家跑的AI,當玩家沒有在AI視野里時,它會繼續跑到最后看到玩家的地點,等待幾秒后如果仍然看不到玩家,則跑回初始地點。官方的案例已經講得比較詳細,對於一些具體的函數調用,官方沒有進一步講解,本文作為官方案例的一個補充,提供給有興趣的朋友參考。
一、整體思路分析
一個整體的思路是,用一個Service檢測附近是否有出現在AI里的玩家,如果有的話,則將TargetToFollow設為該對象,然后跑向該對象(RapidMoveTo,注意,不是跑向玩家所在位置,而是跑向玩家),如果沒有的話,則將TargetToFollow置為空,然后跑向(MoveTo)玩家最后出現的位置(TargetLocation),否則,跑回(MoveTo)HomeLocation。也就是說,1.建立一個Blackboard記錄數據,2.需要實現一個Service來檢測AI附近並且出現在AI視野里的玩家,3.實現一個Task(RapidMoveTo),使得AI跑向玩家,4.實現一個Task,使得AI跑回初始地點(MoveTo 已在引擎中實現)5.實現一個Decorator節點,判斷AI是否已經離玩家的距離較近,如果較近,在停止活動。
二、每個步驟的分析
1.建立Top-Down模板,此處不再贅述。
2.建立尋路網絡邊界體積框,AI只會在此框內進行尋路,按p鍵可以查看,模板中已經存在,實際試驗當中不需要添加。
3.設置角色藍圖。具體參看官網案例,比較簡單,此處不再贅述。
4.設置Blackboard資源。Blackboard里,添加三個變量,即Homelocation,TargetLocation,TargetToFollow。
5.設置AIController,此處可以按照官方的案例,創建AIController的藍圖類,也可以在C++代碼里創建。需要指出的是,需要在控制器里設置行為樹使用的Blackboard,以及運行的行為樹,並且初始化HomeLocation。C++版本與藍圖版本本質相同,以下只給出藍圖版本。
void AMyAIController::Possess(class APawn* InPawn) { Super::Possess(InPawn); AMyCharacter* Bot = Cast<AMyCharacter>(InPawn); if (Bot) { if (Bot->BehaviorTree->BlackboardAsset) { BlackboardComp->InitializeBlackboard(*Bot->BehaviorTree->BlackboardAsset); /* Make sure the Blackboard has the type of bot we possessed */ BlackboardComp->SetValueAsEnum(BotTypeKeyName, (uint8)Bot->BotType); } BehaviorComp->StartTree(*Bot->BehaviorTree); } }
或者:
6.放置AI角色,拖住藍圖腳本放進Level Editor即可。
7.設置Service節點。其中需要注意的是:
(1)官方案例中,使用一個AI_CON_Ref的變量保存AIController的引用,可以進一步使用Event Receive Tick的AI版本,可以直接得到AIController的引用,連變量都省了。
(2)案例中使用MultiSphereTraceForObject進行附近是否存在玩家的檢測。其中的Radius是球形的半徑,ObjectTypes是需要檢測的類型,Actors to Igonore是不需要檢測的類型。而它的檢測路徑如第二張圖,即為一個半徑為Radius的球體從Start移動到end掃過的面積。
(3)其中的LineTraceByChannel進行線性檢測,查看AI與玩家之間是否存在阻擋物。至於為什么Trace Channel要設
置成Camera,是因為在默認情況下,Character不會Block Visibility,但是會阻礙Camera。可以在Character藍圖中查
看相關設置。
8.Task的設置,此設置可在藍圖中進行設置,可參看官方例子,也可以在C++中進行設置,參看Shooter Game的例子。沒有沒有需要注意的地方,看官方文檔即可,此處不再贅述。
9.Decorator的設置。
10.設置行為樹。設置完行為樹之后,同時開啟Level編輯器界面和行為樹界面可以看到行為樹的運行情況。