UE5顶点动画方案

前言

UE5为了黑客帝国的样片增加了内置顶点动画插件,另外第三方也有相对比较成熟的顶点动画工具

本文分析并记录一下

Anim To Texture

img

UE从5.0开始跟随者Mass更新了这个插件,不过一直到5.4也一直处于实验性功能

并且没有文档

开启插件以后,并没有什么特殊的提示和菜单


DataAsset

创建类型为AnimToTextureDataAsset的DA资产

界面如下

image-20241217114454271

需要重点关注的几个地方

  • SkeletalMesh:原始骨骼模型
  • StaticMesh:用于播放顶点动画的静态模型,可由骨骼模型一键生成
  • Mode:两种计算方式
    • Vertex:从顶点采样
    • Bone:通过骨骼和蒙皮采样
  • Texture:对应上面2个模式的数据贴图
  • AnimSequences:动画片段,可以设置多个一起烘焙到同一张贴图上,通过材质参数改动画

其他参数一般可以不修改或者视情况调整

材质

两种模式创建的材质不一样,这里以顶点方式举例

image-20241217114511937

函数库都是提供好的,也不展开讨论

设置材质数据

这一步不需要通过手动设置,那会非常麻烦,通过一些现有的编辑器方法将DA的数据烘焙到贴图中,然后在设置一下材质参数即可

image-20241217114527223

image-20241217114537741

上面的材质即该角色用到的所有材质实例

录制_2024_12_13_11_11_11_738

缺陷

必须自己再写一套工具自动识别模型和材质,自动创建贴图,否则流程过于冗长

另外没有办法混合/过渡动画

所以只适合简单的顶点动画机制

VertexAnimationManager

image-20241217114650433

一个评分挺高的第三方插件

文档

文档比较旧,很多设置已经不一样了,仅供参考

录制_2024_12_17_11_39_37_140

这个插件按照介绍,解决了官方版本的很多短处,如下

  • 更简单的配置方式
  • 支持动画过渡
  • 更好的动画切换方式
  • 支持获取Socket位置
  • 支持动画通知(一种平替)
  • 支持同步组
  • 支持RootMotion
  • 支持Ragdoll
  • 支持ABP

具体每个功能效果怎么样,下面分析

配置方式

创建一个DA,类型是UVertexAnimationProfile

image-20241217133304726

一般只需要修改上图种的内容

  • Mode: 同官方,分骨骼和顶点,一般建议骨骼;以下以骨骼模式距离
  • InfluencesMaxBones: 最大影响的骨骼数,一般建议4个
  • InfluencesStorage: 建议选择Texture用贴图来存储顶点信息,否则会用模型的定点色来存储,会影响模型本身的顶点色的使用
  • Animation: 可以选择多条动画

材质

image-20241217133325820

材质非常简单,使用一个函数库,如图连上即可

Bake

然后打开骨骼模型资源,在AssetUserData里添加插件的一个,对象如下

image-20241217133343985

然后点击骨骼模型编辑页面左上角插件提供的一个按钮

image-20241217133355619

点以后会自动的生产贴图和静态模型,并且会设置到DA中

完整的DA应该是如下图

image-20241217133405135

创建BP

img

添加上图两个组件,一个静态模型,一个播放动画

image-20241217133441586

静态模型如上图设置好

img

runtime组件如上图,一般功能都可以勾上

然后就可以通过播放动画的API播放特定的动画了

img

动画通知

动画通知算是比较重要的功能了,看他如何实现的

img

看一下他如何实现

核心的代码在 UVARuntimeComponent::RegisterNotifications

image-20241217133525141

遍历搜集到的所有通知,对几种类型的通知分别处理

核心围绕TimerManager,本质上就是倒计时到点了就发出通知事件

  • ANS
    • Begin/End 2个计时器,到点了触发
    • 注册world的tick回调,一直触发,end以后销毁
  • AN:到点了触发
  • 自定义通知
    • 判断是否有Handle对象
    • 查询同名函数并执行
    • 最多支持一个参数

蓝图/cpp通知

蓝图或者cpp写的动画通知都需要继承对应的接口

img

然后实现里面的接口就以触发通知,比如

img

但是蓝图的ANS通知有一个bug

看实现的地方

img

蓝图的ANS类即使继承了接口也会cast失败,这个是UE自身的问题,所以无法正常触发动画通知

可以通过修改代码实现,但是不建议,直接用cpp吧

自定义通知

这个要分2类,一般就是我们右键直接创建出来的通知

对应关系如下

img

这里不得不提到还有一种自定义通知的方法

就是创建一个蓝图AN,但是不继承自上述说到的接口

那么也是通过函数名去查询,但是名称有点奇怪,反正不建议就是了,如下图

img

动画蓝图

ABP也能用是没想到的,这样就非常方便了

img

ABP里专门写了一个播放动画的节点

image-20241217133722459

image-20241217133740881

看代码发现核心逻辑是拷贝pose

那么既然有ABP,后面肯定有个在跑的SkeletalMeshComponent

所以理解一下就是, 后面其实是有一个看不见的骨骼模型在跑,然后将ABP的pose拷贝到静态模型上

所以意义在哪里?

用顶点动画其中一点原因难道不就是为了节约ABP和骨骼模型的那些性能开销吗?

实际使用下来发现也有一些问题和bug

  • 在编辑器模拟运行是可以的,运行时状态机无法根据条件正确跳转
  • 节点无法自动过渡
  • 无法使用蒙太奇

Ragdoll

这个也是同ABP,必修后面有个SkeletalMeshComponent,原理也类似

那这个功能也就鸡肋了

image-20241217133800368

同步组

本以为同步组也是跟上面两者一样偷梁换柱,结果这个反而是正儿八经的做了的

image-20241217133814111

考虑到本身这个动画只有一种情况会用到同步组,就是2个动画过渡的时候,那么也能理解这个同步组的实现并不需要骨骼动画那么麻烦了

补充

  • 24年12月作者只更新到支持5.4,还未支持5.5
  • 使用过程中会出现动画丢失或者严重变形,需要重新Bake或者重新设置2个组件,应该是个bug
  • 编辑或者运行过程中偶尔会crash,也是bug