NLDClient-yudde/ProjectNLD/Assets/Editor/AnimCompressor/LTCompressor.cs

180 lines
6.0 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class LTCompressor
{
private const string COMPRESSED_PATH = "Assets/Art/Animations/compressed";
private const string NEED_COMPRESS_PATH = "Assets/Art/Animations/animator";
private static List<string> _compressedFiles;
[MenuItem("Tools/资源压缩/压缩所有动画")]
public static void CompressAll()
{
// 确保路径存在
_InitCompressPath();
// 加载所有需要的动画
var realPath = Application.dataPath.Replace("Assets", NEED_COMPRESS_PATH);
var allFiles = System.IO.Directory.GetFiles(realPath, "*.overrideController", System.IO.SearchOption.TopDirectoryOnly);
var filterFiles = new List<string>();
foreach (var fileName in allFiles)
{
var onlyFileName = System.IO.Path.GetFileName(fileName);
var assetPath = NEED_COMPRESS_PATH + "/" + onlyFileName;
filterFiles.Add(assetPath);
}
// 挨个处理
_compressedFiles = new List<string>();
foreach (var assetPath in filterFiles)
{
var loadController = AssetDatabase.LoadAssetAtPath<AnimatorOverrideController>(assetPath);
if (loadController == null)
{
Debug.LogError("读取文件发生错误:" + assetPath);
return;
}
// 检出
// VersionControlSystem.Checkout(assetPath);
_CompressAnim(loadController);
}
AssetDatabase.Refresh();
}
private static void _InitCompressPath()
{
var realPath = Application.dataPath.Replace("Assets", COMPRESSED_PATH);
if (!System.IO.Directory.Exists(realPath))
{
System.IO.Directory.CreateDirectory(realPath);
}
}
private static void _CompressAnim(AnimatorOverrideController overrideController)
{
// 读取所有的动画
var overrideClips = new List<KeyValuePair<AnimationClip, AnimationClip>>();
overrideController.GetOverrides(overrideClips);
var newClips = new List<KeyValuePair<AnimationClip, AnimationClip>>();
// 挨个处理
for (var i = 0; i < overrideClips.Count; ++i)
{
var clipPair = overrideClips[i];
var srcClip = clipPair.Key;
var dstClip = clipPair.Value;
if (srcClip == null && dstClip == null)
{
// 双为空才报错
Debug.LogError("动画为空,请检查:" + overrideController.name);
continue;
}
AnimationClip compressedClip;
if (dstClip == null)
{
compressedClip = _CompressClip(srcClip);
}
else
{
compressedClip = _CompressClip(dstClip);
}
if (compressedClip == null)
{
Debug.LogError("压缩动画失败:" + srcClip.name);
}
var newClip = new KeyValuePair<AnimationClip, AnimationClip>(srcClip, compressedClip);
newClips.Add(newClip);
}
// 重新设置
overrideController.ApplyOverrides(newClips);
}
private static bool _CheckIsAllwaysOne(EditorCurveBinding curveBinding, AnimationClip clip)
{
// 检查是否一直为1
var curve = AnimationUtility.GetEditorCurve(clip, curveBinding);
var keys = curve.keys;
var isAllwaysOne = true;
for (var i = 0; i < keys.Length; ++i)
{
var key = keys[i];
if (Math.Abs(key.value - 1) > 0.01f)
{
isAllwaysOne = false;
break;
}
}
return isAllwaysOne;
}
private static AnimationClip _CompressClip(AnimationClip clip)
{
var clipName = clip.name;
var savePath = COMPRESSED_PATH + "/compressed_" + clipName + ".anim";
if (_compressedFiles.Contains(savePath))
{
var loadClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(savePath);
return loadClip;
}
_compressedFiles.Add(savePath);
// 如果名字中包含compressed,则不再压缩
if (clip.name.StartsWith("compressed"))
{
return clip;
}
// 读取所有的曲线,删除scale曲线
var curveBindings = AnimationUtility.GetCurveBindings(clip);
var newCurveBindings = new List<EditorCurveBinding>();
foreach (var curveBinding in curveBindings)
{
// Debug.Log("curveBinding.propertyName:" + curveBinding.propertyName);
if (curveBinding.propertyName.Contains("m_LocalScale")
&& _CheckIsAllwaysOne(curveBinding, clip))
{
continue;
}
newCurveBindings.Add(curveBinding);
}
// 截取float精度为4位
foreach (var curveBinding in newCurveBindings)
{
var curve = AnimationUtility.GetEditorCurve(clip, curveBinding);
var keys = curve.keys;
for (var i = 0; i < keys.Length; ++i)
{
var key = keys[i];
key.value = Mathf.Round(key.value * 10000) / 10000;
key.outWeight = Mathf.Round(key.outWeight * 10000) / 10000;
key.inWeight = Mathf.Round(key.inWeight * 10000) / 10000;
keys[i] = key;
}
curve.keys = keys;
AnimationUtility.SetEditorCurve(clip, curveBinding, curve);
}
// 创建新的clip,储存为compressed_原有名称
var newClip = new AnimationClip();
foreach (var curveBinding in newCurveBindings)
{
var curve = AnimationUtility.GetEditorCurve(clip, curveBinding);
AnimationUtility.SetEditorCurve(newClip, curveBinding, curve);
}
AssetDatabase.CreateAsset(newClip, savePath);
return newClip;
}
}