Files
JJBB/Assets/Project/Script/Shader/Editor/AnimationOptimizaztion.cs
2024-08-23 15:49:34 +08:00

197 lines
7.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//****************************************************************************
//
// 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)
// : "结束动画优化时发生错误!");
// }
//}
}
}