diff --git a/Assets/TEngine/Thirdly/Animation/Editor/AnimationHierarchyEditorTool.cs b/Assets/TEngine/Thirdly/Animation/Editor/AnimationHierarchyEditorTool.cs
index a2354617..a31c13f8 100644
--- a/Assets/TEngine/Thirdly/Animation/Editor/AnimationHierarchyEditorTool.cs
+++ b/Assets/TEngine/Thirdly/Animation/Editor/AnimationHierarchyEditorTool.cs
@@ -10,12 +10,14 @@
///
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
+using System.IO;
+using System.Reflection;
+using UnityEngine.Profiling;
// Local Namespace
namespace CGF.Editor.Tools
@@ -29,13 +31,13 @@ namespace CGF.Editor.Tools
public EditorCurveBinding EditorCurve;
- public PathData(string clipName, string currentPath, string lastPath, EditorCurveBinding editorCurve,AnimationClip clip)
+ public PathData(string clipName, string currentPath, string lastPath, EditorCurveBinding editorCurve, AnimationClip clip)
{
ClipName = clipName;
CurrentPath = currentPath;
LastPath = lastPath;
EditorCurve = editorCurve;
- Clip= clip;
+ Clip = clip;
}
}
@@ -47,12 +49,11 @@ namespace CGF.Editor.Tools
/// \endenglish
/// \spanish
///
- /// Herramienta que permite canviar la ruta de la jerarqua de las animaciones de un clip de animacin.
+ /// Herramienta que permite canviar la ruta de la jerarqu韆 de las animaciones de un clip de animaci髇.
///
/// \endspanish
public class CGFAnimationHierarchyEditorTool : EditorWindow
{
-
#region Public Variables
#endregion
@@ -62,7 +63,6 @@ namespace CGF.Editor.Tools
private enum TypeGameObject
{
-
None,
GameObject,
@@ -70,7 +70,6 @@ namespace CGF.Editor.Tools
/*AnimationClip,
RuntimeAnimatorController*/
-
};
private TypeGameObject _currentSelectionGameObject;
@@ -115,16 +114,13 @@ namespace CGF.Editor.Tools
[MenuItem("Tools/Animation Hierarchy Editor Tool")]
private static void ShowWindow()
{
-
EditorWindow window = EditorWindow.GetWindow(typeof(CGFAnimationHierarchyEditorTool), false, "Animation Hierarchy Editor Tool", true);
window.minSize = new Vector2(1024, 250);
-
}
public CGFAnimationHierarchyEditorTool()
{
-
_currentSelectionGameObject = new TypeGameObject();
_currentSelectionGameObject = TypeGameObject.None;
@@ -132,7 +128,6 @@ namespace CGF.Editor.Tools
_myanimationClips = new List();
_gameObjects = new List();
-
}
private void OnEnable()
@@ -145,7 +140,6 @@ namespace CGF.Editor.Tools
ResetSelection();
this.Repaint();
-
}
private void ResetSelection()
@@ -164,15 +158,11 @@ namespace CGF.Editor.Tools
if (Selection.activeGameObject is GameObject)
{
-
_currentSelectionGameObject = TypeGameObject.GameObject;
-
}
else
{
-
_currentSelectionGameObject = TypeGameObject.None;
-
}
DrawSeletedAnimator();
@@ -180,7 +170,6 @@ namespace CGF.Editor.Tools
private void DrawSeletedAnimator()
{
-
if (_currentSelectionGameObject != TypeGameObject.GameObject)
{
return;
@@ -212,18 +201,14 @@ namespace CGF.Editor.Tools
foreach (AnimationClip i in _myruntime.animationClips)
{
-
_myanimationClips.Add(i);
-
}
_clipNames.Add("All Clips");
foreach (AnimationClip e in _myanimationClips)
{
-
_clipNames.Add(e.name);
-
}
if (_myanimationClips.Count > 0)
@@ -240,7 +225,6 @@ namespace CGF.Editor.Tools
private void DrawGui()
{
-
bool animations = true;
EditorGUILayout.Space();
@@ -279,7 +263,6 @@ namespace CGF.Editor.Tools
switch (_selectedMode)
{
-
case 0:
GUILayout.Label("Path");
@@ -295,7 +278,6 @@ namespace CGF.Editor.Tools
_replaceGameObject = (GameObject)EditorGUILayout.ObjectField(_replaceGameObject, typeof(GameObject), true);
break;
-
}
EditorGUILayout.EndHorizontal();
@@ -308,7 +290,6 @@ namespace CGF.Editor.Tools
switch (_currentSelectionGameObject)
{
-
case TypeGameObject.GameObject:
GUI.enabled = true;
@@ -322,7 +303,7 @@ namespace CGF.Editor.Tools
else
{
_currentAnimationClips = new List() { _myanimationClips[index - 1] };
- }
+ }
break;
case TypeGameObject.None:
@@ -349,7 +330,6 @@ namespace CGF.Editor.Tools
switch (_selectedMode)
{
-
case 0:
_replacementPath = EditorGUILayout.TextField(_replacementPath);
@@ -361,7 +341,6 @@ namespace CGF.Editor.Tools
_replacementGameObject = (GameObject)EditorGUILayout.ObjectField(_replacementGameObject, typeof(GameObject), true);
break;
-
}
EditorGUILayout.EndHorizontal();
@@ -395,26 +374,22 @@ namespace CGF.Editor.Tools
if (GUILayout.Button("Apply All", EditorStyles.toolbarButton, GUILayout.Width(70)))
{
-
foreach (var pathData in _pathDataList)
{
UpdatePath(pathData);
}
EditorGUI.FocusTextInControl(null);
-
}
if (GUILayout.Button("Revert All", EditorStyles.toolbarButton, GUILayout.Width(70)))
{
-
foreach (var pathData in _pathDataList)
{
Revert(pathData);
}
EditorGUI.FocusTextInControl(null);
-
}
GUI.enabled = true;
@@ -425,7 +400,6 @@ namespace CGF.Editor.Tools
if (_currentSelectionGameObject != TypeGameObject.None)
{
-
if (_pathDataList != null)
{
scrollPosContent = EditorGUILayout.BeginScrollView(scrollPosContent);
@@ -437,7 +411,6 @@ namespace CGF.Editor.Tools
EditorGUILayout.EndScrollView();
}
-
}
if (!animations)
@@ -473,9 +446,7 @@ namespace CGF.Editor.Tools
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
-
}
-
}
private void Revert(PathData pathData)
@@ -487,10 +458,8 @@ namespace CGF.Editor.Tools
private void Replace()
{
-
switch (_selectedMode)
{
-
case 0:
if (string.IsNullOrEmpty(_replacePath))
@@ -518,7 +487,6 @@ namespace CGF.Editor.Tools
{
pathData.CurrentPath = ChildPath(_replacementGameObject);
}
-
}
break;
@@ -532,7 +500,6 @@ namespace CGF.Editor.Tools
private void GUICreatePathItem(PathData pathData)
{
-
GameObject newObj;
GameObject obj;
@@ -548,11 +515,9 @@ namespace CGF.Editor.Tools
if (obj == null || obj.GetComponent(pathData.EditorCurve.type) == null)
{
-
propertyNameStyle.normal.textColor = Color.yellow;
pathNameStyle.normal.textColor = Color.yellow;
-
}
EditorGUILayout.LabelField(pathData.ClipName, GUILayout.Width(280));
@@ -574,11 +539,9 @@ namespace CGF.Editor.Tools
if (!pathData.CurrentPath.Equals(pathData.EditorCurve.path))
{
-
buttonStyle.fontStyle = FontStyle.Bold;
pathNameStyle.fontStyle = FontStyle.Bold;
-
}
pathData.CurrentPath = EditorGUILayout.TextField(pathData.CurrentPath, pathNameStyle);
@@ -587,14 +550,11 @@ namespace CGF.Editor.Tools
if (obj != null)
{
-
GUI.color = Color.white;
-
}
if (obj == null || obj.GetComponent(pathData.EditorCurve.type) == null)
{
-
GUI.color = Color.yellow;
}
@@ -617,55 +577,40 @@ namespace CGF.Editor.Tools
if (GUILayout.Button("Apply", buttonStyle) && !pathData.CurrentPath.Equals(pathData.EditorCurve.path))
{
-
UpdatePath(pathData);
EditorGUI.FocusTextInControl(null);
-
}
buttonStyle.fontStyle = !pathData.LastPath.Equals(pathData.EditorCurve.path) ? FontStyle.Bold : FontStyle.Normal;
if (GUILayout.Button("Revert", buttonStyle) && pathData.CurrentPath.Equals(pathData.EditorCurve.path))
{
-
-
Revert(pathData);
-
}
EditorGUILayout.EndHorizontal();
try
{
-
if (obj != newObj)
{
-
pathData.CurrentPath = ChildPath(newObj);
-
}
-
}
catch (UnityException ex)
{
-
Debug.LogError(ex.Message);
-
}
-
}
private void OnInspectorUpdate()
{
-
this.Repaint();
-
}
private void FillModel()
{
-
try
{
_pathDataList = new List();
@@ -674,7 +619,8 @@ namespace CGF.Editor.Tools
{
var pathDataListByClip = FillModelWithCurves(currentAnimationClip.name, AnimationUtility.GetCurveBindings(currentAnimationClip), currentAnimationClip);
- var pathDataListByObjectReference = FillModelWithCurves(currentAnimationClip.name, AnimationUtility.GetObjectReferenceCurveBindings(currentAnimationClip), currentAnimationClip);
+ var pathDataListByObjectReference = FillModelWithCurves(currentAnimationClip.name, AnimationUtility.GetObjectReferenceCurveBindings(currentAnimationClip),
+ currentAnimationClip);
_pathDataList.AddRange(pathDataListByClip);
@@ -683,16 +629,12 @@ namespace CGF.Editor.Tools
}
catch (Exception e)
{
-
Console.WriteLine(e);
-
}
-
}
-
- private List FillModelWithCurves(string clipName, EditorCurveBinding[] curves,AnimationClip clip)
+ private List FillModelWithCurves(string clipName, EditorCurveBinding[] curves, AnimationClip clip)
{
var pathDataList = new List();
@@ -712,12 +654,10 @@ namespace CGF.Editor.Tools
}
return pathDataList;
-
}
private void UpdatePath(PathData pathData)
{
-
if (pathData.CurrentPath.Equals(pathData.EditorCurve.path))
{
return;
@@ -762,71 +702,51 @@ namespace CGF.Editor.Tools
FillModel();
this.Repaint();
-
}
private GameObject FindObjectInRoot(string path)
{
-
if (_animatorObject == null)
{
-
return null;
-
}
Transform child = _animatorObject.transform.Find(path);
if (child != null)
{
-
return child.gameObject;
-
}
else
{
-
return null;
-
}
}
private string ChildPath(GameObject obj, bool sep = false)
{
-
if (_animatorObject == null)
{
-
throw new UnityException("Please assign Referenced Animator (Root) first!");
-
}
if (obj == _animatorObject.gameObject)
{
-
return "";
-
}
else
{
-
if (obj.transform.parent == null)
{
-
throw new UnityException("Object must belong to " + _animatorObject.ToString() + "!");
-
}
else
{
-
return ChildPath(obj.transform.parent.gameObject, true) + obj.name + (sep ? "/" : "");
-
}
-
}
-
}
#endregion
@@ -840,7 +760,314 @@ namespace CGF.Editor.Tools
#region Utility Events
#endregion
+ }
+}
+
+namespace TEngine.Editor
+{
+ class AnimationOpt
+ {
+ static Dictionary _FLOAT_FORMAT;
+ static MethodInfo getAnimationClipStats;
+ static FieldInfo sizeInfo;
+ static object[] _param = new object[1];
+
+ static AnimationOpt()
+ {
+ _FLOAT_FORMAT = new Dictionary();
+ for (uint i = 1; i < 6; i++)
+ {
+ _FLOAT_FORMAT.Add(i, "f" + i.ToString());
+ }
+
+ Assembly asm = Assembly.GetAssembly(typeof(UnityEditor.Editor));
+ getAnimationClipStats = typeof(AnimationUtility).GetMethod(
+ "GetAnimationClipStats",
+ BindingFlags.Static | BindingFlags.NonPublic
+ );
+ Type aniclipstats = asm.GetType("UnityEditor.AnimationClipStats");
+ sizeInfo = aniclipstats.GetField("size", BindingFlags.Public | BindingFlags.Instance);
+ }
+
+ AnimationClip _clip;
+ string _path;
+
+ public string path
+ {
+ get { return _path; }
+ }
+
+ public long originFileSize { get; private set; }
+
+ public int originMemorySize { get; private set; }
+
+ public int originInspectorSize { get; private set; }
+
+ public long optFileSize { get; private set; }
+
+ public int optMemorySize { get; private set; }
+
+ public int optInspectorSize { get; private set; }
+
+ public AnimationOpt(string path, AnimationClip clip)
+ {
+ _path = path;
+ _clip = clip;
+ _GetOriginSize();
+ }
+
+ void _GetOriginSize()
+ {
+ originFileSize = _GetFileZie();
+ originMemorySize = _GetMemSize();
+ originInspectorSize = _GetInspectorSize();
+ }
+
+ void _GetOptSize()
+ {
+ optFileSize = _GetFileZie();
+ optMemorySize = _GetMemSize();
+ optInspectorSize = _GetInspectorSize();
+ }
+
+ long _GetFileZie()
+ {
+ FileInfo fi = new FileInfo(_path);
+ return fi.Length;
+ }
+
+ int _GetMemSize()
+ {
+ return Profiler.GetRuntimeMemorySize(_clip);
+ }
+
+ int _GetInspectorSize()
+ {
+ _param[0] = _clip;
+ var stats = getAnimationClipStats.Invoke(null, _param);
+ return (int)sizeInfo.GetValue(stats);
+ }
+
+ void _OptmizeAnimationScaleCurve()
+ {
+ if (_clip != null)
+ {
+ //去除scale曲线
+ foreach (EditorCurveBinding theCurveBinding in AnimationUtility.GetCurveBindings(_clip))
+ {
+ string name = theCurveBinding.propertyName.ToLower();
+ if (name.Contains("scale"))
+ {
+ AnimationUtility.SetEditorCurve(_clip, theCurveBinding, null);
+ Debug.LogFormat("关闭{0}的scale curve", _clip.name);
+ }
+ }
+ }
+ }
+
+ void _OptmizeAnimationFloat_X(uint x)
+ {
+ if (_clip != null && x > 0)
+ {
+ //浮点数精度压缩到f3
+ AnimationClipCurveData[] curves = null;
+ curves = AnimationUtility.GetAllCurves(_clip);
+ Keyframe key;
+ Keyframe[] keyFrames;
+ string floatFormat;
+ if (_FLOAT_FORMAT.TryGetValue(x, out floatFormat))
+ {
+ if (curves != null && curves.Length > 0)
+ {
+ for (int ii = 0; ii < curves.Length; ++ii)
+ {
+ AnimationClipCurveData curveDate = curves[ii];
+ if (curveDate.curve == null || curveDate.curve.keys == null)
+ {
+ //Debug.LogWarning(string.Format("AnimationClipCurveData {0} don't have curve; Animation name {1} ", curveDate, animationPath));
+ continue;
+ }
+
+ keyFrames = curveDate.curve.keys;
+ for (int i = 0; i < keyFrames.Length; i++)
+ {
+ 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));
+ key.inWeight = float.Parse(key.inWeight.ToString(floatFormat));
+ key.outWeight = float.Parse(key.outWeight.ToString(floatFormat));
+ keyFrames[i] = key;
+ }
+
+ curveDate.curve.keys = keyFrames;
+ _clip.SetCurve(
+ curveDate.path,
+ curveDate.type,
+ curveDate.propertyName,
+ curveDate.curve
+ );
+ }
+ }
+ }
+ else
+ {
+ Debug.LogErrorFormat("目前不支持{0}位浮点", x);
+ }
+ }
+ }
+
+ public void Optimize(bool scaleOpt, uint floatSize)
+ {
+ if (scaleOpt)
+ {
+ _OptmizeAnimationScaleCurve();
+ }
+
+ _OptmizeAnimationFloat_X(floatSize);
+ _GetOptSize();
+ }
+
+ public void Optimize_Scale_Float3()
+ {
+ Optimize(false, 3);
+ }
+
+ public void LogOrigin()
+ {
+ _logSize(originFileSize, originMemorySize, originInspectorSize);
+ }
+
+ public void LogOpt()
+ {
+ _logSize(optFileSize, optMemorySize, optInspectorSize);
+ }
+
+ public void LogDelta()
+ {
+ }
+
+ void _logSize(long fileSize, int memSize, int inspectorSize)
+ {
+ Debug.LogFormat(
+ "{0} \nSize=[ {1} ]",
+ _path,
+ string.Format(
+ "FSize={0} ; Mem->{1} ; inspector->{2}",
+ EditorUtility.FormatBytes(fileSize),
+ EditorUtility.FormatBytes(memSize),
+ EditorUtility.FormatBytes(inspectorSize)
+ )
+ );
+ }
}
+ public class OptimizeAnimationClipTool
+ {
+ static List _AnimOptList = new List();
+ static List _Errors = new List();
+ static int _Index = 0;
+
+ [MenuItem("Assets/Animation/裁剪浮点数去除Scale")]
+ public static void Optimize()
+ {
+ _AnimOptList = FindAnims();
+ if (_AnimOptList.Count > 0)
+ {
+ _Index = 0;
+ _Errors.Clear();
+ EditorApplication.update = ScanAnimationClip;
+ }
+ }
+
+ private static void ScanAnimationClip()
+ {
+ AnimationOpt _AnimOpt = _AnimOptList[_Index];
+ bool isCancel = EditorUtility.DisplayCancelableProgressBar(
+ "优化AnimationClip",
+ _AnimOpt.path,
+ (float)_Index / (float)_AnimOptList.Count
+ );
+ _AnimOpt.Optimize_Scale_Float3();
+ _Index++;
+ if (isCancel || _Index >= _AnimOptList.Count)
+ {
+ EditorUtility.ClearProgressBar();
+ Debug.Log(
+ string.Format(
+ "--优化完成-- 错误数量: {0} 总数量: {1}/{2} 错误信息↓:\n{3}\n----------输出完毕----------",
+ _Errors.Count,
+ _Index,
+ _AnimOptList.Count,
+ string.Join(string.Empty, _Errors.ToArray())
+ )
+ );
+ Resources.UnloadUnusedAssets();
+ GC.Collect();
+ AssetDatabase.SaveAssets();
+ EditorApplication.update = null;
+ _AnimOptList.Clear();
+ _cachedOpts.Clear();
+ _Index = 0;
+ }
+ }
+
+ static Dictionary _cachedOpts = new Dictionary();
+
+ static AnimationOpt _GetNewAOpt(string path)
+ {
+ AnimationOpt opt = null;
+ if (!_cachedOpts.ContainsKey(path))
+ {
+ AnimationClip clip = AssetDatabase.LoadAssetAtPath(path);
+ if (clip != null)
+ {
+ opt = new AnimationOpt(path, clip);
+ _cachedOpts[path] = opt;
+ }
+ }
+
+ return opt;
+ }
+
+ static List FindAnims()
+ {
+ string[] guids = null;
+ List path = new List();
+ List assets = new List();
+ UnityEngine.Object[] objs = Selection.GetFiltered(typeof(object), SelectionMode.Assets);
+ if (objs.Length > 0)
+ {
+ for (int i = 0; i < objs.Length; i++)
+ {
+ if (objs[i].GetType() == typeof(AnimationClip))
+ {
+ string p = AssetDatabase.GetAssetPath(objs[i]);
+ AnimationOpt animopt = _GetNewAOpt(p);
+ if (animopt != null) assets.Add(animopt);
+ }
+ else
+ path.Add(AssetDatabase.GetAssetPath(objs[i]));
+ }
+
+ if (path.Count > 0)
+ guids = AssetDatabase.FindAssets(
+ string.Format("t:{0}", typeof(AnimationClip).ToString().Replace("UnityEngine.", "")),
+ path.ToArray()
+ );
+ else
+ guids = new string[] { };
+ }
+
+ for (int i = 0; i < guids.Length; i++)
+ {
+ string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
+ AnimationOpt animopt = _GetNewAOpt(assetPath);
+ if (animopt != null) assets.Add(animopt);
+ }
+
+ return assets;
+ }
+ }
}
\ No newline at end of file