AI角色
角色控制器
AI角色必须要一个角色控制器
![](https://img-blog.csdnimg.cn/direct/fb4beda4893d42679e317e9006fd22a6.png)
角色控制器最基本只需要执行行为树,在EventOnPossess后runBehaviorTree
![](https://img-blog.csdnimg.cn/direct/cb0bd8c1eae049fbaa034365900fbee8.png)
如果要的是一个角色,可以创建一个Character,在类默认设置中可以找到
Pawn->AIControllerClass,在这里设置AI操控模式和AI控制器类(角色自带移动组件,否则move to行为不起作用)
![](https://img-blog.csdnimg.cn/direct/12d3eaa27dfc4c77bb57dd3756d36dd7.png)
行为树
行为树是大脑,执行逻辑,数据存储在黑板,所以创建行为树同时也要创建黑板
设置AI的行为,判断,分支Selector,执行Task,顺序Sequence
根节点往下第一个只能接基础3个节点,一般选Sequence或Selector
在Selector上可以套装饰器(Decorator) 或者服务(Service)
装饰器:根据逻辑判断当前节点是否执行
服务:当运行到当前节点的时候执行服务内的逻辑
服务
一个随机找点的服务:
首先在行为树界面最上方新建一个服务
![](https://img-blog.csdnimg.cn/direct/45779fd0eaa8423581089c49522b954e.png)
重写一个EventReceiveTickAI,这里简单找个三维向量赋值给黑板
新建一个黑板变量
![](https://img-blog.csdnimg.cn/direct/9144a874f5c645c98fcd6cc5d9858b03.png)
![](https://img-blog.csdnimg.cn/direct/0d7fd58002b347518710ae0a22b9ae8e.png)
使用Service:在行为树节点上右键选中想要的服务即可
![](https://img-blog.csdnimg.cn/direct/c9e6f87933cf41cea4ed2cbb66315bd1.png)
装饰器
最经常使用的就是使用黑板值来判断是否执行该节点
在节点上右键选择要使用的BlackBorad
![](https://img-blog.csdnimg.cn/direct/ae457b5006b94ba5b781623682582346.png)
然后单机蓝色的框(装饰器),在右侧面板上可以指定具体的黑板变量
这里选择变量hasPlayer,当IsSet(设置有值或者为true)就执行
![](https://img-blog.csdnimg.cn/direct/e3bfe893782c439c86a780df6d3f02cc.png)
行为Task
具体的执行节点,同时也是行为树的最末端节点,
创建自定义Task:
在行为树面板顶部选择NewTask
![](https://img-blog.csdnimg.cn/direct/abffdfd5f7fc4ebdb45594d4cdb20900.png)
在Task中重写EventReceiveExecuteAI,记得一定执行FinishExecute
![](https://img-blog.csdnimg.cn/direct/7e6f76355dcd452297f48d478e397036.png)
使用:直接拉出来选择要执行的Task就行
![](https://img-blog.csdnimg.cn/direct/8bef7cff4ec54cdd8773c16dd760b215.png)
黑板
负责记录AI行为所需的数据,可以是任意类型数据
![](https://img-blog.csdnimg.cn/direct/822b97218b8546c6ac54f34d4d7309f8.png)
对黑板数据的读取和修改跟普通的蓝图类不同
设置变量
需要先创建一个类型为BlackBoardKeySelector变量,再将变量设置为黑板值
比如设置一个在黑板中的三维向量变量
![](https://img-blog.csdnimg.cn/direct/9144a874f5c645c98fcd6cc5d9858b03.png)
![](https://img-blog.csdnimg.cn/direct/c6dfe9ffab6142ca8287f6a1304f8638.png)
获取变量
![](https://img-blog.csdnimg.cn/direct/cb783461f69e44698dee59f980ca8551.png)
EQS
代替大部分常用的服务和Task,例如找点移动等
创建
![](https://img-blog.csdnimg.cn/direct/23aff556edfc498990545048120ea17d.png)
进入,根节点往下拉可以看到有很多可以执行的节点
![](https://img-blog.csdnimg.cn/direct/ee187d63d6b646cbbeb698012476f4c4.png)
例如随机找点
可以选择Points下的各种类型(生成不同形状的查找范围)
可以在右侧面板设置生成点的范围和密度数量等
![](https://img-blog.csdnimg.cn/direct/bf4174ed72c44b5094f8921af10557a4.png)
在这个节点上可以套额外的限制
比如给一个角度限制
在节点上右键AddTest选择dot(余弦)
![](https://img-blog.csdnimg.cn/direct/6dcc72098f5648729fd63db735c9d77d.png)
单击dot可以选择给生成的点打分 或筛选
打分可以在后面选点时参与,筛选则直接去除
我这里选择只打分,并且只判断平面,反向打分Inverse(这样在身后的分最高)
![](https://img-blog.csdnimg.cn/direct/8b837944dbe14e7aac974bc883b2d468.png)
判断路径是否可到达
AddTest->PathFinding
![](https://img-blog.csdnimg.cn/direct/d9b2958b1d94470bac1428593a941408.png)
使用
完成的EQS可以直接在行为树上使用,如作为Service套在节点上
![](https://img-blog.csdnimg.cn/direct/4e5d60e9e518411abf4eb205f6329c6e.png)
或作为节点执行
![](https://img-blog.csdnimg.cn/direct/43af00356c6a4a02a183cf84214a55db.png)
选中节点同时在右侧面板指定要执行的EQS类即可
中断节点
当角色看到玩家或者其他的判断条件需要我们放弃当前的操作时(比如moveTo,移动到一半直接去攻击玩家之类的)
需要在分支或节点上添加一个装饰器(或现有的可以满足需求也可以)
在右侧面板找到FlowControl
一般选择当结果改变时,中断自身(自身及下面的节点)
![](https://img-blog.csdnimg.cn/direct/1ad092fd270644afbbc191fcdae27b57.png)
可以添加多个装饰器判断,只要一个满足就会中断
行为树只有跟节点在亮,不进行其他操作
需要检查所有的条件判断是否有问题
在服务里面添加打印输出,有时虽然Selector或Sequence上面的服务在执行,但是节点和线条并不会在闪烁,需要排查问题出现的节点位置和逻辑
添加wait节点分开其他节点来排查
其他逻辑
始终面朝玩家
通过一个task来实现面朝玩家的需求(tick需求)
但是task执行频率是一次性,并且依赖行为树的频率,并不是完整的每帧执行
在task中重写EventReceiveTickAI和EventReceiveExecuteAI
Execute是一开始执行,先获取玩家(黑板值)和AI的转向速度(自定义)
![](https://img-blog.csdnimg.cn/direct/508f7e75c5374519a4f95c7efc7dc729.png)
在Tick中不断地比较目标旋转和自身旋转,使用RInterpTo来实现平滑数值过度,不能忘记finish
![](https://img-blog.csdnimg.cn/direct/d360391d714c4bfcb6a510e35dfdabcd.png)