UE4官方行为树快速入门文档解析和修改
近学习了UE4官方文档的行为树快速入门指南,发现里面的部分逻辑稍稍有点混乱和重叠,于是加入了自己的想法,修改了部分行为树逻辑,优化了其AI寻路能力。
初始的基本操作和资源创建同官方文档一样:1个Follower_AI_CON即AI控制器,1个FollowerBT行为树,1个FollowBlackboard黑板,1个Character蓝图资源AI_Character。

打开FollowBlackboard黑板资源,创建1个TargetToFollow的Object变量,1个HomeLocation的Vector变量,1个TargetLocation的Vector变量,保存后退出。

打开Follower_AI_CON控制器,创建1个HomeLocation的Name变量,编写蓝图节点逻辑

添加EventBeginPlay事件,绑定黑板资源为FollowBlackboard,设置HomeLocation变量存储AI_Character的初始坐标(Target为黑板自身,KeyName为Name变量HomeLocation,VectorValue为AI控制器下Pawn的ActorLocation),之后运行行为树FollowerBT。

打开AI_Character蓝图,在Mesh中指定人物骨骼和角色动画蓝图,选中Components窗口的AI_Character(self),在Pawn选项中指定AIControllerClass为Follower_AI_CON,这样在创建AI_Character实例时,会自动创建1个AI控制器。

打开FollowerBT行为树,点击NewService,创建一个AgroCheck业务,前面的逻辑和官方文档一样,添加Branch节点判断AI控制器的引用AI_CON_Ref是否为空,空则将EventReceiveTick的OwnerActor输入参数强制转换成目标AI控制器后赋值给AI_CON_Ref。之后获取到场景中的所有AI_Character(在目标检测中作为忽略Actor目标,防止AI_Character互相检测导致混乱);获取到AI控制器下Pawn的ActorLocation作为目标检测的圆心(同时设置为MyLocation),Z轴添加15单位作为球体检测的半径终点,辐射半径设为1000作为目标检测的范围,检测的目标种类拖选成数组后设置为Pawn(即只会检测到类型为Pawn的目标)。


个人觉得接下来官网教程的蓝图逻辑有些不合适。官网上将目标检测的结果循环遍历,创建一个射线检测,MyLocation为起点,目标检测到的Actor为终点(即二次检测),别忘了Actor to Ignore连接到AI_Character。将射线检测的结果Actor和目标检测的结果Actor进行比较,结果作为Branch节点的判断依据,相同则将该Actor设为TargetToFollow,并将其Location设为TargetLocation;不相同则将TargetToFollow设为空值。


个人觉得不合理的地方如下:
1.对目标进行的二次检测重复多余,且没有意义,相当于将一个数组中的元素与数组中的所有元素进行比较(包括自身比较自身,且逻辑上两两比较了两遍),增加了逻辑复杂度和时间复杂度,导致的结果是之后的Branch节点频繁被调用,双分支(True,False)一直在重复执行;
2.并没有突出检测到的目标为正确寻路目标,而是使得所有在检测范围内的Pawn都符合寻路条件,AI_Character会将检测到的第一个Pawn作为跟踪对象;
3.目标监测范围内没有Pawn时,数组为空,导致之后的Branch节点不会执行。
所以我在官方文档的基础上加入了自己的想法,更改后的蓝图逻辑如下:

对目标检测的输出进行Branch判断,检测到Pawn目标时进行数组循环遍历,没有Pawn目标时直接对TargetToFollow赋值为空。对HitResult的Actor进行强制类型转换,转换成PlayerCharacter(玩家控制的角色),转换成功则表示玩家进入AI_Character的检测范围,并将玩家设置为TargetToFollow,玩家的Location设置为TargetLocation。
打开FollowerBT行为树,点击NewDecorator创建一个CloseEnough的Decorator,

将输入参数OwnerActor强制转换为Follower_AI_CON,赋值给AI_CON_Ref,连接到输出节点,添加1个Boolean输出参数,将TargetToFollow的Location减去AI控制器下Pawn的Location(即AI_Character和目标之间的距离)和预设距离进行比较,大于等于预测距离(即两者距离太远)则为True(继续执行Decorator下的逻辑),否则停止之后的逻辑。
打开FollowerBT行为树,点击NewTask,创建1个RapidMoveTo的任务,

首先进行AI_CON_Ref的非空判断,为空则将OwnerActor强制转换成Follower_AI_CON赋值给它,不为空则进行AIMoveTo,Pawn为AI控制器下的Pawn(即AI_Character),TargetActor为TargetToFollow。移动成功后结束此次行为树任务。
最终的行为树运行逻辑如下:

AgroCheck的刷新Tick为0.5s,TargetToFollow和TargetLocation分别对应于黑板资源的同名参数,之后进入分支判断,TargetToFollow非空则进入左侧,AI_Character和目标的距离大于100则进行RapidMoveTo任务;TargetToFollow为空则进入右侧分支,判断AI_Character是否位于TargetLocation,及TargetLocation是否为空,如果AI_Character已经到达TargetLocation则等待2.5s后返回HomeLocation。在这里我删除了移动到TargetLocation的任务,否则会造成AI_Character在TargetLocation和HomeLocation之间不间断的移动,删除之后AI_Character移动回HomeLocation之后保持静止,直到TargetToFollow的再次确立导致的左侧行为树分支开启。
UE4官方行为树快速入门文档解析和修改的更多相关文章
- jackson官方快速入门文档
官方地址: http://jackson.codehaus.org/ http://wiki.fasterxml.com/JacksonInFiveMinutes http://wiki.faster ...
- ThinkPHP5 快速入门文档
一. 5.0版本采用模块化的设计架构,默认的应用目录下面只有一个index模块目录,如果我要添加新的模块可以使用控制台命令来生成. 切换到命令行模式下,进入到应用根目录并执行如下指令: php thi ...
- Python快速入门文档
前言 此文本质为本人学习Python过程中的笔记,部分地方叙述表达可能不够清晰,欢迎留言. (本文适合有一定程序语言基础的读者阅读(最好是c语言)) 一.基本语法 1.框架: (1)以缩进表示层次所属 ...
- 【简明翻译】Hibernate 5.4 Getting Started Guide 官方入门文档
前言 最近的精力主要集中在Hibernate上,在意识到Hibernate 5 的中文资料并不多的时候,我不得不把目光转向Hibernate的官方doc,学习之余简要翻一下入门文档. 原文地址:htt ...
- Apache BeanUtils 1.9.2 官方入门文档
为什么需要Apache BeanUtils? Apache BeanUtils 是 Apache开源软件组织下面的一个项目,被广泛使用于Spring.Struts.Hibernate等框架,有数千个j ...
- vuex最简单、最直白、最全的入门文档
前言 我们经常用element-ui做后台管理系统,经常会遇到父组件给子组件传递数据,下面一个简单的例子,点击按钮,把弹框显示变量数据通过子组件的props属性传递,子组件通过$emit事件监听把数据 ...
- 【Elastic-1】ELK基本概念、环境搭建、快速开始文档
TODO 快速开始文档 SpringBoot整合ELK(Logstash收集日志.应用主动向ES写入) ELK接入Kafka 基本概念 ElasticSearch 什么是ElasticSearch? ...
- 使用requests爬取梨视频、bilibili视频、汽车之家,bs4遍历文档树、搜索文档树,css选择器
今日内容概要 使用requests爬取梨视频 requests+bs4爬取汽车之家 bs4遍历文档树 bs4搜索文档树 css选择器 内容详细 1.使用requests爬取梨视频 # 模拟发送http ...
- 数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1)
数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1)
随机推荐
- [WPF]启动参数
在App.xaml.cs中重写方法OnStartup protected override void OnStartup(StartupEventArgs e) { //e.Args为命令行参数 // ...
- yum 私有仓库
参考地址:https://blog.oldboyedu.com/autodeploy-yum YUM主要用于自动安装.升级rpm软件包,它能自动查找并解决rpm包之间的依赖关系.要成功的使用YUM工具 ...
- 一次gcc编译失败分析
1. 场景: 在使用gcc编译时,编译器报错:xxx:'xxx'未定义的引用 2. 排查过程: 首先,我很自然的想到是不是自己使用了未定义的函数或者将函数名称写错了,在检查了一边过后,我发现自己使 ...
- JavaScript利用Date实现简单的倒计时实例
介绍 Date对象,是操作日期和时间的对象.Date对象对日期和时间的操作只能通过方法.Date在js中和Array类似,都是拥有自己的特殊方法的特殊对象. 创建 Date 对象的语法: var my ...
- A “Type Erasure” Pattern that Works in Swift:类型域的转换
新视角:通过函数式编程的范畴理论来看待这个问题会更容易理解: 在低层类型无法很好表达的类型,可以将其转化为高阶类型进行表示. 将协议的实现类型转化为monad类型: 解决将具有关联类型的协议当作类型的 ...
- 容器内部设置JVM的Heap大小
容器内部利用脚本来获取容器的CGroup资源限制,并通过设置JVM的Heap大小. Docker1.7开始将容器cgroup信息挂载到容器中,所以应用可以从 /sys/fs/cgroup/memory ...
- C++的技术探究
C++深究 函数指针 double pam(int, double); // prototype double (*pf)(int, double); // declare function poin ...
- myEtherWallet在线钱包的使用
https://www.myetherwallet.com/#generate-wallet myEtherWallet是一款在线钱包,当你不想安装类似metamask这样的插件时,可以选择使用它 1 ...
- Postman-自动化传参
一,自动化传参 在实现接口自动测试的时候,会经常遇到接口参数依赖的问题,例如调取登录接口的时候,需要先获取登录的key值,而每次请求返回的key值又是不一样的,那么这种情况下,要实现接口的自动化,就要 ...
- Stay true to yourself
https://zhuanlan.zhihu.com/p/22928614 艾伦·德詹尼斯,1958年1月26日出生于美国路易斯安纳州梅泰里,美国主持人.演员.凭借出众的诙谐幽默的口才和喜剧天赋,活跃 ...