六一的部落格


关关难过关关过,前路漫漫亦灿灿。




说明

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节点


在C++中创建任务类型



说明

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节点