为什么你的 AI 总是“智障”?因为 EQS 没玩透
如果你还在用蓝图里一堆 Get All Actors Of Class 加 ForEachLoop 来让 AI 找掩体、找巡逻点、找玩家,那你的 AI 不仅卡成 PPT,行为还像喝了假酒。UE5 的环境查询系统(Environment Query System,简称 EQS)是官方给 AI 开的后门——它把“空间决策”从杂乱的 Actor 遍历中抽离出来,用生成器、测试、权重三件套,让 AI 像特种兵一样评估战场。但 90% 的人只用了它 10% 的功力。下面这 10 个技巧,每个都是我踩过坑、调过参、在项目里验证过的硬货。读完你不会再问“为什么我的 AI 不智能”,而是会问“为什么我没早点用 EQS”。

技巧一:用“环境查询上下文”解耦 AI 与场景,别把逻辑写死在控制器里
一句话核心:把 EQS 查询需要的 Actor 引用(比如玩家、巡逻路径点、资源点)通过 EnvQueryContext 蓝图或 C++ 子类注入,而不是在查询里硬编码 Get Player Character。
为什么有用:EQS 的测试项(Test)需要知道“相对于谁”来打分。如果你在测试里直接写死获取玩家,那这个查询就只能用于“找玩家附近的位置”。一旦你想让 AI 找“离最近队友最近的位置”或“离资源点最近的位置”,就得复制一堆查询。上下文(Context)是 EQS 的依赖注入,让同一个查询模板适配多种目标。
怎么操作:创建蓝图类继承 EnvQueryContext_BlueprintBase,重写 Provide Single Actor 或 Provide Actors Set。例如做一个 BP_Context_SquadLeader,返回小队队长的 Actor。然后在 EQS 测试项的 Context 参数里选这个自定义上下文。C++ 中则继承 UEnvQueryContext 并重写 ProvideContext。
效果展示:一个“寻找掩体”查询,通过切换上下文,能瞬间变成“寻找离队长 800 单位内的掩体”或“寻找离最近敌人最远的掩体”,复用率提升 300%。
注意:上下文返回的 Actor 集合大小直接影响性能,尽量用
Provide Single Actor而不是返回全场 Actor。
技巧二:生成器(Generator)不是随便撒点——用“路径网格”代替“圆形”做地面搜索
一句话核心:默认的 Actors Of Class 和 Simple Grid 生成器要么依赖场景物体,要么撒点不均匀;用 Pathing Grid 生成器基于导航网格(NavMesh)生成点,才是地面 AI 的正解。
为什么有用:Simple Grid 在斜坡、台阶、狭窄通道会生成悬空的点,AI 跑过去直接卡住或掉落。而 Pathing Grid 只会在 NavMesh 上生成点,并且可以通过 Grid Size 和 Generation Extent 控制密度和范围。它内部调用导航系统的投影函数,确保每个点都是“可到达”的。
怎么操作:在 EQS 查询里添加 Pathing Grid 生成器,设置 Grid Half Size(例如 1500),Space Between(例如 200)。勾选 Project Down 并设置 Post Projection Vertical Offset 为 50,让点贴合地面。配合 Don't Filter 或 Filter By Navigation 使用。
效果展示:AI 在复杂室内场景中找掩体,不再出现“看着点却跑不过去”的尴尬,路径成功率从 60% 提升到 98%。
技巧三:测试项权重叠加——用“归一化”让评分不再被单项绑架
一句话核心:每个测试项返回的原始分数范围不同(距离可能是 0-5000,可见性可能是 0-1),直接相加会导致某项主导结果;必须用 Normalize 或 Scoring Equation 把分数映射到 0-1 再乘权重。
为什么有用:EQS 的评分机制是“加权和”。假设你有“距离”测试(原始分 0-3000)和“可见性”测试(0-1),如果不归一化,距离的微小变化会淹没可见性。归一化后,你可以精确控制“我更在乎离得近还是更在乎不被看到”。
怎么操作:在测试项细节面板里,找到 Scoring Factor 和 Clamp Min/Max。推荐使用 Scoring Equation 为 Inverse Linear(距离越近分越高)或 Linear(距离越远分越高),并设置 Reference Value 为 2000 等。然后在 Weight 里调整重要性,总和不必为 1,EQS 会自动归一化权重。
效果展示:AI 选择掩体时,不再死板地选“最近的”而是选“距离适中且敌人看不到的”,行为更像真人。
| 测试项 | 原始分范围 | 归一化方法 | 推荐权重 |
|---|---|---|---|
| 距离 | 0-5000 | Inverse Linear, Clamp 0-1 | 0.6 |
| 可见性 | 0-1 | Bool 转 0/1 | 0.3 |
| 队友距离 | 0-3000 | Inverse Linear | 0.1 |

技巧四:用“预查询”和“查询缓存”干掉每帧重复计算
一句话核心:EQS 查询默认是异步的,但如果你在 Tick 里反复跑同一个查询,性能会崩;用 Run EQS Query 节点的 Query Template 配合 Cache 或 Query Request 的 Auto Run 模式,并设置合理的 Query Interval。
为什么有用:EQS 的生成和测试涉及大量射线检测和导航投影,单次查询在复杂场景可能耗时 1-2ms。如果 20 个 AI 每帧都跑,直接吃掉 40ms,游戏卡成幻灯片。缓存机制让查询结果在指定时间内复用。
怎么操作:在 AI 控制器里使用 Run EQS Query 节点,将 Run Mode 设为 EQS Query Run Mode::Single Result 或 All Results,并勾选 Use Query Cache。更高级的做法是创建 EnvQueryManager 的 C++ 调用,设置 QueryConfig 的 GenerationActors 和 TestMode。在 Project Settings > AI System > EQS 里调整 Max Allowed Queries Per Frame。
效果展示:20 个 AI 的 EQS 开销从 35ms 降到 4ms,帧率稳定 60fps。
技巧五:用“自定义测试”实现“视线遮挡预判”和“动态威胁评估”
一句话核心:内置测试不够用?继承 EnvQueryTest 写 C++ 或蓝图测试,实现“预测玩家 1 秒后的位置是否可见”或“该点是否在多个敌人火力交叉区”。
为什么有用:EQS 内置测试(如 Trace、Distance、Pathfinding)是通用型,但战术 AI 需要领域知识。自定义测试让你把游戏逻辑封装成可复用的评分项。
怎么操作:C++ 中继承 UEnvQueryTest,重写 RunTest 函数,使用 FEnvQueryInstance 获取当前测试项的所有 Item,对每个 Item 执行自定义计算(如发射预测射线),然后 SetScore。蓝图则继承 EnvQueryTest_BlueprintBase,实现 DoItemScore 事件。
效果展示:AI 不再傻傻地躲在“当前”看不见的掩体后,而是躲到“玩家下一秒也看不到”的位置,生存率提升 40%。
自定义测试中避免每帧做复杂物理查询,可以用
Async Trace或降低测试频率。
技巧六:用“调试可视化”看穿 AI 的脑回路,别靠猜
一句话核心:按 ' 键打开控制台,输入 ai.eqs.debug 1 或 ShowDebug EQS,实时查看生成点、测试分数和最终选择。
为什么有用:EQS 的评分是黑盒,你以为是距离问题,其实是某个测试项返回了负分。可视化能直接显示每个点的分数颜色(绿高红低)和测试详情。
怎么操作:在 PIE 运行中,控制台输入 ai.eqs.debug 1 开启调试绘制。更精细的用 ai.eqs.debug 2 显示每个测试项的分数。还可以在 EnvQueryManager 中设置 Debugger 断点。对于打包版本,用 Gameplay Debugger 的 EQS 分类。
效果展示:一眼看出“为什么 AI 选了那个烂点”——原来是 Pathfinding 测试的 Cost 计算把好点过滤了。
技巧七:用“查询模板”和“数据资产”做模块化,别复制粘贴
一句话核心:把常用的生成器+测试组合保存为 EnvQueryTemplate 资产,在不同 AI 之间共享;用 Data Asset 存储上下文和参数,实现“一次修改,全局生效”。
为什么有用:项目里可能有步枪兵、狙击手、医疗兵,他们找掩体的逻辑相似但参数不同。如果每个都复制一份 EQS 查询,维护噩梦。模板+数据资产让参数外置。
怎么操作:创建 EnvQueryTemplate 资产,在 Query Template 里引用。然后创建 PrimaryDataAsset 子类,暴露 GridSize、Weight 等变量。在 AI 蓝图中,用 Run EQS Query 时通过 Query Config 覆盖参数。
效果展示:调整所有 AI 的搜索半径,只需改一个数据资产,不用碰任何查询。
技巧八:用“EQS 与行为树”的异步协作,避免阻塞
一句话核心:在行为树中用 Run EQS Query 任务节点,并设置 Run Mode 为 Async,让 AI 在等待查询结果时继续执行其他分支。
为什么有用:同步查询会卡住行为树,AI 变成木头人。异步查询让 AI 可以边移动边评估,或者同时处理多个查询。
怎么操作:行为树中添加 Run EQS Query 任务,Query Template 选好,Run Mode 选 Async,并设置 Blackboard Key 存储结果。然后在 On Query Finished 事件里处理。注意处理查询失败或超时。
效果展示:AI 在奔跑中不断重新评估最佳掩体,而不是跑一步停一秒。
技巧九:用“权重曲线”做动态偏好,让 AI 性格迥异
一句话核心:不要用固定权重,用 Curve Float 资产驱动测试项的 Weight,根据 AI 血量、弹药量、士气值动态调整。
为什么有用:同一个 EQS 查询,血量高时 AI 偏好“冲锋点”(距离近权重高),血量低时偏好“撤退点”(距离远但安全权重高)。曲线让行为有层次。
怎么操作:在测试项的 Weight 参数里,点击下拉选择 Curve Float 资产。然后创建曲线,X 轴为血量百分比,Y 轴为权重乘数。在 AI 蓝图中,通过 Set Float Curve 或直接修改曲线资产的值(运行时用 Dynamic Material 思路,但 EQS 支持 Weight 绑定到 Blackboard 变量)。
效果展示:残血 AI 会突然变得“怂”,躲到更远的掩体,玩家能直观感受到 AI 的求生欲。
技巧十:性能压榨——用“查询预算”和“分帧”控制大规模 AI
一句话核心:在 Project Settings > AI System > EQS 中设置 Max Allowed Queries Per Frame 和 Query Budget,并利用 EnvQueryManager 的 TimeSlice 机制,让 EQS 查询分帧执行。
为什么有用:100 个 AI 同时查询,即使每个 0.5ms,也是 50ms 的尖峰。分帧让查询排队,平滑 CPU 负载。
怎么操作:调整 Max Allowed Queries Per Frame 为 4-8,Query Budget 为 2-4ms。在 C++ 中可以用 UEnvQueryManager::RunQuery 的 FEnvQueryRequest 设置 QueryPriority。另外,用 EQS Query Template 的 Generation 设置 Max Points 限制生成点数量。
效果展示:100 个 AI 的 EQS 总耗时稳定在 3ms 以内,帧率波动小于 1ms。

行业案例:从“呆瓜”到“战术大师”的蜕变
在某款第三人称射击游戏中,敌方 AI 原本使用简单的“最近玩家”逻辑,玩家躲在掩体后就能无伤刷怪。接入 EQS 后,我们做了三件事:用 Pathing Grid 生成掩体点,用自定义测试评估“玩家可见性”和“队友火力覆盖”,用曲线权重让 AI 在血量低时优先撤退。结果:AI 的击杀/死亡比从 0.8 提升到 1.6,玩家反馈“敌人像真人一样会包抄”。更重要的是,EQS 查询的 CPU 开销只占 AI 总预算的 15%,因为用了缓存和分帧。
如果你也想做出这种级别的 AI,光看文档不够,得有人带你拆解底层机制。火星人教育,创办 24 年来专注数字艺术与 AIGC 实战职业技能培训,开设课程包括 AI 漫剧创作、AIGC 视觉设计、UE5 游戏特效、室内全屋定制、MAYA 三维动画、C4D 动态设计、工业设计、NUKE 影视后期、摄影摄像实训。北京、深圳双校区开设线下面授班,面向美术生、在校大学生及意向转行的职场人群,以项目化实训教学,夯实专业技能,助力就业与职业提升。咨询电话:010-65918670。想让你的 AI 从“智障”变“智将”,来火星人,我们手把手教你。








评论(0)