在C++中创建任务类型
2023年10月20日 2024年1月11日
说明
AI Task
在C++中生成随机点, 让NPC移动到随机生成位置
创建任务类型
-
创建蓝图任务类型的方法
BT_STUCharacter
点击
New Task
-
C++
- 基类 BTTaskNode 路径 AI/Tasks/ Public STUNextLocationTask ShootThemUp: ShootThemUp.Build.cs
修改头文件搜索路径
1PublicIncludePaths.AddRange(new string[] 2{ 3 "ShootThemUp/Public/Player", 4 "ShootThemUp/Public/Components", 5 "ShootThemUp/Public/Dev", 6 "ShootThemUp/Public/Weapon", 7 "ShootThemUp/Public/UI", 8 "ShootThemUp/Public/Animations", 9 "ShootThemUp/Public/Pickups", 10 "ShootThemUp/Public/Weapon/Components", 11 "ShootThemUp/Public/AI", 12 "ShootThemUp/Public/AI/Tasks" 13});
添加依赖模块GameplayTasks和NavigationSystem
1PublicDependencyModuleNames.AddRange(new string[] 2{ 3 "Core", 4 "CoreUObject", 5 "Engine", 6 "InputCore", 7 "Niagara", 8 "PhysicsCore", 9 "GameplayCameras", 10 "GameplayTasks", 11 "NavigationSystem" 12});
实现任务: 在给定半径圆形范围内生成随机点并设置变量
-
添加构造函数
ShootThemUp: AI/Tasks/STUNextLocationTask.h
public
1USTUNextLocationTask();
-
执行任务时调用ExecuteTask
覆写
ShootThemUp: AI/Tasks/STUNextLocationTask.h
public
1virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent &OwnerComp, uint8 *NodeMemory) override;
-
添加属性
半径和黑板变量
ShootThemUp: AI/Tasks/STUNextLocationTask.h
protected
1UPROPERTY(EditAnywhere, BlueprintReadWrite) 2float Radius = 1000.0f; 3 4UPROPERTY(EditAnywhere, BlueprintReadWrite) 5FBlackboardKeySelector AimLocationKey;
-
在构造函数中设置任务节点名
ShootThemUp: AI/Tasks/STUNextLocationTask.cpp
1USTUNextLocationTask::USTUNextLocationTask() 2{ 3 NodeName = "Next Location"; 4}
-
生成随机点并写入黑板变量
GetRandomReachablePointInRadius在游戏角色可以去到的nav mesh范围内计算随机点, 该函数在覆盖范围实现路径搜索算法如果找到该点, 游戏角色一定能从所处位置去到该点
给出搜索中心点, 搜索半径, 存放点的变量
ShootThemUp: AI/Tasks/STUNextLocationTask.cpp
1#include "BehaviorTree/BlackboardComponent.h" 2#include "AIController.h" 3#include "NavigationSystem.h" 4 5EBTNodeResult::Type USTUNextLocationTask::ExecuteTask(UBehaviorTreeComponent &OwnerComp, uint8 *NodeMemory) 6{ 7 const auto Controller = OwnerComp.GetAIOwner(); 8 const auto Blackboard = OwnerComp.GetBlackboardComponent(); 9 if (!Controller || !Blackboard) return EBTNodeResult::Failed; 10 11 const auto Pawn = Controller->GetPawn(); 12 if (!Pawn) return EBTNodeResult::Failed; 13 14 const auto NavSys = UNavigationSystemV1::GetCurrent(Pawn); 15 if (!NavSys) return EBTNodeResult::Failed; 16 17 FNavLocation NavLocation; 18 const auto Found = NavSys->GetRandomReachablePointInRadius(Pawn->GetActorLocation(), Radius, NavLocation); 19 if (!Found) return EBTNodeResult::Failed; 20 21 Blackboard->SetValueAsVector(AimLocationKey.SelectedKeyName, NavLocation.Location); 22 return EBTNodeResult::Succeeded; 23}
查看
-
添加变量AimLocation
BB_STUCharacter
-
更新行为树
BT_STUCharacter
> 生成随机点 > 等待两秒 > 去到随机点; 循环黑板变量绑定
移动到随机点
-
移除上节在指定点往返逻辑
BP_STUAIController
人为干预: 设置ExecuteTask返回Failed
BT_STUCharacter
-
添加任务: FinishedWithResult, 设置结果为Failed; 游戏角色停留在Wait节点
-
移除FinishedWithResult节点