允许开火的装饰器
BTDecorator_AllowedToFire

这个就是编辑器设置里面那个,机器人是否能开火的开关
开火的 Service

TODO 本来这里还要拿到枪和子弹,但是为了快速跑通,先跳过一下。初始换了把子弹多的步枪
SetFocus

SetFocus 是外部传入的,Target Ennemy 也是行为树那里关联引用
攻击跑通

比较神奇,AI直接把我打死了,按event触发开火,然后打中玩家。
AI是怎么瞄准我的呢???
FTransform UEqZeroGameplayAbility_RangedWeapon::GetTargetingTransform(APawn* SourcePawn, EEqZeroAbilityTargetingSource Source) const
{
// 根据枚举。决定子弹从哪里发出来、射向哪里
}
射线从 SourcePawn->GetActorLocation() + FVector(0, 0, SourcePawn->BaseEyeHeight);
方向 Controller->GetControlRotation(); // 这里是AIController
同样受到散布的影响
寻找最佳射击位置
/ShooterCore/Bot/EQS/EQS_MoveAgainstEnnemy.EQS_MoveAgainstEnnemy
创建
/EqZeroCore/Bot/EQS/Context/EQS_Context_TargetEnemy.EQS_Context_TargetEnemy
实现 Provide Single Locatjion

如何理解EQS Context
EQS Context = "从谁的视角做查询"
EQS 查询里有两个核心问题:
- 生成哪些候选点/Actor(Generator)
- 相对于谁来评估这些候选(Context)
【Context 就是第 2 个问题的答案。】
常见内置 Context:
EnvQueryContext_Querier 发起查询的那个 AI 自己
EnvQueryContext_Item 当前正在被评估的候选项本身
===
Lyra其他EQS Context
EQS_Context_ControlPoints 找控制点,暂时跳过
EQS_Context_WeaponCheck 找武器的
- 蓝图连的比较难看,大概逻辑是遍历常见中所有的武器点,如果自己子弹不满,就把这个武器点加到数组里面


EQS_MoveAgainstEnnemy
回来
EQS 查询里有两个核心问题:
- 生成哪些候选点/Actor(Generator)
- 相对于谁来评估这些候选(Context)

写完是这样
如何理解EQS呢?
Generator → Tests(筛选+打分)→ 最佳 Item
EQS 的核心逻辑就三步:
-
Generator 生成一堆候选点(Items)
-
Tests 逐个淘汰或打分
-
引擎选出得分最高的 Item
-
SimpleGrid: generate around Querier
Querier = 执行这个查询的 AI(也就是 Bot 自己)。
SimpleGrid 以 Querier 为中心,生成一个平面网格的点阵:
- Radius 400 以 Bot 为圆心,半径 400cm(4米)的圆形范围
- Space Between 150 每两个点之间间隔 150cm
- Projection Height 1024 把所有点投影到 NavMesh 上(向下搜索最多 1024cm 高度差)
所以它大概生成了一个 ~5x5 的点阵(约 20-25 个候选点),都在 Bot 脚边附近。这些点就是 Items。
- 三个 Test(按顺序执行)
Test 1: PathExist — from Item
- 作用:检查从 Bot 能不能沿 NavMesh 走到这个 Item
- Filter Only(筛选不打分):discard unreachable = 走不到的直接淘汰
- 这是性能优化,先把不可达的点干掉,后面的 Test 就少算了
Test 2: Trace — to EQS_Context_TargetEnemy on Camera
- 作用:从 Item 位置向
EQS_Context_TargetEnemy(敌人位置)做一条 Line Trace(射线检测) on Camera= 使用 Camera 高度偏移(模拟视线高度)- 意义:检查从这个候选点能不能"看到"敌人(没有墙挡着)
constant score [x1]= 看得到就 +1 分,看不到就 0 分(或被淘汰)
Test 3: Distance — to EQS_Context_TargetEnemy
- 作用:计算每个 Item 到敌人的距离
at least 5000= 距离低于 5000cm(50米)的直接淘汰(Filter)prefer greater [x1]= 距离越远得分越高
这个 Test 的实际效果是:在能看到敌人的前提下,尽量选一个离敌人稍远一点的位置(往后退一步而不是冲上去)

回来行为树

完成这个
左边这个Run Mode 意思是
选出排名前5%的,然后随机一个。
EQS_FindTarget
| Generator | 生成什么 | 典型用途 |
|--------------------|--------------------------------------------------|--------------------------------------------------------------|
| Actors Of Class | 场景中指定类的所有 Actor 实例 | "找到所有弹药箱"、"找到所有掩体Actor" |
| Composite | 组合多个 Generator 的结果 | 同时用 Grid + ActorsOfClass,合并候选点 |
| Current Location | 就一个点:Querier 当前位置 | 配合 Test 做"原地评估"(比如判断当前位置是否安全) |
| Perceived Actors | AI Perception 已感知到的 Actor | "找到我能看到的所有敌人"——直接用感知结果而非全场搜索 |
| Points: Circle | 围绕某个 Context 生成一圈等距点 | 围绕敌人找包抄位置、环形巡逻点 |
| Points: Cone | 在某个方向的锥形范围内生成点 | 在 Bot 前方扇形区域找射击位置 |
| Points: Donut | 内外两个半径之间的环形区域生成点 | "不要太近也不要太远"的位置搜索 |
| Points: Grid | 正方形网格点阵(就是你在用的 SimpleGrid) | 通用的位置搜索,最常用 |
| Points: Pathing Grid | 只在 NavMesh 可达区域生成网格点 | 比 Grid 更智能,直接排除了不可达点,但开销更大 |
这里有个 EQS_GetAllEnemy: around Querier 找不到
/EqZeroCore/Bot/EQS/Generator/EQS_GetAllEnemy.EQS_GetAllEnemy
父类是 Env Query Context Blueprint Base

拿到除了查询的 AI自己的 Character

获取Actor后距离越近的权重越高。
BUG1

Bot在原地,一会跑一次红色的流程,然后开一枪,有时候也不开枪。我这是写出什么东西了?

问题是,原来默认参数是近的一段红色,所以在比较近的地方EQS没有返回。
EQS_FindWeapon

从 Context 拿到武器,然后根据距离和可达性打分和过滤
问题:他不跑 Search Weapon呀,是不是扫出来没有武器。
由于BOT还不会换子弹,备用弹夹一直有子弹。
加个换子弹,就一个Event的Service就行。
还缺一个自动换弹技能。通过换弹的service,我们躲一下让机器人换弹。这样打子弹,
补充后大概是这样。

BUG:死亡后准星不见了

漏了一条线呀?