六一的部落格


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




说明

AI / EQS / Context

完成两点

  1. 在敌人周围生成具有随机性的点阵, 选择一个位置点, 去到那里
  2. 设置点阵中心为敌人

生成创建BP类

Content/AI/EQS目录下, 创建EQS资产EQS_NextToEnemyLocation

为EQS_TestPawn设置EQS模板: 在世界大纲中选中EQS_TestPawn, Details > EQS > Query Template , 设置为EQS_NextToEnemyLocation



设置EQS资产

EQS_NextToEnemyLocation

生成附近随机位置

  • 添加生成器: 环形点阵

  • 设置环形点阵

    -
    Projection Data > Track Mode Navigation
    Inner Radius Data Binding = None, Inner Radius = 450
    Outer Radius Data Binding = Random number, Outer Radius = 1000-1500
    Number Of Rings Data Binding = Random number, Number Of Rings = 3-8
    Points Per Ring Data Binding = Random number, Number Of Rings = 4-20
    Arc Angle 360
    Use Spiral Pattern 勾选


  • 为环形点阵添加距离条件: Distance

  • 设置Distance

    -
    Filter > Filter Type Range: 400-800
    Score > Scoring Factor Data Binding = Random number, Scoring Factor = -1 ~ 1, 随机



使用蓝图类测试


创建蓝图类

-
基类 EnvQueryContext_BlueprintBase
路径 AI/EQS
名称 EQS_ContextSTUCharacter

覆写函数

选择返回Actor或者位置

双击打开 EQS_NextToEnemyLocation


选择函数原型

My Blueprint > Functions Override , 选择 Provide Single Actor

-
Provide Actors Set Actor数组
Provide Locations Set 位置数组
Provide Single Actor 单一Actor
Provide Single Location 单一位置



覆写

  1. 筛选Actor类型

    Provide Single Actor 之后, 添加节点: Get All Actors Of Class , 设置类类型为STUBaseCharacter

  2. Get All Actor Of Class 之后, 返回第一个元素, 添加节点: Get (a copy)

    未作检查, 返回第一个元素




设置中心点

设置中心点

  1. 设置环状点阵生成器中心点使用EQS_ContextSTUCharacter


  2. 设置Distance距离计算参照点使用EQS_ContextSTUCharacter


  3. 查看

    • 在场景中添加BP_STUBaseCharacter

    • 移动游戏角色, 再次选中TestPawn, 环状点阵的中心一直是游戏角色


    • 移除游戏角色


在行为树中使用

  1. 选择 Run EQS Query, 设置使用的模板为 EQS_NextToEnemyLocation

    Details > EQS > Query Template , 选择EQS_NextToEnemyLocation


  2. 运行游戏

    NPC始终在游戏角色附近的圆环点阵中切换位置



学习EnvQueryContext_Querier

  1. 构造函数
  2. PrivideContext
    • 该函数只用来计算Actor, 返回计算得到Actor
    • 获取EQS上级, 并通过SetContextHelper设置给ContextData
    • 我们要做的, 即获取黑板变量EnemyActor对应的Actor, 并设置给ContextData
    • QueryOwener: Pawn或者Character, EQS的上级

使用C++类实现

设置黑板变量EnemyActor


创建C++类

-
EnvQueryContext
STUEnemyEnvQueryContext
AI/EQS
Public

修改STUUtils.h的预编译命令的遗留错误

ShootThemUp: STUUtils.h

1#pragma once

修改头文件搜索路径

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    "ShootThemUp/Public/AI/Services",
14    "ShootThemUp/Public/AI/EQS"
15});

实现STUEnemyEnvQueryContext


添加属性: EnemyActor变量名

protected

ShootThemUp: AI/EQS/STUEnemyEnvQueryContext.h

1UPROPERTY(EditAnywhere, BlueprintReadWrite)
2FName EnemyActorKeyName = "EnemyActor";

覆写虚函数

public

ShootThemUp: AI/EQS/STUEnemyEnvQueryContext.h

1virtual void ProvideContext(FEnvQueryInstance &QueryInstance, FEnvQueryContextData &ContextData) const override;
  • 获取EQS上级对应的Actor

    FEnvQueryInstance在EnvQueryTypes.h中

    1#include "EnvironmentQuery/EnvQueryTypes.h"
    2
    3const auto QueryOwner = Cast<AActor>(QueryInstance.Owner.Get());
  • 获取黑板组件

    通过转换EQS上级得到Pawn, 通过Pawn得到Controller; 指定组件类型, 通过Controller获取黑板组件

    1#include "Blueprint/AIBlueprintHelperLibrary.h"
    2#include "BehaviorTree/BlackboardComponent.h"
    3
    4const auto Blackboard = UAIBlueprintHelperLibrary::GetBlackboard(QueryOwner);
    5if (!Blackboard) return;
  • 获取黑板变量

    1const auto ContextActor = Blackboard->GetValueAsObject(EnemyActorKeyName);
  • 将黑板变量用作中心点

    1#include "EnvironmentQuery/Items/EnvQueryItemType_Actor.h"
    2
    3UEnvQueryItemType_Actor::SetContextHelper(ContextData, Cast<AActor>(ContextActor));
  • 完整实现

    ShootThemUp: AI/EQS/STUEnemyEnvQueryContext.cpp

     1#include "EnvironmentQuery/EnvQueryTypes.h"          
     2#include "Blueprint/AIBlueprintHelperLibrary.h"
     3#include "BehaviorTree/BlackboardComponent.h"
     4#include "EnvironmentQuery/Items/EnvQueryItemType_Actor.h"
     5
     6void USTUEnemyEnvQueryContext::ProvideContext(FEnvQueryInstance &QueryInstance, FEnvQueryContextData &ContextData) const
     7{
     8    const auto QueryOwner = Cast<AActor>(QueryInstance.Owner.Get());
     9
    10    const auto Blackboard = UAIBlueprintHelperLibrary::GetBlackboard(QueryOwner);
    11    if (!Blackboard) return;
    12
    13    const auto ContextActor = Blackboard->GetValueAsObject(EnemyActorKeyName);
    14    UEnvQueryItemType_Actor::SetContextHelper(ContextData, Cast<AActor>(ContextActor));
    15
    16}      
    

使用C++类STUEnemyEnvQueryContext


设置行为树

BT_STUCharacter

  1. 在环形点阵和距离限制条件中使用STUEnemyEnvQueryContext



  2. 恢复行为树框架, 移除Task


  3. 添加任务: RunEQSQuery - EQS_NextToEnemyLocation


  4. 添加任务: RunEQSQuery - EQS_RandomRoam


  5. 暂时移除Fire服务里目标: 点击恢复图标



查看

  • 按下 ' 打开调试界面

  • 选中AICharacter

  • 按下小写键盘 3 显示EQS

  • 当前存在两个EQS点阵, 按下小写键盘 * 显示当前EQS

    Project Settings > Engine > Gameplay Debugger


对于EQS的使用, 我们现在可以设置任意移动模板, 或者随机结合他们

  • 可以移除楼梯和模拟爆炸
  • 可以添加墙, 躲避NPC捕获

使用EQS在敌人附近移动



说明

AI / EQS / Context

完成两点

  1. 在敌人周围生成具有随机性的点阵, 选择一个位置点, 去到那里
  2. 设置点阵中心为敌人

生成创建BP类

Content/AI/EQS目录下, 创建EQS资产EQS_NextToEnemyLocation

为EQS_TestPawn设置EQS模板: 在世界大纲中选中EQS_TestPawn, Details > EQS > Query Template , 设置为EQS_NextToEnemyLocation



设置EQS资产

EQS_NextToEnemyLocation

生成附近随机位置

  • 添加生成器: 环形点阵

  • 设置环形点阵

    -
    Projection Data > Track Mode Navigation
    Inner Radius Data Binding = None, Inner Radius = 450
    Outer Radius Data Binding = Random number, Outer Radius = 1000-1500
    Number Of Rings Data Binding = Random number, Number Of Rings = 3-8
    Points Per Ring Data Binding = Random number, Number Of Rings = 4-20
    Arc Angle 360
    Use Spiral Pattern 勾选


  • 为环形点阵添加距离条件: Distance

  • 设置Distance

    -
    Filter > Filter Type Range: 400-800
    Score > Scoring Factor Data Binding = Random number, Scoring Factor = -1 ~ 1, 随机



使用蓝图类测试


创建蓝图类

-
基类 EnvQueryContext_BlueprintBase
路径 AI/EQS
名称 EQS_ContextSTUCharacter

覆写函数

选择返回Actor或者位置

双击打开 EQS_NextToEnemyLocation


选择函数原型

My Blueprint > Functions Override , 选择 Provide Single Actor

-
Provide Actors Set Actor数组
Provide Locations Set 位置数组
Provide Single Actor 单一Actor
Provide Single Location 单一位置



覆写

  1. 筛选Actor类型

    Provide Single Actor 之后, 添加节点: Get All Actors Of Class , 设置类类型为STUBaseCharacter

  2. Get All Actor Of Class 之后, 返回第一个元素, 添加节点: Get (a copy)

    未作检查, 返回第一个元素




设置中心点

设置中心点

  1. 设置环状点阵生成器中心点使用EQS_ContextSTUCharacter


  2. 设置Distance距离计算参照点使用EQS_ContextSTUCharacter


  3. 查看

    • 在场景中添加BP_STUBaseCharacter

    • 移动游戏角色, 再次选中TestPawn, 环状点阵的中心一直是游戏角色


    • 移除游戏角色


在行为树中使用

  1. 选择 Run EQS Query, 设置使用的模板为 EQS_NextToEnemyLocation

    Details > EQS > Query Template , 选择EQS_NextToEnemyLocation


  2. 运行游戏

    NPC始终在游戏角色附近的圆环点阵中切换位置



学习EnvQueryContext_Querier

  1. 构造函数
  2. PrivideContext
    • 该函数只用来计算Actor, 返回计算得到Actor
    • 获取EQS上级, 并通过SetContextHelper设置给ContextData
    • 我们要做的, 即获取黑板变量EnemyActor对应的Actor, 并设置给ContextData
    • QueryOwener: Pawn或者Character, EQS的上级

使用C++类实现

设置黑板变量EnemyActor


创建C++类

-
EnvQueryContext
STUEnemyEnvQueryContext
AI/EQS
Public

修改STUUtils.h的预编译命令的遗留错误

ShootThemUp: STUUtils.h

1#pragma once

修改头文件搜索路径

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    "ShootThemUp/Public/AI/Services",
14    "ShootThemUp/Public/AI/EQS"
15});

实现STUEnemyEnvQueryContext


添加属性: EnemyActor变量名

protected

ShootThemUp: AI/EQS/STUEnemyEnvQueryContext.h

1UPROPERTY(EditAnywhere, BlueprintReadWrite)
2FName EnemyActorKeyName = "EnemyActor";

覆写虚函数

public

ShootThemUp: AI/EQS/STUEnemyEnvQueryContext.h

1virtual void ProvideContext(FEnvQueryInstance &QueryInstance, FEnvQueryContextData &ContextData) const override;
  • 获取EQS上级对应的Actor

    FEnvQueryInstance在EnvQueryTypes.h中

    1#include "EnvironmentQuery/EnvQueryTypes.h"
    2
    3const auto QueryOwner = Cast<AActor>(QueryInstance.Owner.Get());
  • 获取黑板组件

    通过转换EQS上级得到Pawn, 通过Pawn得到Controller; 指定组件类型, 通过Controller获取黑板组件

    1#include "Blueprint/AIBlueprintHelperLibrary.h"
    2#include "BehaviorTree/BlackboardComponent.h"
    3
    4const auto Blackboard = UAIBlueprintHelperLibrary::GetBlackboard(QueryOwner);
    5if (!Blackboard) return;
  • 获取黑板变量

    1const auto ContextActor = Blackboard->GetValueAsObject(EnemyActorKeyName);
  • 将黑板变量用作中心点

    1#include "EnvironmentQuery/Items/EnvQueryItemType_Actor.h"
    2
    3UEnvQueryItemType_Actor::SetContextHelper(ContextData, Cast<AActor>(ContextActor));
  • 完整实现

    ShootThemUp: AI/EQS/STUEnemyEnvQueryContext.cpp

     1#include "EnvironmentQuery/EnvQueryTypes.h"          
     2#include "Blueprint/AIBlueprintHelperLibrary.h"
     3#include "BehaviorTree/BlackboardComponent.h"
     4#include "EnvironmentQuery/Items/EnvQueryItemType_Actor.h"
     5
     6void USTUEnemyEnvQueryContext::ProvideContext(FEnvQueryInstance &QueryInstance, FEnvQueryContextData &ContextData) const
     7{
     8    const auto QueryOwner = Cast<AActor>(QueryInstance.Owner.Get());
     9
    10    const auto Blackboard = UAIBlueprintHelperLibrary::GetBlackboard(QueryOwner);
    11    if (!Blackboard) return;
    12
    13    const auto ContextActor = Blackboard->GetValueAsObject(EnemyActorKeyName);
    14    UEnvQueryItemType_Actor::SetContextHelper(ContextData, Cast<AActor>(ContextActor));
    15
    16}      
    

使用C++类STUEnemyEnvQueryContext


设置行为树

BT_STUCharacter

  1. 在环形点阵和距离限制条件中使用STUEnemyEnvQueryContext



  2. 恢复行为树框架, 移除Task


  3. 添加任务: RunEQSQuery - EQS_NextToEnemyLocation


  4. 添加任务: RunEQSQuery - EQS_RandomRoam


  5. 暂时移除Fire服务里目标: 点击恢复图标



查看

  • 按下 ' 打开调试界面

  • 选中AICharacter

  • 按下小写键盘 3 显示EQS

  • 当前存在两个EQS点阵, 按下小写键盘 * 显示当前EQS

    Project Settings > Engine > Gameplay Debugger


对于EQS的使用, 我们现在可以设置任意移动模板, 或者随机结合他们

  • 可以移除楼梯和模拟爆炸
  • 可以添加墙, 躲避NPC捕获