版权声明:本文为CSDN博主「蓬 蒿 人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
下面用行为树创建一个简单的 AI 角色,没有玩家靠近时随机巡逻,当有玩家角色靠近时跑到玩家附近,模拟游戏中怪物攻击玩家的行为(没有实际的攻击动作),是官方示例的简化版,官方完整实例参考
具体步骤
1、创建 第三人称 模板蓝图工程
2、创建 AI 角色,选择第三人称角色 骨骼 和 动画,命名为 AICharacter
创建行为树和黑板及其变量
3、在内容浏览器中,右键创建 BehaviorTree 资源,命名为 BT_AI ,然后创建 Blackboard 资源,命名为 BB_AI ,用于存放行为树使用的变量
4、打开黑板 BB_AI ,创建三个变量 NearToPlayer : bool(是否有玩家靠近),RandomLocation : Vector(随机走动位置)和 Player : Object(靠近的玩家),Player 的 BaseClass 选择 Actor
行为树的设计
5、打开行为树 BT_AI ,选中 ROOT 节点,将 BlackboardAsset 设置为 BB_AI
6、从 ROOT 拖出引脚选择 Selector 创建一个 选择器节点 命名为 AIRoot,作为 AI 角色执行行为的根节点
Selector、Sequence 和 SimpleParallel 的详细说明见官方文档。
- 简单地说 Selector 就像
if-else的 if 语句,从左往右执行一系列节点,有一个节点执行成功就不往下执行; - 而 Sequence 是在有节点执行失败时就不往下执行了。
- Simple Parallel 则是一个在主任务执行的同时也会执行的一个活动(并行),而且它会随着主任务的结束而结束。
Selector、Sequence 和 SimpleParallel 属于 Composites,类似于编程中的 流程控制语句 ,还有一类节点属于 Tasks,是 实际执行的动作 。
7、通过 拖动 或 右键 从左到右分别添加下列节点,
AttackPlayer为 Sequence 节点,在玩家靠近 AI 时,执行 AI 角色攻击玩家的行为,Patrol为 Sequence 节点,在没有玩家靠近时随机巡逻,Wait属于 Tasks ,在前面两个节点执行失败时等待指定的时间
8、在 AttackPlayer 上右键,移到 AddDecorator 菜单,选择Blackboard,添加 黑板类的装饰器
9、选中装饰器,
- 在右侧 Blackboard Key 属性选择 NearToPlayer,这个装饰器就是一个 条件语句,能判断
NearToPlayer变量是否置为true,如果是 就会执行该节点; - Observer aborts 选择 both ,即
NearToPlayer改变时,中止 本身和任何低优先级 的任务,转而执行Patrol; - Key Query 选择 Is Set ,当
NearToPlayer变为true时会执行该节点;
最后改一下 NodeName。
10、在 AttackPlayer 和 Patrol 节点下添加 Move To 任务节点 【Move To 的作用:移动到一个黑板键的目标位置】,
- 当(
AttackPlayer)要攻击玩家的时候调用Move To移动到玩家的位置,这个Move To选择 Player; Patrol下的Move To选择 RandomLocation ;Patrol下在添加一个Wait,到达一个巡逻位置后等待 2 ~ 4 秒的时间
任务蓝图的设计
11、上面的 Patrol 节点下 Move To 的目标位置并没有设置,我们要新建一个任务更新 RandomLocation 的值,点击 NewTask 按钮新建一个任务蓝图,保存为BTTask_FindLocation
12、在上面新建的任务蓝图中,选择重载 RecevieExecuteAI 事件
13、按下图连接蓝图节点
- 首先判断
ControlledPawn是不是AICharacter,如果是的话,就使用GetRandomReachablePointInRadius获取一个半径为 500 的范围内的随机位置; - 接着将上一步的位置通过
SetBlackboardAsVector设置给黑板中的RandomLocation; - 接着在该节点的
Key引脚上右键选择 提升为变量,新建一个黑板键类型的变量,命名为RandomLocationKey,并勾选 Instance Editable 属性(或者点击变量后的眼睛),使之能在行为树中修改, - 最后添加
FinishExecute,勾选 Success 表示该任务执行成功,否则执行失败,
14、在行为树中点击 右键 找到刚新建的任务,并添加
15、如下图所示,将 RandomLocationKey 设置为 RandomLocation
AI Controller 中更新黑板中的变量
16、到此为止,行为树的部分都完成了,但是上面 NearToPlayer 和 Player 变量都还没有更新,这两个值在控制器中完成,新建一个蓝图类,基类选择 AIController,命名为 Controller_AI,打开该蓝图,添加 AIPerception 组件
17、选中 AI Perception 组件设置 Senses Config 属性,我们只要 视觉感知 ,所以添加一个 AI Sight config 配置,调整视野范围 Sight Radius 和 Lose Sight Radius ,勾选 Detect Neutrals ,没有特殊设置应该都是 中立生物 ,所以要勾选。
18、添加 OnTargetPerceptionUpdated 事件处理函数
19、按下图连接蓝图节点,
OnTargetPerceptionUpdated中判断感知的角色是不是ThirdPersonCharacter,如果是的话,就将NearToPlayer设置为true, 接着将Player设置为 感知到的玩家 ,Blackboard能在AIController中直接获取,NearToplayer和Player变量为 Text 类型,分别是 黑板中对应变量的名称 。- 在
OnPossess事件中调用RunBehavior Tree运行 BT_AI 行为树
最后一些细节
20、上面创建的所有资源如下图所示
21、将 AICharacter 拖入关卡中,AIControllerClass 选择 Controller_AI
22、最后别忘了将 NavMeshBoundsVolume 体积拖入关卡,使其包围所有 AICharacter 可能行走的区域
结语
一个简单的 AI 角色就完成了,当玩家靠近他时,他会朝玩家跑过去;远离他时,他会自己在随机的位置来回跑。更完整的例子可以看官方文档。