前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >UE5的动画蓝图(Lyra工程)

UE5的动画蓝图(Lyra工程)

作者头像
quabqi
发布2022-05-23 09:56:39
2.3K0
发布2022-05-23 09:56:39
举报
文章被收录于专栏:Dissecting UnrealDissecting Unreal

UE5正式版附带的Lyra工程,展示了很多UE5里面的新的内容和新的优化,这个工程中动画的做法,就是一个非常有亮点的模块,也做了很多的优化,包括多线程优化,运行时挂载不同的动画层,CopyPose,IK Retarget等。Lyra这个工程本身就是个第三人称射击游戏,动画这部分从实际的表现效果上来看,其实并不比之前商城里的ALS的差,但从动画蓝图本身的规模来说要比ALS的动画蓝图简单太多了。下面就来具体说说有哪些内容。

动画蓝图总体结构

打开ABP_Mannequin_Base,可以看到动画蓝图的结构是Locomotion状态机Layer+上下半身分离+后处理的组织方式。

红色部分状态机:

这里UE5为了状态机看着简单,新加了一种别名节点(State Alias),这样就可以将原来多个状态汇总为一个节点,在写条件跳转的时候就可以只拉一条线。如下图所示的JumpSource,就是红框中这五个节点的别名。游戏跳跃动画这个状态,一般游戏静止,跑步等都可以触发,如果没有别名来做这个状态机,我们需要拉5条线到jumpSelector,而现在有了Alias汇总,只需要一条线就可以搞定,整个图就会简洁许多。

动画分层

在动画图表中,我们可以看到有很多蓝色的节点,里面并没有对应的输出,这些其实是通过layer动画蓝图实现的。

其实动画节点,本身也跟C++的函数一样,是从output pose开始向前一层一层的递归调用对应的节点,这些蓝色的节点,其实就是纯虚函数,需要留给动画蓝图的Layer实例去实现。打开动画蓝图的Class Settings,就可以看到这个动画蓝图实现了这些接口。

而这个接口,就定义了这些节点的输入和输出,但是并没有对应实现,就像C++定义了一个纯虚接口一样。

而真正的实现是在ABP_ItemAnimLayersBase这个蓝图中。打开后可以看到,动画图表中什么都没有,而只有对应的接口中有输出Pose的实现。

比如Idle,内部又是一个子状态机,实现了Idle和原地转身等动画状态的切换:

再比如起跳,内部输出的是两个动画按骨骼分层blend,这里UE5也新加了一种模式,另外也可以看到动画输出的节点可以挂载对应的函数,如下面的UpdateHipFireRaiseWeaponPose,后面具体说:

以ABP_ItemAnimLayersBase这个蓝图为基类,直接或间接继承出来了8个子类,如下图所示:

其中,空手/手枪/步枪/霰弹枪的动画蓝图是直接继承ABP_ItemAnimLayersBase的,而ABP_ItemAnimLayersBase并没有继承ABP_Mannequin_Base,而是实现上面定义的动画layer接口ALI_ItemAnimLayers。因此空手/手枪/步枪/霰弹枪的动画蓝图里面并不能去编辑动画图表连连看,只能设定默认的参数,真正的动画图表逻辑是在ABP_ItemAnimLayersBase中。

那么这个动画蓝图是怎样使用的呢?其实是需要运行时在代码中主动link对应的layers上去。

可以看到,在角色蓝图里的构造脚本中,一开始默认link了空手的动画蓝图。

在角色换枪时候,会link上对应的武器的动画蓝图,整个动画link都发生在运行时。你可能会说这样做有什么好处呢?其实当游戏做的很大的时候可能角色都会有上万个动画资源,所占用的内存对游戏也会有很大的负担,因此肯定不希望一开始就把角色的所有动画资源都加载进内存,有了动画分层的机制,就可以在需要的时候将对应的动画蓝图link到主动画蓝图上,这样就能减少动画对内存的占用。

多线程动画

打开动画蓝图,我们可以看到对应的注释,详细讲解了动画蓝图里的新内容和优化。这里只要全局搜AnimBP Tour这样的关键字,就可以找到所有的关键点。这里可以看到,动画里面新增了一个BlueprintThreadSafeUpdateAnimation函数,以前我们在做动画多线程优化的时候,只能在C++通过继承AnimInstance的方式,在子类代码中将动画中需要用到的变量主动同步到子线程,自己写的同步函数,还要时刻注意线程安全。而UE5可以直接在动画蓝图里面这样做了。

可以看到,这里增加了一个Property Access节点,可以在子线程直接去访问对应的变量,本质上其实是内部会在动画每帧开始执行前,先将这些变量在主线程拷贝出来,这样就能保证子线程的线程安全。这个节点第一次用可能一开始不知道怎么添加进来,其实只要输入Property Access即可

可以看到,在BlueprintThreadSafeUpdateAnimation里,调用了非常多的函数去获取动画运行需要的各种变量,这个就是替代原本应该放在Event Graph里的函数。

这里从角色蓝图或者其他组件里获取数据,都必须通过Property Access方式获取,因为这些函数是运行在子线程上,只有用这种方式获取UE5才能知道这些变量需要保证线程安全(内部每帧会提前拷贝)。

GameplayTag的获取

动画蓝图里的一些功能也依赖于GameplayTag,比如是否开镜,是否跳跃,是否换弹等,但是动画获取这些tag会比较麻烦,所以Lyra的动画蓝图就将这些Tag转换成了bool变量,藏在了CDO里,这个配置非常隐蔽。C++里会在运行时自动映射,这样动画就能取到对应的值了,具体C++代码很简单这里就不细说了。

Layered Blend Per Bone

前面说的有个节点,可以看到可以通过Mask进行Blend。这个节点本身功能很简单,就是mask里的骨骼按照权重用Base Pose和pose0进行混合,不在mask里的就是Base的Pose。这个节点本身很简单就不多说了。

第一次用可能会不知道这个Blend Mask的Config在哪里配置,为什么这里会出现上下半身的Mask。其实这个配置是在骨架资源上面编辑的。如下图,要点击左上角的小齿轮。这里就可以去编辑每根骨骼mask的权重了。

动画节点的回调函数

可以看到,Lyra工程里很多的动画播放节点里,都可以绑定回调函数了,而动画的Sequence的参数也定义为了Dynamic可以在回调函数里动态改。打开函数,可以看到实际是在Update过程中,动态的去换播放的动画资源。

这个其实就是UE5新增的一种方式,在以前通过一个变量控制动画都是通过blend的方式做的,现在可以直接通过代码支持更复杂的操作了,比如可以做距离匹配,速度匹配等,这里也用了惯性混合过渡,这么写有个好处就是不需要同时播放两个动画混合了,每帧只需要计算一个动画就可以。虽然灵活性高了很多,但动画本身节点就不是fast path了,而且这里Node只能Convert成下面这些,不支持混合空间,因此也不是所有的混合都能改成这样来写。

多部位Mesh的CopyPose动画

Lyra本身的Mesh是支持多部位的,如下图,就像很多网游那种换装。

对于主SkeletalMeshComponent,跑的是真正的动画,但是并没有挂任何模型,打开模型文件可以看到只有两个三角形,而子SkeletalMeshComponent里的动画蓝图用的是CopyPose动画蓝图

可以看到,这里就是从父层级上拷贝对应的pose直接用。这样我们就可以做到一个角色身上有各种各样的衣服,裤子等装备,但是共用同一个骨架和动画。

这种功能其实UE4以前就有,不过需要在代码里设,如果有多个SkeletalMeshComponent,可以设置MasterPoseComponent,这样多个子SkeletalMeshComponent都会CopyPose。如下:

IK Retarget

如果动画要可以CopyPose,前提是他们的骨架需要相同,但是Lyra也提供了Retarget功能,可以让骨架不同的动画通过IK Retarget的方式播放。比如下面这个就是运行时让Lyra的动画可以在UE4小白人上骨架播放。这里的关键就是配置的这个IK Retarget文件。

可以看到,这里右下角是将每个骨骼链做了一一映射。这个映射链,是通过上面的两个IKRig Asset读取的。

可以看到,这里是小白人的骨骼链,Lyra已经给ue4的小白人建立好了这样的骨骼链,非常多。

UE5的小蓝人也同样建立了这样的骨骼链。

这两个骨架大体上差不多,但仔细看其实不太一样。小蓝人比小白人的胸骨多了一节,每个手指头是4节,小白人是3节,当然还有其他细节不太一样就不细说了。

因为有了UE4和UE5两个骨架的互转Retargeter文件,所以只要是任何支持UE4或UE5标准骨架的动画,都可以在这两个骨架的模型上播放,动画资源也可以互转。当然如果自己有一个新的骨架,也可以通过建立IK Rig和IK Retargeter这两个文件做到动画共享。

如果担心运行时播放不同骨架的动画性能不好,也可以在动画资源层面进行离线转换。可以右键点击动画资源,点击Retarget。

在打开窗口右侧选择对应的IK Retargeter,就可以把动画转换成自己需要的骨架动画。

因此理论上来说,在网上扒的任何动画,哪怕不是人形的,都能给UE5的标准骨架来用。但是肯定还是支持UE4或者UE5的标准骨架动画是最方便的,因为Lyra已经建好了IK Retargeter,动画导入进来可以直接一键转换。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 动画蓝图总体结构
  • 动画分层
  • 多线程动画
  • GameplayTag的获取
  • Layered Blend Per Bone
  • 动画节点的回调函数
  • 多部位Mesh的CopyPose动画
  • IK Retarget
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档