Unity压缩Animation

unity animation 压缩

https://blog.csdn.net/lingyun5905/article/details/86255192

http://gad.qq.com/article/detail/27424

https://blog.uwa4d.com/archives/Optimization_Animation.html

最后附上工具的代码和简要使用说明,选中想要优化的文件夹或文件,右键Animation->裁剪浮点数去除Scale。
请输入图片描述

 
  1. //****************************************************************************

  2. //

  3. // File: OptimizeAnimationClipTool.cs

  4. //

  5. // Copyright (c) SuiJiaBin

  6. //

  7. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF

  8. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO

  9. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A

  10. // PARTICULAR PURPOSE.

  11. //

  12. //****************************************************************************

  13. using System;

  14. using System.Collections.Generic;

  15. using UnityEngine;

  16. using System.Reflection;

  17. using UnityEditor;

  18. using System.IO;

  19.  
  20. namespace EditorTool

  21. {

  22. class AnimationOpt

  23. {

  24. static Dictionary<uint,string> _FLOAT_FORMAT;

  25. static MethodInfo getAnimationClipStats;

  26. static FieldInfo sizeInfo;

  27. static object[] _param = new object[1];

  28.  
  29. static AnimationOpt ()

  30. {

  31. _FLOAT_FORMAT = new Dictionary<uint, string> ();

  32. for (uint i = 1; i < 6; i++) {

  33. _FLOAT_FORMAT.Add (i, "f" + i.ToString ());

  34. }

  35. Assembly asm = Assembly.GetAssembly (typeof(Editor));

  36. getAnimationClipStats = typeof(AnimationUtility).GetMethod ("GetAnimationClipStats", BindingFlags.Static | BindingFlags.NonPublic);

  37. Type aniclipstats = asm.GetType ("UnityEditor.AnimationClipStats");

  38. sizeInfo = aniclipstats.GetField ("size", BindingFlags.Public | BindingFlags.Instance);

  39. }

  40.  
  41. AnimationClip _clip;

  42. string _path;

  43.  
  44. public string path { get{ return _path;} }

  45.  
  46. public long originFileSize { get; private set; }

  47.  
  48. public int originMemorySize { get; private set; }

  49.  
  50. public int originInspectorSize { get; private set; }

  51.  
  52. public long optFileSize { get; private set; }

  53.  
  54. public int optMemorySize { get; private set; }

  55.  
  56. public int optInspectorSize { get; private set; }

  57.  
  58. public AnimationOpt (string path, AnimationClip clip)

  59. {

  60. _path = path;

  61. _clip = clip;

  62. _GetOriginSize ();

  63. }

  64.  
  65. void _GetOriginSize ()

  66. {

  67. originFileSize = _GetFileZie ();

  68. originMemorySize = _GetMemSize ();

  69. originInspectorSize = _GetInspectorSize ();

  70. }

  71.  
  72. void _GetOptSize ()

  73. {

  74. optFileSize = _GetFileZie ();

  75. optMemorySize = _GetMemSize ();

  76. optInspectorSize = _GetInspectorSize ();

  77. }

  78.  
  79. long _GetFileZie ()

  80. {

  81. FileInfo fi = new FileInfo (_path);

  82. return fi.Length;

  83. }

  84.  
  85. int _GetMemSize ()

  86. {

  87. return Profiler.GetRuntimeMemorySize (_clip);

  88. }

  89.  
  90. int _GetInspectorSize ()

  91. {

  92. _param [0] = _clip;

  93. var stats = getAnimationClipStats.Invoke (null, _param);

  94. return (int)sizeInfo.GetValue (stats);

  95. }

  96.  
  97. void _OptmizeAnimationScaleCurve ()

  98. {

  99. if (_clip != null) {

  100. //去除scale曲线

  101. foreach (EditorCurveBinding theCurveBinding in AnimationUtility.GetCurveBindings(_clip)) {

  102. string name = theCurveBinding.propertyName.ToLower ();

  103. if (name.Contains ("scale")) {

  104. AnimationUtility.SetEditorCurve (_clip, theCurveBinding, null);

  105. Debug.LogFormat ("关闭{0}的scale curve", _clip.name);

  106. }

  107. }

  108. }

  109. }

  110.  
  111. void _OptmizeAnimationFloat_X (uint x)

  112. {

  113. if (_clip != null && x > 0) {

  114. //浮点数精度压缩到f3

  115. AnimationClipCurveData[] curves = null;

  116. curves = AnimationUtility.GetAllCurves (_clip);

  117. Keyframe key;

  118. Keyframe[] keyFrames;

  119. string floatFormat;

  120. if (_FLOAT_FORMAT.TryGetValue (x, out floatFormat)) {

  121. if (curves != null && curves.Length > 0) {

  122. for (int ii = 0; ii < curves.Length; ++ii) {

  123. AnimationClipCurveData curveDate = curves [ii];

  124. if (curveDate.curve == null || curveDate.curve.keys == null) {

  125. //Debug.LogWarning(string.Format("AnimationClipCurveData {0} don't have curve; Animation name {1} ", curveDate, animationPath));

  126. continue;

  127. }

  128. keyFrames = curveDate.curve.keys;

  129. for (int i = 0; i < keyFrames.Length; i++) {

  130. key = keyFrames [i];

  131. key.value = float.Parse (key.value.ToString (floatFormat));

  132. key.inTangent = float.Parse (key.inTangent.ToString (floatFormat));

  133. key.outTangent = float.Parse (key.outTangent.ToString (floatFormat));

  134. keyFrames [i] = key;

  135. }

  136. curveDate.curve.keys = keyFrames;

  137. _clip.SetCurve (curveDate.path, curveDate.type, curveDate.propertyName, curveDate.curve);

  138. }

  139. }

  140. } else {

  141. Debug.LogErrorFormat ("目前不支持{0}位浮点", x);

  142. }

  143. }

  144. }

  145.  
  146. public void Optimize (bool scaleOpt, uint floatSize)

  147. {

  148. if (scaleOpt) {

  149. _OptmizeAnimationScaleCurve ();

  150. }

  151. _OptmizeAnimationFloat_X (floatSize);

  152. _GetOptSize ();

  153. }

  154.  
  155. public void Optimize_Scale_Float3 ()

  156. {

  157. Optimize (true, 3);

  158. }

  159.  
  160. public void LogOrigin ()

  161. {

  162. _logSize (originFileSize, originMemorySize, originInspectorSize);

  163. }

  164.  
  165. public void LogOpt ()

  166. {

  167. _logSize (optFileSize, optMemorySize, optInspectorSize);

  168. }

  169.  
  170. public void LogDelta ()

  171. {

  172.  
  173. }

  174.  
  175. void _logSize (long fileSize, int memSize, int inspectorSize)

  176. {

  177. Debug.LogFormat ("{0} \nSize=[ {1} ]", _path, string.Format ("FSize={0} ; Mem->{1} ; inspector->{2}",

  178. EditorUtility.FormatBytes (fileSize), EditorUtility.FormatBytes (memSize), EditorUtility.FormatBytes (inspectorSize)));

  179. }

  180. }

  181.  
  182. public class OptimizeAnimationClipTool

  183. {

  184. static List<AnimationOpt> _AnimOptList = new List<AnimationOpt> ();

  185. static List<string> _Errors = new List<string>();

  186. static int _Index = 0;

  187.  
  188. [MenuItem("Assets/Animation/裁剪浮点数去除Scale")]

  189. public static void Optimize()

  190. {

  191. _AnimOptList = FindAnims ();

  192. if (_AnimOptList.Count > 0)

  193. {

  194. _Index = 0;

  195. _Errors.Clear ();

  196. EditorApplication.update = ScanAnimationClip;

  197. }

  198. }

  199.  
  200. private static void ScanAnimationClip()

  201. {

  202. AnimationOpt _AnimOpt = _AnimOptList[_Index];

  203. bool isCancel = EditorUtility.DisplayCancelableProgressBar("优化AnimationClip", _AnimOpt.path, (float)_Index / (float)_AnimOptList.Count);

  204. _AnimOpt.Optimize_Scale_Float3();

  205. _Index++;

  206. if (isCancel || _Index >= _AnimOptList.Count)

  207. {

  208. EditorUtility.ClearProgressBar();

  209. Debug.Log(string.Format("--优化完成-- 错误数量: {0} 总数量: {1}/{2} 错误信息↓:\n{3}\n----------输出完毕----------", _Errors.Count, _Index, _AnimOptList.Count, string.Join(string.Empty, _Errors.ToArray())));

  210. Resources.UnloadUnusedAssets();

  211. GC.Collect();

  212. AssetDatabase.SaveAssets();

  213. EditorApplication.update = null;

  214. _AnimOptList.Clear();

  215. _cachedOpts.Clear ();

  216. _Index = 0;

  217. }

  218. }

  219.  
  220. static Dictionary<string,AnimationOpt> _cachedOpts = new Dictionary<string, AnimationOpt> ();

  221.  
  222. static AnimationOpt _GetNewAOpt (string path)

  223. {

  224. AnimationOpt opt = null;

  225. if (!_cachedOpts.ContainsKey(path)) {

  226. AnimationClip clip = AssetDatabase.LoadAssetAtPath<AnimationClip> (path);

  227. if (clip != null) {

  228. opt = new AnimationOpt (path, clip);

  229. _cachedOpts [path] = opt;

  230. }

  231. }

  232. return opt;

  233. }

  234.  
  235. static List<AnimationOpt> FindAnims()

  236. {

  237. string[] guids = null;

  238. List<string> path = new List<string>();

  239. List<AnimationOpt> assets = new List<AnimationOpt> ();

  240. UnityEngine.Object[] objs = Selection.GetFiltered(typeof(object), SelectionMode.Assets);

  241. if (objs.Length > 0)

  242. {

  243. for(int i = 0; i < objs.Length; i++)

  244. {

  245. if (objs [i].GetType () == typeof(AnimationClip))

  246. {

  247. string p = AssetDatabase.GetAssetPath (objs [i]);

  248. AnimationOpt animopt = _GetNewAOpt (p);

  249. if (animopt != null)

  250. assets.Add (animopt);

  251. }

  252. else

  253. path.Add(AssetDatabase.GetAssetPath (objs [i]));

  254. }

  255. if(path.Count > 0)

  256. guids = AssetDatabase.FindAssets (string.Format ("t:{0}", typeof(AnimationClip).ToString().Replace("UnityEngine.", "")), path.ToArray());

  257. else

  258. guids = new string[]{};

  259. }

  260. for(int i = 0; i < guids.Length; i++)

  261. {

  262. string assetPath = AssetDatabase.GUIDToAssetPath (guids [i]);

  263. AnimationOpt animopt = _GetNewAOpt (assetPath);

  264. if (animopt != null)

  265. assets.Add (animopt);

  266. }

  267. return assets;

  268. }

  269. }

  270. }

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值