UE4学习笔记19——【AI】AI移动

  • P54. 【AI】导航网格
  • P55. 【AI】蓝图实现AI随机移动
  • P56. 【AI】AI行为树实现随机和跟随移动
  • P57. 【AI】靠近玩家挥拳
  • P54

在默认编辑界面中,编辑界面的左侧 “体积——导航网格体边界体积” 可以设置AI移动的区域

  

把“导航网格体边界体积”拖进编辑器后,按 P 键可以显示/隐藏:

    

  • 导航网格的静态和动态

静态是游戏前已经规划好的;动态是游戏中实时计算的。

  如何设置 静态/动态:

默认编辑界面中,选择工具栏中的“设置——项目设置”

新的界面中,左侧选“引擎——导航网格体”

在右侧滚轮滚到最下,“运行时——运行时生成”中的选项可以更改 静态或动态(动态的开销较大)

  

 

  • P55. 蓝图实现AI随机移动

(先创建一个含有第三人称模板的工程)

内容浏览器中,路径“内容——ThirdPersonBP——Blueprints”,复制一份此路径下的“ThirdPersonCharacter”蓝图类,并重命名为“AI_BP”

  

创建一个文件夹(在哪里无所谓),把“AI_BP”移动到此文件夹(拖拽进去即可)

打开“AI_BP”蓝图类,把事件图表中的所有节点都删掉,把组件中的相机也删掉;“我的蓝图”中的两个变量也删掉:

    

在“事件图表”中,添加节点“AI Move To

  

从此节点的引脚“pawn”添加节点“self”(搜索self就有,对自身的引用)

 

(“AI Move To”其他引脚说明:

Target Actor:跟随的角色(AI跟随的目标角色)

Acceptance Radius:跟随角色的半径(在目标角色的多远处停下)

Stop on Overlap:如果打勾,那么AI到上述半径后就会停下来

成功时:AI到达目的地时 就执行这条线路

失败时:AI没能到目的地时 执行这条线路)

 

添加节点“自定义事件”,重命名为“AI移动”,此节点的执行端 连接 “AI Move To”的前端执行

从节点“AI Move To”的引脚“Destination”添加节点“获取可导航半径内的随机点”(需要在 关卡编辑器 中添加一个“导航网格体边界体积”)

从节点“获取可导航半径内的随机点”的引脚“Origin”(导航半径的圆心)添加节点“获取Actor位置”,节点“获取可导航半径内的随机点”的引脚“radius”改成5000(即以“获取Actor位置”的角色为圆心,半径5000cm随机找一个点移动)

添加节点“事件开始运行”,从此节点添加节点“AI移动”(上面添加的自定义节点重命名为的“AI移动”)

(此时编译,然后回到关卡编辑器把“AI_BP”添加进场景中,AI会随机找点移动,但是只会移动一次)

从节点“AI移动”添加节点“以事件设置定时器”,此节点的引脚“event”连到事件“AI移动”(不是函数“AI移动”,是事件“AI移动”,是一开始的自定义事件),再从此节点的引脚“time”添加节点“范围内随机浮点”,min改为3,max改为5(意思就是3s到5s的随机时间AI会移动到一个点);节点“以事件设置定时器”的引脚“Looping”打勾(循环)

连完线后蓝图的事件图表:

  

 

  • P56. AI行为树实现随机和跟随移动

 (接着上节课的工程)

在 内容浏览器中 自己的文件夹下,右键“人工智能——黑板”;再右键“人工智能——行为树”;再右键“蓝图类”,在所有类中搜索“AIcontroller”,添加“AIcontroller(AI控制器)”,重命名为“AIController_New”

  

打开“黑板”,在左侧的“新建”按钮添加变量:“布尔”变量“是否看到玩家”,“向量”变量“要去的地方”

打开“AIController_New”(蓝图类),“添加组件——AI感知组件”,单击新添加的组件,在右侧的“细节——AI感知——感知配置”,点击“感知配置”后的“+”号,然后选择“AI视力配置”:

  

展开这个新添加的感知配置(点前面的小三角展开),“Sense——按归属检测——检测中立方”,此项打勾(玩家算中立方,这样会检测到玩家)

点击“细节——事件——目标感知更新时”后面的+号(添加这个节点),从此节点的引脚“actor”添加节点“类型转换为ThirdPersonCharacter”(如果搜不到这个节点,需要在“关卡编辑器”中添加一个小白人“ThirdPersonBP——Blueprints——ThirdPersonCharacter”)(类型转换的作用是 只有看到小白人 才会响应之后的逻辑);

从节点“目标感知更新时”的引脚“stimulus”添加节点“中断AIStimulus”;

(测试用:从节点“类型转换为ThirdPersonCharacter”的后端执行添加节点“打印字符串”,节点“中断AIStimulus”的引脚“successfully sensed”连接节点“打印字符串”的引脚“in string”;

目前,“AIController_New”蓝图类和“AI_BP”蓝图类没有建立关系;

打开“AI_BP”蓝图类,点击工具栏中的“类默认值”,在“细节——Pawn——AI控制器类”,选择“AIController_New”(我们自己新建的那个AIController蓝图的名字))

(上面的东西记得要编译和保存)

这时运行关卡,当我们控制的小白人在AI视线内时,打印true;在AI视线外时,打印false:

  

打开“AI行为树”(NewBehaviorTree),从“根”的黄色部分拉出线添加“Selector”:

  

再从“Selector”添加两个“Sequence”;右键左边的“Sequence”,选择“添加装饰器——Blackboard

如果之前已经有“黑板”,并且目前有多个“黑板”,怎么使用某一个指定的“黑板”?:

为了演示,我们将一开始我们新建的黑板重命名为“AI_BB”,

  

然后打开“AI行为树”,在右边的“细节——AI——BehaviorTree——黑板资产”中,选择“AI_BB”,然后点击红框的向左的箭头,这样就把黑板“AI_BB”应用到了这个“AI行为树”中

  

 单击“Blackboard Based Condition”(选择“添加装饰器——Blackboard”后出现的东西),在“细节——黑板——黑板键”选择“是否看到玩家”(“是否看到玩家”是此“黑板”中的变量)(键查询是“已设置”)

    

对于右边的“Sequence”,执行和左边的“Sequence”一样的操作(右键,“添加装饰器——Blackboard”)

不同的是,单击“Blackboard Based Condition”后,“细节——黑板——键查询”选择“未设置”,“黑板键”仍然选择“是否看到玩家”

(“已设置”和“未设置”对应的是看到玩家和没看到玩家执行的不同的流程)

两个“Blackboard Based Condition”的“细节——流控制——观察器中止”均选择“both”(把两边的优先级设置到了同一级,左边走了右边就不走,右边走了左边就不走)

 

打开“AIController_New”蓝图类,删除节点“打印字符串”和一个红色粉色转接的节点(在节点“中断AIStimulus”后面):

  

添加节点“获取黑板”,从此节点的后端添加节点“将值设为布尔”;然后节点“将值设为布尔”的前端执行连接节点“类型转换为ThirdPersonCharacter”的后端执行,节点“将值设为布尔”的引脚“Bool Value”连接节点“中断AIStimulus”的引脚“successfully sensed”;

从节点“将值设为布尔”的引脚“key name”添加节点“创建文字命名”,新添加节点的引脚“value”的值改成“是否看到玩家”(AI_BB中的布尔型变量的名字)

 

切换到“AI行为树”(NewBehaviorTree),在工具栏中选择“新建任务”,然后到“关卡编辑器”界面对这个新建的东西重命名为“随机找点”:

  

打开这个新建的“随机找点”,在左侧“我的蓝图——图表——函数——重载”,选择“接收执行AI”:

  

 

打开“AI_BP”蓝图类,把“事件开始运行”和“AI移动”之间的连接线断开(这节课做的是通过其他方式实现上节课的逻辑,如果之前的“AI_BP”蓝图类的事件图表还保留着那么编译器将混乱,不知道执行哪一边):

  

复制图中4个黄框节点,到“随机找点”的事件图表

  

 

节点“事件接收执行AI”的执行端连节点“AI Move To”的前端执行,节点“事件接收执行AI”的引脚“controlled pawn”连接节点“AI Move To”的引脚“pawn”(之前引脚“pawn”连接的“self”删除掉)

(节点“AI Move To”的引脚“stop on overlap”记得打勾)

从节点“AI Move To”的引脚“成功时”添加节点“完成执行”,新添加节点的引脚“success”要打勾

节点“事件接收执行AI”的引脚“controlled pawn”连接节点“获取actor位置”的引脚“目标

(上面的东西记得弄完了编译)

切换到“AI行为树”(NewBehaviorTree),从右侧的“Blackboard Based Condition”(“键查询”为“未设置”的)的底端拉出一条线添加“Tasks——随机找点”,再添加“Wait

(到目前为止,“AI行为树”和“AIController_New”(蓝图类)还没建立联系,现在建立联系)

切换到“AIController_New”(蓝图类),添加节点“事件开始运行”,节点“运行行为树”;节点“运行行为树”的“BTAssets”选择“NewBehaviorTree”(这个是我们的AI行为树的名字)

(刚才忘了说,要把“AI_BP”蓝图类的事件图表中的节点全都删除)

这个时候运行,AI在没看到“玩家”前会随机跑(每隔5s),看到“玩家”之后便会停下来再也不动了,这是因为“AI行为树”看到玩家这一边的逻辑还没有写:

  

在“AI行为树”(NewBehaviorTree),点击工具栏的“新建任务”,重命名为“寻找玩家”

打开这个“寻找玩家”蓝图类,在左侧“图表——函数——重载”选择“接收执行AI”,从此节点添加节点“AI Move To”,节点“事件接收执行AI”的引脚“controlled pawn”连接节点“AI Move To”的引脚“Pawn”;节点“AI Move To”的引脚“Target Actor”添加节点“获取玩家角色”(AI会跟着玩家走);从节点“AI Move To”的引脚“成功时”添加节点“完成执行”,“success”打勾;

切换到“AI行为树”(NewBehaviorTree),从左边的“Blackboard Based Condition”添加“寻找玩家

(这时运行,玩家可能会甩开AI,所以下面要让AI的视角一直跟随玩家)

打开“AI_BP”蓝图类,单击“组件——角色移动”,把“细节——角色移动(旋转设置)——将旋转朝向运动”取消勾选;点击工具栏的“类默认值”,把“细节——pawn——使用控制器旋转Yaw”打勾;

打开“寻找玩家”蓝图类,从节点“事件接收执行AI”的引脚“Owner Controller”添加节点“设置焦距”,然后节点“事件接收执行AI”的后端执行连接节点“设置焦距”的前端执行,节点“设置焦距”的后端执行连接节点“AI Move To”的前端执行;

节点“设置焦距”的引脚“new focus”连接节点“获取玩家角色”的引脚“return value”;

打开“随机找点”蓝图类,从节点“事件接收执行AI”的引脚“Owner Controller”添加节点“清除焦距”,然后“清除焦距”的前面和“事件接收执行AI”的后面相连,“清除焦距”的后面和“AI Move To”的前面相连。

最终:

  AI_BB(黑板):

  

  AI_BP(蓝图类):事件图表是空的

  AIController_New(蓝图类):

  

  NewBehaviorTree(行为树):

  

  寻找玩家(蓝图类):

  

  随机找点(蓝图类):

  

这节好乱啊,没懂

 

  • P57. 靠近玩家挥拳

(接上期的继续做)

打开“AI_BP”(蓝图类),在左侧的“组件”部分,在“胶囊体组件”下添加组件“sphere collision”;单击新添加的“sphere”,在“细节——形状——球体半径”,改成80;

还是这个“sphere”,从“细节——事件”,添加“组件开始重叠时”和“组件结束重叠时”,从这两个节点的“other actor”分别添加节点“类型转换为ThirdPersonCharacter”;

把组件中的“胶囊体组件——网格体”,拖进事件图表中,从此节点添加节点“获取动画实例”,再从新节点添加节点“蒙太奇播放”;“组件开始重叠时”后面的“类型转换为ThirdPersonCharacter”的后端执行连接“蒙太奇播放”的前端执行;

(为了在“Montage to play”中添加资产,首先在“Epic Games 启动程序”中将 动画初学者内容包 添加到我们正在使用的工程中:

  

 

但是这个包中并没有挥拳动作,我们用这个包的别的动作来代替好了;

这个包中的动作都是“动画序列”,并没有“蒙太奇动画”,此时我们还无法在“Montage to play”中添加资产;

我们找到一个我们想添加的动作,然后右键“创建——创建动画蒙太奇”:

  

 

这时我们就可以在“Montage to play”中添加这个蒙太奇动画

  

 

从节点“蒙太奇播放”添加节点“以事件设置定时器”,从此节点的引脚“event”添加节点“添加自定义事件”,重命名为“loop”;

“loop”的执行连到“蒙太奇播放”的前端执行,“以事件设置定时器”的“time”连接“蒙太奇播放”的“return value”,“以事件设置定时器”的“looping”打勾;

  

 

从节点“以事件设置定时器”的引脚“return value”添加节点“以句柄清除定时器并使之无效”(搜索clear就找到)(“以事件设置定时器”的后面执行不连接“以句柄...”的前端执行!);“组件结束重叠时”后面的“类型转换为ThirdPersonCharacter”的后端执行连接“以句柄...”的前端执行;

(下面的操作我也不知道是怎么回事)

在“关卡编辑器”,从内容浏览器的“内容——mannequin——animations”,复制这里面的“ThirdPerson_AnimBP”,到自己的文件夹里(能辨别就行),重命名为“AI_AnimBP”

  

回到“AI_BP”(蓝图类),单击组建中的“网格体”,在“细节——动画——动画类”,选择“AI_AnimBP”

回到关卡编辑器,双击点开“AI_AnimBP”,在左下角“我的蓝图——动画图表”,双击“AnimGraph”,在两个小人之间添加“插槽”(搜索slot就有)

  

(AI靠近玩家的时候(比较近的时候),摄像机会被阻挡)(视角不太正常),现在解决这个问题)

打开“AI_BP”蓝图类,单击组件中的“胶囊体组件”(视频中说的是“网格体”,但是经过实验修改“网格体”的相应细节还是不行,需要修改的是“胶囊体组件”),在“细节——碰撞——碰撞预设”改成“custom”,“碰撞响应——camera”改成“忽略”:

  

我自己的项目中出现的问题:

  用“动画初学者内容包”里的动画序列创建的“蒙太奇动画”,AI靠近玩家之后没反应;然后我就用了“内容——mannequin——animations”中的“ThirdPersonJump_Start”动画序列创建了一个蒙太奇动画,在“AI_BP”里用这个,AI靠近玩家之后就有反应了。

后续更新:针对上面的问题,在实验之后,原因可能是 AI 的骨骼和 蒙太奇动画中绑定的骨骼不一致造成的;后来用了其他的人物模型 和 与该人物模型一致骨骼的动画序列生成的动画蒙太奇 并应用,动画能够正常播放。

anyway,懵

(〃>_<;〃)(〃>_<;〃)(〃>_<;〃)

posted @ 2022-11-25 15:53  我会变强的  阅读(1817)  评论(0编辑  收藏  举报