最近在做动画优化插件,花了一周时间写代码调试效果,总算在大幅降低内存的基础上做出了美术同学满意的效果,目前优化过的动画文件是未优化的动画文件的7.5%左右的内存,写篇博客记录一下。
1、为什么要做动画优化:
动画文件在游戏包体和内存中占的比例仅次于贴图,优化好动画文件,就优化了一小半游戏内存。拿我们正在开发的游戏举例,优化后的包体和内存比优化前减少了一百多兆,大概优化掉了五分之一的内存。
2、优化思路:
- 设置Animation.Compression:Animation.Compression默认选择的是Optimal,AnimationPositionError默认0.2,AnimationRotationError默认0.1,AnimationScaleError大部分需要丢弃,所以默认就可以。具体值需要根据自己游戏调整,我们游戏由于战斗需要拉近镜头所以对动画精度要求较高,调的压缩值比较小。
- 默认不开启Resample Curves选项:Unity官方给的建议是开启,但是开启会增大内存,所以在动画没有问题的情况下建议关闭该选项。
- 减少帧信息的精度:将帧信息精度减少为小数点后四位,网上大多数文章也是给出的是小数点后三位,但是优化到小数点后三位导致我们游戏一些角色的披风抖动时会穿帮,所以精度优化到了小数点后四位。
- 优化未改变的Rotation、Position序列帧和剔除Scale序列帧:如果需要用到Scale变化就在骨骼节点上加关键字区分。Position、Rotation有很多骨骼节点其实并未发生变化,但是由于我们Animation.Compression这两个优化值设置的比较小,所以这里我们手动优化掉没有变化的Position、Rotation序列帧,只留头尾两帧,保证Position和Rotation初始值正确,这么处理一下会降不少内存。
3、源码:
using System.IO;
using System.Linq;
using Assets.Scripts.Common.Util;
using UnityEditor;
using UnityEngine;
using FileUtil = Assets.Scripts.Common.Util.FileUtil;
namespace Assets.Scripts.Editor.MenuItemEx
{
public class OptimizeFBX
{
private const float AnimationPositionError = 0.2f;
private const float AnimationRotationError = 0.1f;
private const ModelImporterAnimationCompression Compression = ModelImporterAnimationCompression.Optimal;
private const int DecimalAccuracy = 10000;
private static string _fbxPath;
[MenuItem("Assets/Optimize/Optimize FBX", false, 1000)]
private static void OptimizeFbx()
{
EditorSettings.serializationMode = SerializationMode.ForceText;
var objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
var count