找回密码
 立即注册
查看: 588|回复: 0

Unity中动画的无损压缩(一)

[复制链接]
发表于 2020-12-26 16:39 | 显示全部楼层 |阅读模式
此文参考了:
前言:虽然动画压缩早是一个老生常谈的话题,且很多动画制作软件都有着对动画压缩的一套很完备的策略,其中也包括游戏引擎UnityUnity在动画压缩方面提供了一套方案,但是有损的。本篇讲述如何在Unity中实现动画的无损压缩。希望你看了能有很大帮助o(∩_∩)o
      由于制作动画的同学水平参差不齐,实现同一效果的方式也千变万化,所以导致个项目的动画文件及其繁杂。随着项目不断迭代,动画这部分慢慢的会占据着巨大的一部分资源,而且还不敢随便碰,不然容易导致动画文件损坏。
      在谈动画压缩方案之前我们先聊聊Unity中的动画系统。
Unity中的动画系统:

      在Unity中,大部分角色的动画都是Animation。Animation是由Animation Curve来表示的,大部分项目中的角色动画一般Curve只有PositionRotationScale
一个复杂的角色动画
      每条曲线上都有着NKeyFrame,这些关键帧存储着顶点变化,位移变换等重要信息。  
      动画文件的存储形式是.anim文件,用Notepad打开可以看到其详细信息。
某一关键帧的信息
      可以看到一个KeyFrame中存储了ValueinSlopeoutSlope信息。
      Unity中对于KeyFrame的处理其实就是相邻读取,线性插值。读到这里聪明的你肯定会说了:这里的KeyFrame数据精度这么高,直接对他裁剪不就优化了吗?
      在这里,我可以明确的告诉你,这种方法是不起任何作用的!
如果你真的这么做了,那么你会惊喜的发现.anim文件在磁盘上减少了很多占用,但他并不会对我们打包后的apk有任何帮助。
      为什么呢?因为Unity会对.anim的文件先进行裁剪和加工,之后打包成Asset Bundle,Asset Bundle是二进制文件,同一个Float,不管精度如何它都占用同样的大小,所以也就失去了意义。
      虽然裁剪精度是无用功,但我们可以裁减掉.anim文件中无用的Scale曲线,减少包体和少部分的数据处理耗时。
      在一般的角色动画制作流程中,几乎很少有人会对骨骼来进行Scale缩放,尤其是对于手游来说,很少有人会用骨骼的Scale来实现效果的。因为类似的效果完全可以用周围顶点偏移来完成,操作方便且运算量小,除非一些及其特殊的需求,才会偶尔用到骨骼Scale
一个无用的Scale曲线
      那么我们就可以来删减.anim文件中所有无用的Scale曲线。这个操作是不会对动画效果有任何损失的,做到真正意义上的无损压缩。
具体实现:

      第一步是要找到文件夹下的所有.anim文件。
通过递归找到所有的anim文件
      找到所有的.anim文件后对其进行遍历,逐个优化。这里我们只处理Scale曲线。
过滤掉position和rotation曲线
      我们要先收集所有的ConstantScale曲线。这里我记录第一帧的Value,如果该曲线不是Constant那么曲线上的Value一定有不同的,所以对曲线上的KeyFrame Value逐个比对即可。
找到所有的!Constant曲线
      之后进行剔除,注意这里foreach遍历的是所有的曲线(包括PositionRotation),这里还需要单独对Scale检索一次。
删除!Constant曲线
测试:

      这里我们拿一个较为复杂的动画文件来做测试。
压缩前占用比
压缩前的曲线细则
      可以看到几乎每个骨骼下都有一个Scale
压缩后占用比
压缩后的曲线细则
      可以看到还是删除了不少的Scale曲线,Constant数量由357->138,裁减了进220条无用曲线,内存占用也少了2.6KB,这对于一个无损压缩方案来说还是很可观的。
我用此方法在王者荣耀的工程里对所有英雄的动画文件进行压缩,是没有任何问题的。足以说明此方案的可行性。
要说明的一点:

      使用了Scale裁剪策略后,.anim文件会有巨量的增长。
压缩前
压缩后
     那么我们来看看到底增加了些什么
压缩前的.anim文件
压缩后的.anim文件


压缩前
压缩后
m_EditorCurvesm_EulerEditorCurves部分的信息是编辑器内记录动画的信息,是冗余的,删除的话也没有任何影响,所以这部分增量是可以忽略的。
      除此以外还有
压缩后会增加的字段
      这里需要注意一下,这里的.anim文件大小只是在磁盘中的占用,上文也提到过,Unity打包Asset Bundle的时候会进行裁剪,所以这里的增量是可以忽略的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-20 08:45 , Processed in 0.090517 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表