本文共 5112 字,大约阅读时间需要 17 分钟。
如何优化动画资源的精度?本文将详细介绍从项目优化需求到具体实现方案的全过程。
随着工程项目的推进,项目资源性能优化逐渐成为重要任务之一。其中一个关键问题是动画资源的精度过高,导致内存占用异常大。为此,我们需要将动画中的浮点数精度调低至2位小数,或更少或更多。
在优化前的 anim 文件中,我们可以看到浮点数的精度问题严重影响了资源占用。以下是通过 anim 文件的具体内容可以看出问题所在:
time=0.123456789: value=0.123456789inSlope=1.234567890: inWeight=0.123456789outSlope=0.123456789: outWeight=0.123456789
这些浮点数的精度过高,直接导致了资源文件的体积膨胀。
为了解决上述问题,我们需要对动画资源进行精度优化。下面是具体的实现方案:
我们需要通过以下步骤对动画资源进行优化:
为了实现上述目标,我们需要使用 Unity 编辑器提供的 API 进行操作。具体代码如下:
using System.Collections.Generic;using UnityEngine;using UnityEditor;using System.IO;using System;public class AniFloatConstraint : EditorWindow{ void OnGUI() { if (Selection.objects.Length <= 0) { GUILayout.Label("请先选择一个文件夹!!!"); } else { GUILayout.Label("当前选中的文件夹: " + AssetDatabase.GetAssetPath(Selection.objects[0])); } if (GUILayout.Button("开始设置")) { if (!CheckSelection()) return; AssetDatabase.Refresh(); Debug.Log("完成"); } } [MenuItem("ResTool/动画精度工具")] static void SetTextureFormat() { Rect _rect = new Rect(0, 0, 500, 500); var temp = GetWindowWithRect (_rect, false, "设置", true); } public bool CheckSelection() { if (Selection.objects.Length <= 0) { Debug.LogError("请先选择一个文件!!! "); return false; } string selectPath = AssetDatabase.GetAssetPath(Selection.objects[0]); Debug.Log("选择了一个文件/夹!!!" + ":" + selectPath); SetAnimationClip(selectPath); return true; } public void SetAnimationClip(string path) { List animationClipList = new List (); List animationPathList = new List (); string[] dirs = Directory.GetFiles(path, "*", SearchOption.AllDirectories); if (dirs == null || dirs.Length <= 0) { Debug.LogError("当前地址没有获取到任何的动画文件"); return; } for (int i = 0; i < dirs.Length; i++) { AnimationClip objs = AssetDatabase.LoadAssetAtPath (dirs[i]); if (objs != null) { animationClipList.Add(objs); animationPathList.Add(AssetDatabase.GetAssetPath(objs)); } } CompressAnim(animationPathList); } public void CompressAnim(List list_anims) { int num = 2; if (list_anims.Count > 0) { for (int i = 0; i < list_anims.Count; i++) { string path = list_anims[i]; EditorUtility.DisplayProgressBar("CompressAnim", path + " Compressing...", ((float)i / list_anims.Count)); string[] strs = File.ReadAllLines(path); if (strs == null) { continue; } File.WriteAllText(path, ""); FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite); StreamWriter sw = new StreamWriter(fs); sw.Flush(); sw.BaseStream.Seek(0, SeekOrigin.Begin); for (int j = 0; j < strs.Length; j++) { if (strs[j].Contains("time")) { string[] txts = strs[j].Split(':'); if (txts != null) { if (txts[1].Contains(".") && (txts[1].Length - txts[1].IndexOf('.') - 1) >= num) { txts[1] = float.Parse(txts[1]).ToString("f" + num); if (float.Parse(txts[1]) == 0) { txts[1] = "0"; } } strs[j] = txts[0] + ": " + txts[1]; } } else if (strs[j].Contains("value") || strs[j].Contains("inSlope") || strs[j].Contains("outSlope") || strs[j].Contains("inWeight") || strs[j].Contains("outWeight")) { strs[j].Trim(); int frontindex = strs[j].IndexOf('{'); int behindindex = strs[j].IndexOf('}'); string beginstr = null; string str = null; if (frontindex < 0 || behindindex < 0) { string[] txts = strs[j].Split(':'); if (txts != null) { if (txts[1].Contains(".") && (txts[1].Length - txts[1].IndexOf('.') - 1) >= num) { txts[1] = float.Parse(txts[1]).ToString("f" + num); if (float.Parse(txts[1]) == 0) { txts[1] = "0"; } } strs[j] = txts[0] + ": " + txts[1]; sw.WriteLine(strs[j]); continue; } } else { beginstr = strs[j].Substring(0, frontindex); str = strs[j].Substring(frontindex + 1, behindindex - frontindex - 1); } if (str != null) { string[] txts = str.Split(','); if (txts != null) { string tt_new = null; for (int k = 0; k < txts.Length; k++) { string[] newstr = txts[k].Split(':'); if (newstr[1].Contains(".") && (newstr[1].Length - newstr[1].IndexOf('.') - 1) >= num) { newstr[1] = float.Parse(newstr[1]).ToString("f" + num); if (float.Parse(newstr[1]) == 0) { newstr[1] = "0"; } } tt_new += newstr[0] + ": " + newstr[1] + (k == txts.Length - 1 ? "" : ","); } strs[j] = beginstr + "{" + tt_new + "}"; } } sw.WriteLine(strs[j]); } } Debug.Log("修改动画精度:" + path); sw.Flush(); sw.Close(); Resources.UnloadUnusedAssets(); AssetDatabase.SaveAssets(); list_anims.Clear(); GC.Collect(); } EditorUtility.ClearProgressBar(); } } } 通过上述代码,我们可以实现以下操作:
在优化过程中,工具会自动处理所有 anim 文件,确保所有浮点数的精度符合要求。
优化完成后,你可以通过比较原始文件和优化后的文件,观察以下效果:
通过这种方式,我们可以轻松地对动画资源进行精度优化,确保项目性能的最佳状态。
本文详细介绍了如何通过 Unity 编辑器对动画资源进行精度优化的完整流程。该方法简单易于操作,适用于大多数动画资源精度优化场景。
转载地址:http://povpz.baihongyu.com/