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

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

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

前言

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

优化前的现状

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

time=0.123456789: value=0.123456789inSlope=1.234567890: inWeight=0.123456789outSlope=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/

    你可能感兴趣的文章
    Orleans框架------基于Actor模型生成分布式Id
    查看>>
    SQL-36 创建一个actor_name表,将actor表中的所有first_name以及last_name导入改表。
    查看>>
    ORM sqlachemy学习
    查看>>
    Ormlite数据库
    查看>>
    orm总结
    查看>>
    os.environ 没有设置环境变量
    查看>>
    os.path.join、dirname、splitext、split、makedirs、getcwd、listdir、sep等的用法
    查看>>
    os.removexattr 的 Python 文档——‘*‘(星号)参数是什么意思?
    查看>>
    os.system 在 Python 中不起作用
    查看>>
    OS2ATC2017:阿里研究员林昊畅谈操作系统创新与挑战
    查看>>
    OSCACHE介绍
    查看>>
    SQL--合计函数(Aggregate functions):avg,count,first,last,max,min,sum
    查看>>
    OSChina 周五乱弹 ——吹牛扯淡的耽误你们学习进步了
    查看>>
    SQL--mysql索引
    查看>>
    OSChina 周四乱弹 ——程序员为啥要买苹果手机啊?
    查看>>
    OSChina 周日乱弹 —— 2014 年各种奇葩评论集合
    查看>>
    OSChina 技术周刊第十期,每周技术抢先看!
    查看>>
    OSError: no library called “cairo-2“ was foundno library called “cairo“ was foundno library called
    查看>>
    OSError: [WinError 193] %1 不是有效的 Win32 应用程序。
    查看>>
    OSGi与Maven、Eclipse PlugIn的区别
    查看>>