Unity场景ab包加载压缩(LZ4,LZMA)格式的测试

Unity加载优化-将基于LZMA的ab压缩方案修改为LZ4压缩的过程 # 观前提示 本文适合需要了解LZMA以及LZ4进行ab打包方案同学,以及会将一些资源管理的方案。如果恰好你也用xlua-framework,那就更适合你了。 # 优化起因 最近新游戏在Iphone6上出现了闪退的情况,出现闪退是在加载完成后的一瞬间,用脚指头想都知道内存超过上限了,查了下Iphone6内存为1GB,可使用最大内存上限为645M,理应是一个很高的内存值,由于新游戏是一款3d大地图城建游戏,模型建筑特别多,内存也出现溢出。这让我不得不想办法优化内存以及加载速度,一般的内存优化是从纹理,模 阅读详情

情况

最近场景越来越大,大概800M的场景加载时间可能长达40秒左右,所以需要测试看看发生了什么。

测试环境

测试环境Win10,21thI5-12600KF,32GRam , Nvidia GF RTX2060 32G
Scene1大小:741M

加载代码

首先放上部分的加载场景的代码:

        public float sceneprog;
        public AsyncOperation sceneAsync;
        async public Task LoadScene(string path)
        {
            sceneprog = 0f;
            await Task.Delay(10);
            StreamAssetVer sav = GameJsonMain.inst.Get(path);
            if (sav == null)
            {
                Debug.LogWarning("不存在的场景:" + path);
                return ;
            }
            if (!sav.isab)
            {
                Debug.LogWarning("场景isab必须对勾:" + path);
                return;
            }
            float loadtime = Time.realtimeSinceStartup;
            float computloadtime;
            float ratetime = 0.9f;
            //Application.backgroundLoadingPriority = ThreadPriority.Low;
            
            Debug.Log("LoadScene - begin ..."+ Application.backgroundLoadingPriority);
#if UNITY_EDITOR && TESTRES
            string[] dirs = UnityEditor.AssetDatabase.GetAssetPathsFromAssetBundle(path);
            //Object[] listobj = new Object[dirs.Length];
            if(dirs.Length == 0)
                Debug.LogWarning("找不到这个资源:" + path);
            for (int i = 0; i < dirs.Length; i++)
            {
                string assetPathAndName = dirs[i];
                LoadSceneParameters ls;
                ls = new LoadSceneParameters();
                ls.loadSceneMode = LoadSceneMode.Additive;
                
                sceneAsync = EditorSceneManager.LoadSceneAsyncInPlayMode(assetPathAndName,ls);  // .LoadSceneInPlayMode(assetPathAndName, ls);
                sceneAsync.allowSceneActivation = false;
                while (sceneAsync.progress < 0.9f)
                {
                    sceneprog = sceneAsync.progress;
                    await Task.Delay(100);
                    Debug.Log("load - " + sceneprog);
                }
                //sceneAsync.allowSceneActivation = true;
                //listobj[i] = null;
            }
            sceneprog = 1f;
            //Debug.Log("load1 - " + sceneprog);

            computloadtime = Time.realtimeSinceStartup - loadtime;
            Debug.Log("LoadScene unity- load file time : " + computloadtime);
            return ;
#endif
            Task<UnityWebRequest> task;
            if (sav.include)
            {
                task = streamingAssetsLoader(sav);
            }
            else
            {
                task = AssetsLoader(sav);
            }
            await task;
            UnityWebRequest www = task.Result;
            if (www.result != UnityWebRequest.Result.Success)
            {
                www.Dispose();
                return ;
            }

            computloadtime = Time.realtimeSinceStartup - loadtime;
            Debug.Log("LoadScene - load file time : " + computloadtime);
            //这个LoadFromFileAsync函数的路径不需要file://
            AssetBundleCreateRequest abRequest;
#if UNITY_EDITOR
            abRequest = AssetBundle.LoadFromFileAsync(sav.savepath.Replace(filelink, ""));
#else
            if(Application.platform == RuntimePlatform.Android)
            {
                abRequest = AssetBundle.LoadFromFileAsync(sav.savepath);
            }
            else
            {
                abRequest = AssetBundle.LoadFromFileAsync(sav.savepath.Replace(filelink, ""));
            }
#endif
            abRequest.allowSceneActivation = false;
            
            while (!abRequest.isDone)
            {
                sceneprog = abRequest.progress;
                await Task.Delay(100);
                //Debug.Log("ab:"+ sceneprog);
            }
            abRequest.allowSceneActivation = true;
            AssetBundle ab = abRequest.assetBundle;

            computloadtime = Time.realtimeSinceStartup - loadtime;
            Debug.Log("LoadScene - load AssetBundle time :" + computloadtime);
            //Debug.Log("ab1:ok," + sav.path +" - "+ sav.url);

            sceneAsync = SceneManager.LoadSceneAsync(sav.path, LoadSceneMode.Additive);
            sceneAsync.allowSceneActivation = false;
            while (sceneAsync.progress < 0.9f)
            {
                sceneprog = ratetime + sceneAsync.progress * (1- ratetime);
                await Task.Delay(100);
                //Debug.Log("load:" + sceneprog);
            }

            sceneprog = 1f;
            computloadtime = Time.realtimeSinceStartup - loadtime;
            Debug.Log("LoadScene - load LoadSceneAsync time :" + computloadtime);
            await Task.Delay(300);
            
            //sceneAsync.allowSceneActivation = true;
            //SceneManager.LoadScene(ab.GetAllScenePaths()[0]);
            //Object[] objs = ab. ab.LoadAllAssets();
            www.Dispose();
            ab.Unload(false);
            return ;
        }

大致代码分为2部分,在编辑器下#if UNITY_EDITOR && TESTRES 使用编辑器加载方式。

首先我们直接用编辑器通过UnityEditor.AssetDatabase.GetAssetPathsFromAssetBundle(path);方法来载入,大概需要5.5-7秒时间。为什么AB包需要那么久 ?

异步和同步加载测试

所有有了下面的AB包测试。
因为是AB包下载,所以关闭宏定义TESTRES ,我在想是不是使用了AssetBundle.LoadFromFileAsync来异步加载的,所以比较慢,所以把函数改为了AssetBundle.LoadFromFile,发现:

同步LoadFromFile方式:33秒
异步LoadFromFileAsync方式:38秒

时间都挺长的,发现有一个修改后台CPU级别的函数Application.backgroundLoadingPriority。

  • ThreadPriority.Low - 2ms
  • ThreadPriority.BelowNormal - 4ms
  • ThreadPriority.Normal - 10ms
  • ThreadPriority.High - 50ms
    改为了High,发现测试的结果相差不大。

压缩方式的对比

把场景的AB包我又打包成了无压缩格式和LZ4格式。我们看看测试结论
默认我的场景是LZMA格式

LZMA : 38秒
无压缩: 4.8秒
LZ4 : 4.7秒

结论

LZ4的压缩方式解压速度非常快和无压缩相差不大,压缩后大小比无压缩强的多,这种不需要从公网下载资源的推荐LZ4。

知识点

LZMA通过UnityWebRequestAssetBundle加载的LZMA格式AB包将自动重新压缩为LZ4压缩,并缓存在本地文件系统上。而通过自己写的下载方案,则可以调用AssetBundle.RecompressAssetBundleAsync API重新压缩。

参考:

https://zhuanlan.zhihu.com/p/342694796

Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

https://segmentfault.com/a/1190000019656656

LZ4压缩算法的实现 LZ4是Unity中用于资源压缩的高性能无损算法,基于LZ77改进,通过滑动窗口和哈希表实现快速解压。Unity优化了其实现,包括内存管理(预分配缓冲区)、SIMD加速和线程安全设计。相比LZMA和Deflate,LZ4在压缩/解压速度和内存开销上表现更优,特别适合AssetBundle压缩和实时网络传输。Unity默认使用LZ4HC模式,支持跨平台差异处理,并通过CRC校验确保数据完整性。该算法可使资源包体缩小30-50%,同时保持极低的处理延迟。 阅读详情

相关推荐

Unity Asset Bundle压缩与加载优化:LZ4流式加载实战指南

在游戏开发中,资源管理是影响用户体验和项目性能的核心环节。其原理在于如何高效地组织、压缩和加载游戏资产,以平衡包体大小、内存占用与加载速度。这项技术的核心价值在于,它直接决定了应用的启动时间、运行流畅度以及更新效率。在Unity引擎中,Asset Bundle是实现资源热更新与动态加载的关键技术。通过对比分析LZMA高压缩比与LZ4快速解压的特性,开发者可以针对不同应用场景(如网络传输与本地加载)选择最优策略。本文聚焦于LZ4压缩格式,深入探讨其基于块的压缩原理如何支持资源流式加载,从而实现平滑的内存曲线与

weixin_30843605的博客 2370

Unity中ab包压缩方案 LZMA 和LZ4

Unity中针对LZ4和LZMA两种压缩方式的比较和选择

qq_38721111的博客 6434

Unity AssetBundle压缩格式LZMA与LZ4内存管理实战指南

在Unity游戏开发中,资源管理是性能优化的核心环节,而AssetBundle作为资源动态加载的关键技术,其内存行为直接影响应用的流畅度与稳定性。理解资源压缩与加载原理,是解决内存泄漏、加载卡顿等问题的技术基础。LZMA与LZ4是两种主流的压缩算法,它们代表了空间效率与时间效率的不同设计哲学。LZMA通过全局字典压缩实现极高的压缩比,能显著减少网络下载体积,但加载时需在内存中完整解压,导致瞬时内存峰值陡增。LZ4则采用基于块的压缩方式,支持按需解压,实现了平滑的内存占用和极快的加载速度,尤其适合对内存敏感和

weixin_30859423的博客 423

unity知识笔记

压缩大小:lzma比lz4小。所以加载lzma的速度会快,lz4的速度会慢压缩时间:lzma会远远高于lz4.解压缩时间:lzma的解压缩时间比lz4慢。lz4的解压缩时间比较快。总结:lzma的解加载速度比较快,lz4的解压缩时间比较快。但是从压缩比和速度来看lz4会更优全称Level Of Detail,中文翻译“细节级别渐变”,顾名思义,不同的级别展示不同的细节,那么究竟这个技术是如何运用在游戏项目中的呢?通过例子我们来学习一下。

weixin_44192860的博客 1306

Unity性能优化:AssetBundle内存管理全攻略(LZMA vs LZ4实测对比)

本文深入探讨Unity性能优化中的AssetBundle内存管理策略,重点对比LZMA与LZ4压缩算法的实际表现。通过实测数据揭示LZ4在移动端设备上的内存优势,并提供避免内存泄漏的五大技巧和移动端专项优化方案,帮助开发者有效控制内存波动,提升游戏帧率稳定性。

weixin_30596343的博客 414

Unity进阶实战 -- AssetBundle(AB包)热更新全流程解析

本文深入解析Unity中AssetBundle(AB包)的热更新全流程,涵盖资源标记、打包策略、运行时加载与卸载技巧,以及热更新系统的完整实现。通过实战案例和性能优化建议,帮助开发者掌握AB包动态加载技术,有效减小包体大小并实现资源热更新,提升游戏开发效率。

weixin_28312391的博客 107

Unity快速切换场景的解决方法

本系列文章由抗痘洁面泥 出品,转载请注明出处。 Unity快速切换场景的解决方法 最近项目在上线测试了之后,每次切换场景需要大概10s左右的时间,这样会导致用户体验很差,合作方想要的效果是达到像剑侠情缘那样的很快的切换速度,大概2秒左右就能把场景切换的效果。因为大多数游戏都会在加载场景的时候处理一些复杂逻辑,还有预加载人物等一系列操作,再加上场景本身也很大很复杂,所以要想达到很快的切换场...

hj1037374062的博客 3941

Unity AssetBundle 之 (进阶)高效资源打包与平台适配技巧

本文深入探讨Unity AssetBundle的进阶打包技巧,旨在解决打包速度、包体大小与跨平台兼容性三大核心痛点。详细对比了LZMA与LZ4压缩算法的适用场景,并分享了增量打包、多平台适配以及依赖管理等高效策略,帮助开发者实现资源包的快速、轻量与稳定部署。

weixin_29011239的博客 311

Unity——深入解析AB包(AssetBundle)的内存管理与优化策略

本文深入解析了Unity AssetBundle(AB包)的内存管理与优化策略。文章详细阐述了AB包从加载、实例化到卸载的完整生命周期,对比了LZMA与LZ4压缩算法的优劣及适用场景,并提供了基于引用计数的加载卸载最佳实践代码示例。同时,探讨了依赖管理、打包粒度设计等顶层优化方案,旨在帮助开发者避免内存泄漏,提升游戏性能。

d6e7f8g9h的博客 480

Unity 热更新技术 | (二) AssetBundle - 完整系列教程学习

开始学习热更新方面系列知识,就从这一篇开始吧! 本系列教程 会从热更新基本概念出发,详细介绍热更新相关的全套知识点。 如热更新技术基本原理、热更新主流方案、AssetBundle系列教程、Lua语言编程、Lua与Unity交互教程、Xlua框架使用、热更新实战教程等方面。 热更新作为一个开发者必备技能,如果想学习的话,可以从现在开始了哦~ 接下来从 AssetBundle - 完整系列教程学习 开始学习吧!

努力前行,总会成为自己心中的那道光 1万+

Unity_LZMA方式的压缩与解压

使用LZMA压缩与解压Unity的Assetbundle包

Assetbundle使用LAMA还是LZ4的一些注意事项

如需转载请注明出处最近遇到了一个assetbundle打包使用LZMA还是LZ4导致内存差异很大的问题。在进入到相同的场景里面的时候就是出生场景,使用LZMA+LoadFromFile比使用LZ4+LoadFromFile大了足足200M,然后去官网上查看了这两种格式的差异文档里面说LZMA在使用LoadFromFile加载的时候会先把LZMA的bundle解压然后再压缩成LZ4,内存中会有被压缩...

tc3819171的博客 6712

Revit二次开发之双事件:空闲事件与DocumentChanged事件

对以下文章所展示的代码进行了修改,当前展示的代码可直接复制使用。 由于本人初学,下列语言为个人理解,如有错误请指正。   《引用1》中: 使用模态对话框,或者尽量保证事件在ExternalCommand的Execute函数或者ExternalApplication的OnStartup函数里面注册。 如果一定要使用非模态对话框,那么请使用ExternalEvent事件的Raise函数,强迫...

一个Revit二次开发的实习生 6147

WebGL资源压缩优化:LZ4与LZMA算法对比与内存峰值解决方案

资源压缩是WebGL应用性能优化的关键技术,通过算法减少资源体积来提升加载效率。LZMA算法以其高压缩比著称,但解压时需要较大内存缓冲区,容易产生内存峰值;而LZ4算法采用流式解压方式,内存占用更平稳。在浏览器沙箱环境内存受限的背景下,合理选择压缩算法对避免页面崩溃至关重要。WebGL项目开发中,AssetBundle的资源加载方案直接影响用户体验,采用LZ4压缩能够有效平衡压缩比与内存消耗,特别适合Web端3D应用场景。本文针对LZMA解压内存过高问题,提供完整的优化方案和实战案例。

weixin_34321753的博客 368

汇川PLC用户程序结构详解:如何像搭积木一样配置多任务?附EtherCAT最佳实践

本文深入解析汇川PLC用户程序结构,阐述如何像搭积木一样,通过POU、FB、FC等模块化组件高效配置多任务。文章重点结合EtherCAT通讯场景,分享了任务周期、优先级设置的最佳实践与关键避坑指南,帮助工程师构建稳定、高效的运动控制系统。

weixin_29184075的博客 541

QMT Python API 实战指南:从安装到策略开发的完整流程

本文提供了一份详尽的QMT Python API实战指南,涵盖从环境配置到策略开发的完整流程。文章深入解析了xtdata行情模块与xttrader交易模块的核心架构与协作方式,并通过一个双均线策略实例,手把手教你如何获取数据、计算信号并执行交易,是量化交易开发者快速上手QMT Python接口文档的实用教程。

butter的博客 1416

Unity AB包

概念 AssetBundle是一个压缩包,包含模型、贴图、预制体、声音、甚至整个场景。 它可以在游戏运行时加载。 AssetBundle的包会保存包与包之间的依赖关系。比如有一个模型的包,有一个贴图的包,模型用到了贴图,然后它们两个包之间就有依赖的关系。 压缩包有两种算法,一种是LZMA,另一种是LZ4。 AssetBundle中一般包含两类文件。一类是序列化文件(只有一个),另一类是源文件。 序列化文件:预制体、模型等文件,使用二进制的形式,统一地写入一个单独的文件中。 源文件:图..

海月的博客 2948

【Halcon】双目立体视觉引导机械手有序抓取,案例分享

本文介绍了一个基于双目视觉的工件定位与抓取系统。该系统使用两个工业相机组成双目视觉系统,通过标定获取相机参数,采用模板匹配算法识别任意摆放且可能交叠的工件。重点阐述了三维坐标获取方法,特别是通过Z方向高度实现有序抓取的策略。文章详细说明了系统搭建、双目标定、模板创建等关键步骤,并展示了特征点匹配和定位结果。该案例为初学者和开发者提供了双目视觉系统的基本实现参考,展示了机器视觉与机械手协同工作的典型应用场景。

机器视觉从业者 2490

Unity PC端图片资源AB打包与加载性能优化实战

AssetBundle是Unity中管理外部资源的核心机制,其本质是将序列化资产打包为可按需加载的二进制文件,通过解包、内存加载、资源解析和GPU上传四阶段完成交付。在PC平台,缺乏内存硬约束易导致图片资源滥用,引发加载卡顿、显存溢出与构建失控等典型问题。本文聚焦大量PNG/JPG UI图场景,深入剖析LZ4压缩失效、小包IO放大、Texture2D显存三倍膨胀、Addressables隐式驻留等关键技术陷阱,并提供基于分组聚类、物理预加载、UnityWebRequest接管IO、DXT压缩强制指定、资源深

weixin_30561177的博客 776

西电计组实验一 存储器实验

计组实验报告 实验一 存储器实验——FPGA中LPM_ROM定制与读出实验 一.实验目的   1.掌握FPGA中lpm_ROM的设置,作为只读存储器ROM的工作特性和配置方法;   2.用文本编辑器编辑mif文件配置ROM,学习将程序代码以mif格式文件加载于lpm_ROM中;   3.在初始化存储器编辑窗口编辑mif文件配置ROM;   4.验证FPGA中mega_lpm_ROM的功能。 二.实验原理   ALTERA的FPGA中有许多可调用的LPM (Library Parameterized Modu

Polaris的博客 1万+

comsol如何实现五厚度的单元模拟?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 471

Unity打包优化:LZ4压缩与Managed Stripping的陷阱与解决方案

在游戏开发中,资源压缩与代码优化是提升性能、减小包体的关键技术。LZ4作为一种高速无损压缩算法,通过字典替换原理实现快速解压,广泛应用于实时资源加载场景。代码剥离(Code Stripping)则通过静态分析移除未使用的托管代码,有效优化包体大小。然而,这些优化技术在实际工程中可能引发兼容性问题:LZ4压缩可能导致自定义资源管线加载失败,而激进的代码剥离会误删反射、序列化等动态调用的代码,引发运行时异常。本文聚焦Unity开发中的LZ4压缩与Managed Stripping两大核心优化选项,深入解析其工作

weixin_33827590的博客 298

使用FPGA实现MIPI DSI接口

通过使用FPGA,我们可以实现MIPI DSI接口,并在FPGA上生成相应的时序和电平转换电路。通过使用FPGA,我们可以实现MIPI DSI接口,并在FPGA上生成相应的时序和电平转换电路。在本文中,我们将探讨如何使用FPGA实现MIPI DSI接口,并提供相应的源代码。根据不同的发送状态,我们设置相应的输出信号。请注意,这只是一个基本的示例,用于说明如何使用FPGA实现MIPI DSI接口的发送功能。请注意,这只是一个基本的示例,用于说明如何使用FPGA实现MIPI DSI接口的发送功能。

ZdqDeveloper的博客 1705

Unity AssetBundle异步加载三段式优化指南

AssetBundle是Unity资源管理的核心机制,其加载过程涉及磁盘IO、内存解压与资源实例化三个关键阶段。理解这‘三段式’生命周期,是实现真正异步、避免主线程阻塞的前提。LZ4压缩相比LZMA显著降低解压耗时与内存峰值,而LoadAssetAsync完成并不等于资源可用——Instantiate才是CPU密集型瓶颈。结合分帧调度、依赖预热与对象池技术,可将单次加载的主线程占用从数百毫秒压至10ms内,切实提升游戏流畅度。本文聚焦AssetBundle异步加载与Unity资源优化实战路径,覆盖中大型项目

weixin_33688840的博客 596

【2025年美团春招(算法岗)-3月15日-第三题(300分)- 字符串权值】(题目+思路+Java&C++&Python解析+在线测试)

小美定义一个字符串的权值为:其长度为3的回文子序列数量。例如,“abca"的权值为2,因为包含两个回文子序列"aba"和"aca现在给定一个仅包含小写字母的字符串,小美希望你输出该字符串每个前缀的权值。

m0_73659489的博客 312

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

上一篇: C# 通过Costura.Fody把DLL合并到exe程序中
下一篇: WPF程序给按钮增加不同状态的图片
Thinbug
博客等级 码龄22年 2万+粉丝 187原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thinbug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值