博客
关于我
Unity之项目优化-精度优化
阅读量:566 次
发布时间:2019-03-09

本文共 5112 字,大约阅读时间需要 17 分钟。

如何优化动画资源的精度?本文将详细介绍从项目优化需求到具体实现方案的全过程。

前言

随着工程项目的推进,项目资源性能优化逐渐成为重要任务之一。其中一个关键问题是动画资源的精度过高,导致内存占用异常大。为此,我们需要将动画中的浮点数精度调低至2位小数,或更少或更多。

优化前的现状

在优化前的 anim 文件中,我们可以看到浮点数的精度问题严重影响了资源占用。以下是通过 anim 文件的具体内容可以看出问题所在:

time=0.123456789: value=0.123456789
inSlope=1.234567890: inWeight=0.123456789
outSlope=0.123456789: outWeight=0.123456789

这些浮点数的精度过高,直接导致了资源文件的体积膨胀。

优化方案

为了解决上述问题,我们需要对动画资源进行精度优化。下面是具体的实现方案:

背景

我们需要通过以下步骤对动画资源进行优化:

  • 获取目标 anim 文件
  • 将 anim 文件转换为可编辑的文件流
  • 对文件流中的浮点数进行精度调整
  • 将调整后的内容写回原文件
  • 实现细节

    为了实现上述目标,我们需要使用 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(); } } }

    操作步骤

    通过上述代码,我们可以实现以下操作:

  • 打开 Unity 编辑器
  • 导入目标 anim 文件夹
  • 执行优化工具
  • 选择需要优化的 anim 文件夹
  • 点击 "开始设置" 按钮
  • 等待优化完成
  • 在优化过程中,工具会自动处理所有 anim 文件,确保所有浮点数的精度符合要求。

    优化后的效果

    优化完成后,你可以通过比较原始文件和优化后的文件,观察以下效果:

  • 文件体积显著减小
  • 动画资源内存占用降低
  • 性能提升明显
  • 通过这种方式,我们可以轻松地对动画资源进行精度优化,确保项目性能的最佳状态。

    总结

    本文详细介绍了如何通过 Unity 编辑器对动画资源进行精度优化的完整流程。该方法简单易于操作,适用于大多数动画资源精度优化场景。

    转载地址:http://povpz.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现图片腐蚀(附完整源码)
    查看>>
    Objective-C实现图片膨胀(附完整源码)
    查看>>
    Objective-C实现图片转化为 ASCII图(附完整源码)
    查看>>
    Objective-C实现图的拓扑序列(附完整源码)
    查看>>
    Objective-C实现图的邻接矩阵(附完整源码)
    查看>>
    Objective-C实现图结构(附完整源码)
    查看>>
    Objective-C实现圆球的表面积和体积(附完整源码)
    查看>>
    Objective-C实现在list中找到next greatest element下一个更大元素算法(附完整源码)
    查看>>
    Objective-C实现在Regex的帮助下检查字谜算法(附完整源码)
    查看>>
    Objective-C实现在指定区间 [a, b] 中找到函数的实根,其中 f(a)*f(b) < 0算法(附完整源码)
    查看>>
    Objective-C实现均值滤波(附完整源码)
    查看>>
    Objective-C实现埃拉托斯特尼筛法算法(附完整源码)
    查看>>
    Objective-C实现埃拉托色尼筛法(附完整源码)
    查看>>
    Objective-C实现域名解析(附完整源码)
    查看>>
    Objective-C实现域名转IP(附完整源码)
    查看>>
    Objective-C实现培根密码算法(附完整源码)
    查看>>
    Objective-C实现基于 LIFO的堆栈算法(附完整源码)
    查看>>
    Objective-C实现基于 LinkedList 的添加两个数字的解决方案算法(附完整源码)
    查看>>
    Objective-C实现基于opencv的抖动算法(附完整源码)
    查看>>
    Objective-C实现基于事件对象实现线程同步(附完整源码)
    查看>>