第9章 AI与行为树系统
AI与行为树系统是创建智能角色和NPC的核心技术。本章将深入探讨UE5的AI系统,包括行为树、黑板、感知系统、导航系统等高级功能。
9.1 AI系统概述
UE5的AI系统提供了一套完整的工具链,用于创建智能角色、NPC和敌人,实现自主行为和决策。
9.1.1 核心概念
- AI控制器 (AI Controller):控制AI角色的大脑
- 行为树 (Behavior Tree):定义AI行为的可视化流程图
- 黑板 (Blackboard):存储AI决策所需的共享数据
- 感知系统 (Perception System):让AI感知周围环境
- 导航系统 (Navigation System):实现AI的路径规划和移动
- 环境查询系统 (EQS):用于AI的环境分析和决策
9.1.2 AI系统的组成
UE5的AI系统由多个相互协作的模块组成:
- 控制模块:AI Controller和Pawn
- 决策模块:行为树和黑板
- 感知模块:AIPerception组件
- 移动模块:导航系统和MoveComponent
- 环境分析:EQS系统
9.2 AI控制器与Pawn
9.2.1 AI Controller
AI Controller是控制AI角色行为的核心组件,负责决策和控制。
-
创建AI Controller
-
右键点击内容浏览器→蓝图→蓝图类
- 选择父类"AIController"
- 命名并保存
-
AI Controller的核心功能
-
Possess/Unpossess:控制/释放Pawn
- 行为树管理:启动、暂停、重置行为树
- 导航控制:控制Pawn的移动
- 事件处理:处理AI相关事件
9.2.2 Pawn
Pawn是AI控制器可以控制的游戏实体,包含物理、渲染和输入等组件。
-
AI Pawn的特点
-
通常包含网格体、碰撞体和动画组件
- 必须有移动组件(如CharacterMovementComponent)
- 可以添加感知组件
-
设置AI Pawn
-
创建Pawn蓝图
- 添加必要的组件
- 设置碰撞属性
- 配置移动组件
9.2.3 AI Controller与Pawn的关系
- 一个AI Controller可以控制一个Pawn
- 一个Pawn可以被多个AI Controller控制(但一次只能一个)
- AI Controller负责决策,Pawn负责执行
9.3 行为树 (Behavior Tree)
行为树是一种可视化的AI决策系统,使用树形结构定义AI的行为逻辑。
9.3.1 行为树的基本结构
行为树由节点组成,节点分为以下几类:
- 根节点 (Root):行为树的起点
-
组合节点 (Composite Nodes):控制子节点的执行顺序
-
序列 (Sequence):按顺序执行子节点,直到一个失败
- 选择器 (Selector):按顺序执行子节点,直到一个成功
- 并行 (Parallel):同时执行多个子节点
-
装饰器节点 (Decorator Nodes):修饰子节点的执行
-
条件检查:如"IsEnemyNearby"
- 循环控制:如"Loop"
- 概率控制:如"Chance"
-
服务节点 (Service Nodes):在行为树执行期间提供持续服务
-
更新黑板数据:如"UpdatePlayerLocation"
- 状态检查:如"CheckHealth"
- 定时任务:如"PatrolTimer"
-
任务节点 (Task Nodes):执行具体的AI行为
-
移动任务:如"MoveTo"
- 攻击任务:如"Attack"
- 等待任务:如"Wait"
- 自定义任务:用户创建的任务
9.3.2 创建行为树
-
创建行为树资产
-
右键点击内容浏览器→AI→行为树
- 命名并保存
-
创建黑板资产
-
右键点击内容浏览器→AI→黑板数据
- 命名并保存
- 在行为树的属性中关联黑板
-
编辑行为树
-
双击打开行为树编辑器
- 从节点面板拖拽节点到工作区
- 连接节点构建行为逻辑
- 设置节点属性
9.3.3 行为树的执行流程
- 初始化:行为树开始执行前的准备工作
- 更新:每帧执行一次行为树逻辑
- 节点执行:
- 从根节点开始
- 按组合节点的规则执行子节点
- 装饰器节点决定子节点是否可以执行
- 服务节点在子树执行期间持续运行
- 任务节点执行具体行为并返回结果(成功/失败/运行中)
- 完成:行为树执行完毕
9.4 黑板 (Blackboard)
黑板是AI系统的共享数据存储,用于在行为树的各个节点之间传递信息。
9.4.1 黑板的组成
- 键 (Key):数据的唯一标识符
- 值 (Value):键对应的数据内容
- 类型 (Type):数据的类型(如Vector、String、Object等)
9.4.2 创建和配置黑板
-
添加黑板键
-
双击打开黑板资产
- 点击"添加键"按钮
- 选择键类型
- 设置键名称和默认值
-
常用黑板键类型
-
Object:引用游戏对象(如PlayerCharacter)
- Vector:3D位置(如PlayerLocation)
- Bool:布尔值(如IsPlayerDetected)
- Float:浮点值(如DistanceToPlayer)
- String:字符串(如CurrentState)
- Enum:枚举类型(如EnemyType)
9.4.3 在行为树中使用黑板
-
读取黑板数据
-
在节点的属性中选择黑板键
- 或使用"Get Blackboard Value as [Type]"节点
-
写入黑板数据
-
使用"Set Blackboard Value as [Type]"节点
- 或在服务节点中更新黑板数据
-
黑板观察者
-
节点可以观察黑板键的变化
- 当黑板键变化时,节点可以重新评估
9.5 感知系统 (Perception System)
感知系统让AI能够感知周围环境中的其他 actors,如玩家、敌人或物体。
9.5.1 感知系统的核心组件
- AIPerceptionComponent:添加到AI Controller或Pawn上
- AIPerceptionStimuliSourceComponent:添加到可被感知的 actors上
- 感知组件 (Sense Components):如视觉、听觉、触觉等
9.5.2 配置感知系统
-
添加AIPerceptionComponent
-
打开AI Controller或Pawn蓝图
- 添加"AIPerception"组件
-
配置感知组件
-
视觉感知 (Sight):
- 检测距离
- 视野角度
- 是否能看到障碍物
- 目标优先级
- 听觉感知 (Hearing):
- 听力范围
- 声音强度
- 衰减系数
- 触觉感知 (Touch):
- 碰撞检测
- 接触响应
-
设置刺激源
-
打开可被感知的 actor蓝图
- 添加"AIPerceptionStimuliSource"组件
- 启用所需的感知类型
- 配置刺激属性
9.5.3 处理感知事件
-
绑定感知更新事件
-
在AIPerceptionComponent的"OnTargetPerceptionUpdated"事件上绑定处理函数
- 或在AI Controller的事件图表中处理
-
获取感知信息
-
获取感知目标列表
- 获取目标的感知数据(如距离、最后感知时间、感知强度等)
- 过滤感知结果
-
更新黑板
-
将感知结果更新到黑板
- 如:设置"PlayerCharacter"、"PlayerLocation"、"IsPlayerDetected"等
9.6 导航系统
导航系统实现AI的路径规划和移动,让AI能够在复杂环境中自主导航。
9.6.1 导航系统概述
UE5的导航系统由以下组件组成:
- 导航网格体 (NavMesh):表示可导航区域的网格
- 导航数据:存储导航网格体的资产
- 导航查询系统:用于路径规划的接口
- 移动组件:执行实际移动的组件
9.6.2 配置导航系统
-
启用导航系统
-
在项目设置中启用导航系统
- 配置默认导航类
-
生成导航网格体
-
打开关卡
- 点击"构建"按钮(或按F11)
- 导航系统会自动生成导航网格体
-
导航区域设置
-
导航区域类:定义不同区域的导航属性
- 导航标签:用于标识特定区域
- 区域成本:影响AI的路径选择
9.6.3 使用导航系统
-
基本移动
-
使用"MoveTo"节点在行为树中移动
- 设置目标位置或目标actor
- 配置移动参数(速度、加速度、停止距离等)
-
高级导航功能
-
路径跟随:跟随指定路径
- 避障:避开动态障碍物
- 跳点:跳转到指定位置
- 移动模式:步行、跑步、游泳、飞行等
-
导航查询
-
FindPathToLocationSynchronously:同步寻找路径
- ProjectPointToNavigation:将点投影到导航网格上
- LineOfSightTo:检查视线是否通畅
9.7 环境查询系统 (EQS)
环境查询系统用于AI的环境分析和决策,帮助AI找到最佳的交互位置或目标。
9.7.1 EQS的基本概念
EQS允许AI:
- 分析周围环境
- 评估多个候选位置
- 选择最佳位置
9.7.2 创建EQS查询
-
创建EQS查询资产
-
右键点击内容浏览器→AI→环境查询
- 命名并保存
-
编辑EQS查询
-
生成器 (Generator):生成候选位置(如圆形、网格、射线等)
- 测试 (Test):评估候选位置(如距离、可见性、覆盖范围等)
- 评分 (Scoring):计算候选位置的总分
- 过滤器 (Filter):过滤不符合条件的候选位置
-
常用EQS生成器
-
Sphere Generator:在球形区域内生成点
- Grid Generator:在网格上生成点
- Path Generator:沿着路径生成点
- Actors Of Class Generator:生成指定类的actor位置
-
常用EQS测试
-
Distance Test:距离测试
- Dot Product Test:方向测试
- Line Of Sight Test:视线测试
- Navigation Test:导航测试
- Overlap Test:重叠测试
9.7.3 在行为树中使用EQS
-
使用EQS Query节点
-
在行为树中添加"Run EQS Query"节点
- 设置查询资产
- 配置查询参数
- 将结果存储到黑板
-
处理EQS结果
-
从黑板获取EQS结果
- 使用结果进行决策(如移动到最佳位置)
9.8 行为树节点开发
9.8.1 自定义任务节点
-
创建自定义任务节点
-
右键点击内容浏览器→蓝图→蓝图类
- 选择父类"BTDecorator_BlueprintBase"(装饰器)或"BTService_BlueprintBase"(服务)或"BTTask_BlueprintBase"(任务)
- 命名并保存
-
任务节点的核心函数
-
ReceiveExecuteAI:执行任务时调用
- ReceiveAbortAI:任务被中止时调用
- FinishExecute:任务执行完毕时调用(返回成功/失败)
- 示例:自定义攻击任务
``` // 伪代码 ReceiveExecuteAI(OwnerController, ControlledPawn) { // 获取目标 Target = GetBlackboardValueAsObject("TargetActor")
// 检查目标是否有效
if (!Target.IsValid()) {
FinishExecute(false)
return
}
// 执行攻击
if (PerformAttack(Target)) {
FinishExecute(true)
} else {
FinishExecute(false)
}
} ```
9.8.2 自定义装饰器节点
-
装饰器节点的作用
-
条件检查:决定子树是否可以执行
- 重复控制:控制子树的执行次数
- 概率控制:基于概率决定是否执行子树
- 示例:距离装饰器
``` // 伪代码 CalculateRawConditionValue(OwnerController, ControlledPawn) { // 获取玩家位置 PlayerLocation = GetBlackboardValueAsVector("PlayerLocation")
// 计算距离
Distance = FVector::Distance(ControlledPawn.GetActorLocation(), PlayerLocation)
// 检查距离是否在范围内
return Distance < MaxDistance && Distance > MinDistance
} ```
9.8.3 自定义服务节点
-
服务节点的作用
-
持续更新黑板数据
- 监控AI状态
- 处理定时任务
- 示例:更新玩家距离服务
``` // 伪代码 ReceiveTickAI(OwnerController, ControlledPawn, DeltaSeconds) { // 获取玩家 Player = GetBlackboardValueAsObject("PlayerCharacter")
if (Player.IsValid()) {
// 计算距离
Distance = FVector::Distance(ControlledPawn.GetActorLocation(), Player.GetActorLocation())
// 更新黑板
SetBlackboardValueAsFloat("DistanceToPlayer", Distance)
// 检查是否在感知范围内
if (Distance < PerceptionRange) {
SetBlackboardValueAsBool("IsPlayerInRange", true)
} else {
SetBlackboardValueAsBool("IsPlayerInRange", false)
}
}
} ```
9.9 AI调试与优化
9.9.1 AI调试工具
-
行为树调试器
-
实时查看行为树的执行状态
- 显示当前执行的节点
- 查看黑板数据
-
感知调试
-
可视化AI的感知范围
- 显示感知到的目标
- 调试感知组件
-
导航调试
-
显示导航网格体
- 可视化路径
- 调试导航查询
9.9.2 AI性能优化
-
减少AI数量
-
使用LOD系统减少远处AI的复杂度
- 使用触发体积控制AI的激活/休眠
- 合并相似的AI行为
-
优化行为树
-
简化行为树结构
- 减少节点数量
- 避免深度嵌套
- 使用服务节点代替频繁的条件检查
-
优化感知系统
-
减少感知范围
- 降低感知更新频率
- 只启用必要的感知类型
- 使用感知刺激源的距离衰减
-
优化导航系统
-
简化导航网格体
- 减少导航查询频率
- 使用导航缓存
- 避免频繁的路径重新计算
-
内存优化
-
共享行为树和黑板资产
- 减少黑板键的数量
- 延迟加载AI资源
思考与练习
- UE5 AI系统的核心组件有哪些?包括AI Controller、行为树、黑板等。
- 如何创建和配置AI Controller和Pawn?它们之间的关系是什么?
- 行为树的基本结构是什么?包括哪些类型的节点?
- 黑板的作用是什么?如何创建和使用黑板?
- 感知系统的核心组件是什么?如何配置和使用感知系统?
- 导航系统的作用是什么?如何生成和使用导航网格体?
- EQS系统的作用是什么?如何创建和使用EQS查询?
- 如何创建自定义的行为树节点?包括任务节点、装饰器节点和服务节点。
- AI性能优化的技巧有哪些?从行为树、感知系统、导航系统等方面分析。
- 设计一个简单的敌人AI,包括巡逻、追击、攻击和逃跑行为。