| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- using UnityEditor;
- using UnityEngine;
- using System.IO;
- using System.Collections.Generic;
- public class AnimationClipper : EditorWindow
- {
- private static AnimationClipper _window = null;
- [MenuItem("Tools/优化/动作/动画剪裁")]
- public static void ClipAnimation()
- {
- _window = EditorWindow.GetWindow<AnimationClipper>(false, "AnimationClipWindow", true);
- _window.Show();
- }
- public void OnGUI()
- {
- if (GUILayout.Button("开始剪裁"))
- {
- foreach(var obj in Selection.objects)
- {
- if(obj.GetType() == typeof(AnimationClip))
- {
- ClipAnimationCurveData((AnimationClip)obj);
- EditorUtility.SetDirty(obj);
- }
- else
- {
- var path = AssetDatabase.GetAssetPath(obj);
- if(Directory.Exists(path))
- {
- ClipAnimationsInDirectory(path);
- }
- }
- }
- AssetDatabase.SaveAssets();
- }
- }
- private static void ClipAnimationsInDirectory(string path)
- {
- string pathDir = FileUtils.ExtractAssetRelativePath(path);
- var files = Directory.GetFiles(pathDir, "*.anim", SearchOption.AllDirectories);
- foreach (var file in files)
- {
- string fileName = FileUtils.ExtractAssetRelativePath(file);
- var clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(fileName, typeof(AnimationClip));
- if (null != clip)
- {
- ClipAnimationCurveData((AnimationClip)clip);
- EditorUtility.SetDirty(clip);
- }
- }
- }
- public static bool ClipAnimationCurveData(AnimationClip clip)
- {
- if (clip == null)
- {
- return false;
- }
- EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip);
- if (curveBindings == null)
- {
- return false;
- }
- AnimationCurve[] curves = new AnimationCurve[curveBindings.Length];
- for (int idx =0; idx < curveBindings.Length;idx++)
- {
- AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, curveBindings[idx]);
- curves[idx] = curve;
- }
- // 清除原来所有的数据
- clip.ClearCurves();
- float len = clip.length;
- for (int idx = 0; idx < curveBindings.Length; idx++)
- {
- EditorCurveBinding ecb = curveBindings[idx];
- AnimationCurve curve = curves[idx];
- // 进行过滤
- if (IsFilterCurveData(curveBindings[idx].propertyName, curve))
- {
- continue;
- }
- // 将数据存回去
- clip.SetCurve(ecb.path, ecb.type, ecb.propertyName, curve);
- }
- curves = null;
- return true;
- }
- public static bool IsFilterCurveData(string propertyName, AnimationCurve curve)
- {
- if (propertyName.Contains("Position"))
- {
- return IsNoEffectCurvy(curve, 0);
- }
- if (propertyName.Contains("Scale"))
- {
- return IsNoEffectCurvy(curve, 1, true);
- }
- if (propertyName.Contains("Rotation"))
- {
- return IsNoEffectCurvy(curve, 0, true);
- }
- return false;
- }
- public static bool IsNoEffectCurvy(AnimationCurve curve, float identity, bool reserveIdentity = false)
- {
- if(curve.keys == null || curve.keys.Length == 0)
- {
- return true;
- }
- var keys = new List<Keyframe>(curve.keys);
- // 减去多余的帧
- for(int i = 0; i < keys.Count;)
- {
- if(i - 1 < 0)
- {
- i++;
- continue;
- }
- if(i + 1 >= keys.Count)
- {
- i++;
- continue;
- }
- // 如果一帧的前一帧和后一帧都和当前帧相等,那么可以删除自己
- if (IsKeyFrameEqual(keys[i-1], keys[i]) && IsKeyFrameEqual(keys[i], keys[i+1]))
- {
- keys.RemoveAt(i);
- continue;
- }
- i++;
- }
- // 如果只剩下2帧了,那么这两帧肯定是相等的,根据参数判断是否整个曲线都去掉
- if(keys.Count <= 2)
- {
- if (Mathf.Abs(keys[0].value - identity) < 0.001f && !reserveIdentity)
- {
- return true;
- }
- }
- curve.keys = keys.ToArray();
- return false;
- }
- private static bool IsKeyFrameEqual(Keyframe frame1, Keyframe frame2)
- {
- if (Mathf.Abs(frame1.value - frame2.value) > 0.001f)
- {
- return false;
- }
- if (Mathf.Abs(frame1.inTangent - frame2.inTangent) > 0.001f)
- {
- return false;
- }
- if (Mathf.Abs(frame1.outTangent - frame2.outTangent) > 0.001f)
- {
- return false;
- }
- if (Mathf.Abs(frame1.tangentMode - frame2.tangentMode) > 0.001f)
- {
- return false;
- }
- return true;
- }
- }
|