前言
本文为本人学习UE4 AI相关模块学习笔记,之前因为没有系统的整理过所以没发出。现在因为某一些原因,又因为懒得整理所以就发了。
其他文档推荐:
UE4场景询问系统浅析(EQS与行为树)
http://www.uejoy.com/?p=500
UE4 AIModule源码阅读之AI感知系统
https://zhuanlan.zhihu.com/p/356716030
本文为本人学习UE4 AI相关模块学习笔记,之前因为没有系统的整理过所以没发出。现在因为某一些原因,又因为懒得整理所以就发了。
其他文档推荐:
UE4场景询问系统浅析(EQS与行为树)
http://www.uejoy.com/?p=500
UE4 AIModule源码阅读之AI感知系统
https://zhuanlan.zhihu.com/p/356716030
之前我有写过两篇通过自定义场景代理来实现描边的文章:
https://zhuanlan.zhihu.com/p/69139579
https://zhuanlan.zhihu.com/p/69156465
当时有一个问题没解决,就是不知道如何将材质设置为反向剔除,因为UE4只有双面渲染选项,毕竟只有卡通渲染等一些非真实渲染才需要这种功能。但经过MeshDraw框架的学习,我发现只需要在场景代理中设置一下FMeshBatch剔除属性即可,而且这个方法没有任何副作用。其他代码可以参考我的插画。效果如图(没有使用深度偏移)

MeshDraw是UE4用于渲染Mesh相关Pass的框架,他主要用于将Mesh渲染到RT上,之后在RDG中进行进一步的渲染。
使用引擎版本:源码版4.27.0
参考Yivanlee的MeshDraw系列文章。
TargetActor是GAS用于获取场景中物体、空间、位移等数据的机制,同时也可以用于制作可视化debug工具。,所以非常有必要掌握它。
一般流程为:使用WaitTargetData_AbilityTask生成TargetActor,之后通过TargetActor的内部函数或者射线获取场景信息,最后通过委托传递携带这些信息构建的FGameplayAbilityTargetDataHandle。
本文部分描述摘自GASDocumentation_Chinese,翻译的还不错,也请大家给此项目点赞。
整理了一下GameplayTasks节点,在此分享给大家。
本文大部分内容来着GASDocumentation与GASDocumentation_Chinese,因为感觉很重要所以在此简单归纳一下。
https://github.com/tranek/GASDocumentation
https://github.com/BillEliot/GASDocumentation_Chinese
使用GAS实现Combo技能,本人所知道的有两种思路:
第一种:为每一段Combo创建一个单独的Ability;定制自定义Asset与编辑器,之后再通过自定义编辑器进行编辑。
第二种:根据GameplayEvent直接在Ability里直接实现Combo切换逻辑
https://zhuanlan.zhihu.com/p/131381892
在此文中,我分析了ActionRPG的攻击逻辑的同时自己也提出一种通过GameplayEvent实现Combat的方法。这个方法理论上没问题,但实际落地的时候发现存在一个问题:里面使用的PlayMontageAndWaitEvent是GameplayTasks是异步运行的,而通过AnimNotify发送的SendGameplayEvent的函数确是同步函数。所以会导致PlayMontageAndWaitEvent节点接收不到任何事件的问题。经过一段事件的探索,本人摸索到了另一种方案:
如果你使用GAS的输入绑定系统,即在GiveAbility()注册时进行输入绑定(参考GASDocument的4.6.2章节)。可将后面介绍的ListenPlayerInputAction节点换成GAS自带的WaitInputPress或WaitInputRelease。
大多数人应该是会通过学习UE4的ActionRPG项目来入门GAS框架的。但在最近自己做Demo的过程中才发现里面的部分不适用网络联机。比如ActionRPG将Character与Controller的指针存在GameMode,因为Server与Client只有一个GameMode的关系,就不符合多人联机游戏的规则。所以在经过实践之后这里我分享一些要点仅供抛砖引玉。这里我再推荐各位读者去看一下GASDocument以及附带的工程,它展现了正确的设计思路。
在插件中使用RDG调用ComputeShader的方法,我花了没几天就搞定了。但PixelShader相对来说就麻烦了,怎么搞都没有绘制到RT上。最后还是通过改写DrawFullscreenPixelShader的代码搞定了。
另外说一下PixelShader的调用和传统的GlobalShader调用很相似。