197 lines
7.1 KiB
C#
197 lines
7.1 KiB
C#
//****************************************************************************
|
||
//
|
||
// File: OptimizeAnimationClipTool.cs
|
||
//
|
||
// Copyright (c) SuiJiaBin
|
||
//
|
||
// Modified by Blastom for Unity 5.4.1f1 Adaption and Project Requirement
|
||
// Removed the Functions for Showing to Optimize Editor Performance
|
||
//
|
||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||
// PARTICULAR PURPOSE.
|
||
//
|
||
//****************************************************************************
|
||
using System.Collections.Generic;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
namespace EditorTool
|
||
{
|
||
class AnimationOpt
|
||
{
|
||
private static Dictionary<uint, string> _FLOAT_FORMAT;
|
||
static AnimationOpt()
|
||
{
|
||
_FLOAT_FORMAT = new Dictionary<uint, string>();
|
||
for (uint i = 1; i < 6; i++)
|
||
{
|
||
_FLOAT_FORMAT.Add(i, "f" + i.ToString());
|
||
}
|
||
}
|
||
|
||
AnimationClip _clip;
|
||
string _path;
|
||
|
||
public string path { get { return _path; } }
|
||
public AnimationOpt(string path, AnimationClip clip)
|
||
{
|
||
_path = path;
|
||
_clip = clip;
|
||
}
|
||
|
||
void _OptmizeAnimationScaleCurve()
|
||
{
|
||
var curveBindings = AnimationUtility.GetCurveBindings(_clip);
|
||
//去除scale曲线
|
||
for (var i = 0; i < curveBindings.Length; i++)
|
||
{
|
||
var curveBinding = curveBindings[i];
|
||
string name = curveBinding.propertyName.ToLower();
|
||
if (name.Contains("scale"))
|
||
{
|
||
AnimationUtility.SetEditorCurve(_clip, curveBinding, null);
|
||
Debug.LogFormat("关闭{0}的scale curve", _clip.name);
|
||
}
|
||
}
|
||
}
|
||
|
||
void _OptmizeAnimationFloat_X(uint x)
|
||
{
|
||
var curveBindings = AnimationUtility.GetCurveBindings(_clip);
|
||
//浮点数精度压缩到f3
|
||
string floatFormat;
|
||
if (_FLOAT_FORMAT.TryGetValue(x, out floatFormat))
|
||
{
|
||
if (curveBindings != null && curveBindings.Length > 0)
|
||
{
|
||
for (var ii = 0; ii < curveBindings.Length; ++ii)
|
||
{
|
||
var curveBinding = curveBindings[ii];
|
||
var curve = AnimationUtility.GetEditorCurve(_clip, curveBinding);
|
||
if (curve == null || curve.keys == null)
|
||
continue;
|
||
var keyFrames = curve.keys;
|
||
for (var i = 0; i < keyFrames.Length; i++)
|
||
{
|
||
var key = keyFrames[i];
|
||
key.value = float.Parse(key.value.ToString(floatFormat));
|
||
key.inTangent = float.Parse(key.inTangent.ToString(floatFormat));
|
||
key.outTangent = float.Parse(key.outTangent.ToString(floatFormat));
|
||
keyFrames[i] = key;
|
||
}
|
||
curve.keys = keyFrames;
|
||
_clip.SetCurve(curveBinding.path, curveBinding.type, curveBinding.propertyName, curve);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
Debug.LogErrorFormat("目前不支持{0}位浮点", x);
|
||
}
|
||
|
||
public void Optimize(uint floatSize)
|
||
{
|
||
_OptmizeAnimationFloat_X(floatSize);
|
||
// 暂时不关闭Scale,某些动画会用到Scale
|
||
//_OptmizeAnimationScaleCurve();
|
||
}
|
||
|
||
public void Optimize_Scale_Float3()
|
||
{
|
||
Optimize(3);
|
||
}
|
||
}
|
||
|
||
public class OptimizeAnimationClipTool
|
||
{
|
||
// 每处理100个动画,就会保存一次,然后清空内存
|
||
private const int _saveFrequency = 100;
|
||
private int _unsavedCount;
|
||
|
||
private readonly List<string> _animList;
|
||
private readonly List<string> _errorList;
|
||
|
||
private int _index;
|
||
private int _skipCount;
|
||
|
||
[MenuItem("Assets/Animation/裁剪浮点数去除Scale")]
|
||
public static void Optimize()
|
||
{
|
||
var animList = EditorCommonUtility.GetPathsFromSelectByExtension(".anim");
|
||
if (animList.Count > 0)
|
||
{
|
||
var tool = new OptimizeAnimationClipTool(animList);
|
||
tool.Start();
|
||
}
|
||
}
|
||
|
||
public OptimizeAnimationClipTool(List<string> animList)
|
||
{
|
||
_animList = animList;
|
||
_errorList = new List<string>();
|
||
}
|
||
|
||
public void Start()
|
||
{
|
||
EditorApplication.update = ScanAnimationClip;
|
||
//Application.logMessageReceived += OnLogCallback;
|
||
}
|
||
|
||
private void Stop()
|
||
{
|
||
SaveProgress();
|
||
EditorApplication.update = null;
|
||
//Application.logMessageReceived -= OnLogCallback;
|
||
EditorUtility.ClearProgressBar();
|
||
}
|
||
|
||
private void SaveProgress()
|
||
{
|
||
_unsavedCount = 0;
|
||
AssetDatabase.SaveAssets();
|
||
EditorUtility.UnloadUnusedAssetsImmediate(true);
|
||
}
|
||
|
||
private void ScanAnimationClip()
|
||
{
|
||
if (_unsavedCount >= _saveFrequency)
|
||
SaveProgress();
|
||
else
|
||
{
|
||
var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(_animList[_index]);
|
||
var isCancel = false;
|
||
if (clip == null)
|
||
_skipCount++;
|
||
else if (clip.length <= 0f)
|
||
_errorList.Add(string.Format("动画文件{0}已经损坏,检查动画文件!", _animList[_index]));
|
||
else if (clip.name.ToLower().Contains("_die"))
|
||
_errorList.Add(string.Format("动画文件{0}为死亡动画,应该跳过!", _animList[_index]));
|
||
else
|
||
{
|
||
var animOpt = new AnimationOpt(_animList[_index], clip);
|
||
isCancel = EditorUtility.DisplayCancelableProgressBar("优化AnimationClip", animOpt.path, (float)_index / (float)_animList.Count);
|
||
animOpt.Optimize_Scale_Float3();
|
||
}
|
||
_index++;
|
||
_unsavedCount++;
|
||
if (isCancel || _index >= _animList.Count)
|
||
{
|
||
Stop();
|
||
Debug.Log(string.Format("--优化完成-- 总数量: {0}/{1}", _index - _skipCount, _animList.Count));
|
||
for (var i = 0; i < _errorList.Count; i++)
|
||
Debug.LogError(_errorList[i]);
|
||
}
|
||
}
|
||
}
|
||
//private void OnLogCallback(string logString, string stackTrace, LogType type)
|
||
//{
|
||
// if (type == LogType.Error || type == LogType.Error)
|
||
// {
|
||
// _errorList.Add(_index < _animList.Count
|
||
// ? string.Format("动画{0}发生错误\n{1}\n{2}", _animList[_index], logString, stackTrace)
|
||
// : "结束动画优化时发生错误!");
|
||
// }
|
||
//}
|
||
}
|
||
} |