浅谈资源加载 -AssetBundleSystem

Unity5-ABSystem(四):AssetBundle依赖 其实前面几章已经介绍完毕了AssetBunlde功能。但AssetBundle稍不注意,就会留下难忘的踩坑回忆。所以先推荐AssetBundleExtractor这个工具,能够查看AssetBundle内到底有哪些资源,让不良资源无所遁形。效果如图: 阅读详情

AssetBundleSystem

Ps:稍微抽点时间写一下这个,这个小项目完成度80%左右,在年初2月份的时候就完成的差不多了,因为各种原因处于半搁浅的阶段,现在官方出了Addressable Assets System ,遂和大伙谈谈这个资源加载。

真的是懒到极致了。

起个头:

项目中代码只是占了体积的一小部分,资源是项目中体积的大头,同时也时刻影响着加载和内存。所以合理的使用和管理资源成为了一个项目中比较重要的部分,在此重要分为两个部分 Editor 和代码部分。

代码部分:

众所周知,Unity5之后除了Assetbundle,这个看似方便的东西,实际上如果不对它进行一个合理的管控,对于包体和内存都是一个不好的发展。它会通过相同的assetbundlename将所有引用的(未打成ab)资源的都打到一个ab包中,冗余就变得不可避免;但是如果做到0冗余,则又会增加IO的开销(小文件太多)。所以就得由代码或者工具进行一些合适的管控。(以assetbundle为例子)

加载部分:

初步设想需求就是这样:

需要梳理清楚这个资源是否有对其他资源的依赖,否则可能导致加载出来的对象关键数据丢失或者整个加载失败。良好的事件通知机制:当加载失败或者加载成功的能及时正确的通知到调用方。良好的异常/失败处理机制:当一个对象加载过程中其中某个步骤失败了,那么之前可能会有先一步加载的资源(比如依赖资源)可能会无法正确的释放,导致泄漏。良好的日志信息:方便开发者准确的把握流程和加载过程中的情况,方便维护相关内容。同时根据功能分多个system。

说到运行时的加载的资源会有2种:Resources的资源,通过Resources.Load<T>(xxxx)的方式进行同步加载。AssetBundle的资源,通过AssetBundle.LoadFromFile /LoadFromMemory等同步和Async系列的异步接口进行加载。Resouces下的资源Unity自动维护引用关系,直接Load足以。而对于细分依赖关系的Assetbundle资源,则需要自行维护资源加载。

1.通过AssetDatabase.GetAssetBundleDependencies 或EditorUtility.CollectDependencies来进行资源依赖的收集。 2.加载过程,在异步情况下如果有正在进行的同目标Task,则把委托事件同等的传递给Task方,先行加载依赖(如果内存中已经存在相关的资源则不需要加载),并记录资源引用。 3.当依赖加载完成时进行目标资源的加载,并记录引用,当真正的主体资源被成功加载的时候则对其依赖进行引用计数的维护(这样即便在加载流程中发生异常也能保证依赖引用计数的正确性,如果提前在依赖加载阶段进行计数,则可能会导致在异常发生的时候的泄漏问题出现)。 4.事件通知,完成或者失败通知到调用方,如果是Prefab因为在unity需要真正使用需要Instaniate所以在Instaniate层使用WeakReference或者挂接AliveTrakcer(随便取名的监听生命周期的脚本函数)来维护实例引用。如果是其他比如Font,Text,Texture资源,则在调用方进行SelfReference等非实例化对象的记录。

举例:摘出一段代码:

判断任务类型(任务尽量单一,不要涉及太多,不容易维护,所以这里基本就是一个task对一个资源),然后进行加载,先加载依赖,当依赖完成则进行目标资源的加载

if (task.IsLoad())
{
    LoadDependency(ref context, ref task, ref result);

    LoadSubTask(ref context, ref task, ref result);

    int finishcnt;
    int totalcnt;
    if (task.IsSubAllDone(ref context, out finishcnt, out totalcnt) )//
    {

        GameAssetBundle gameAssetBundle;
        if (context.Cache.GetAssetBundle(task.AssetBundleName, out gameAssetBundle))
        {
            if (task.Result.ProgresCallback != null)
            {
ProgressArgs progressArgs = new ProgressArgs((float)finishcnt / (totalcnt + 1), 0, task.AssetPath, false);
task.Result.ProgresCallback(ref progressArgs);
            }

            Load(ref context, ref task, ref gameAssetBundle, ref result, true);
            context.Cache.UpdateAssetBundle(task.AssetBundleName, ref gameAssetBundle);
        }
        else
        {
            Debug.LogErrorFormat("not found gameassetbundle :{0}", task.AssetBundleName);
            AddException(ref context, task.AssetPath);
        }

    }
    else
    {
        if (task.Result.ProgresCallback != null)
        {
            ProgressArgs progressArgs = new ProgressArgs((float)finishcnt / (totalcnt + 1), 0, task.AssetPath, false);
            task.Result.ProgresCallback(ref progressArgs);
        }
    }
}

gameobject因为会涉及到实例化,所以需要维护实例化的引用, 像普通的asset资源或者场景资源,则通过依赖引用和自引用的方式进行引用维护,最后根据不同的策略进行管理。

内存管理:

当一些资源已经使用完毕或者完全看不见的时候,会需要即时的对资源进行一个卸载操作,或者要加载一些资源则可以直接使用缓存中的资源。常规一般就是通过已经加载对象的引用计数和卸载策略(比如卸载周期,对未来即将到来的加载调用做一个等待周期结束再实际卸载的操作)来判断资源是否需要卸载,卸载策略主要看你关注的重心是什么,如果你的重心是内存,则即时快速的卸载或者对内存阀值的控制是好的方案;如果你关心的重心是帧率,则异步的加载和较长时间的资源内存驻留是个合适的方案。一些老资源则可以直接使用缓存中的资源。对于assetbundle,通过AssetBundle.UnLoad(true/false)进行卸载,true需要把加载出来的Assets也进行一个统一的卸载,因为true会完整的卸全部资源,false则单纯的卸载Assetbundle资源,通过之前维护的引用计数进行合理的管理。这里默认采用unload true,因为对全部的引用都做了管理,清理的更干净,可以用这种,不放心,可以unload false。

策略制定方面:

基本就是采用上面说的:简单/内存/fps

举例:摘出一段代码:

public enum UnLoadStrategy
{
    Default,
    Memory,
    FramesPerSecond,
}


public void Run(ref AssetBundleContext context, AssetEvent eEvent)
{
    bool force = eEvent == AssetEvent.Destroy;

    bool inLoading = context.Tasks == null ? false : context.Tasks.Count > 0;
    if (!inLoading || force)
    {
        var result = Record(ref context, ref force, context.Cache.GetAllAssetBundle());

        if (result != null && result.Count > 0)
        {
                    UnLoad(result, ref context);
        }
    }
}

极懒模式之编辑器部分:

基本制作了几个简单的部分:

Asset:修改assetbundlename(拖拽 / ×(设置空名字)),罗列信息,罗列冗余打包的资源,正/反向查资源引用。

Profiler:简单罗列task和ab的情况

Build:显示了参数选项和含义,记得打依赖资源(dep)!

Sprite:极简(各种sort,set偷懒了,233),主要就是用于观察图集和引用。

很晚了,有空再补充。晚安!!下一章预计(有空可以交流一波,下一个模块基本形式已经完成,持续优化中):

资源地址:AssetBundleSystem(有空则维护一波,不过等官方那个出来后,可能就不用这个了。)

Unity3d AssetBundle依赖关系获取 PS:本文将从“打包之前”和“打包之后”两个方面去说明如何获取依赖关系 获取AB包依赖的作用 众所周知,如果一个AB包(我们称之为C)里面的资源引用到的其他资源(我们成为R)并没有被打包成AB包,那么C里面就会多出一份资源R的备份,如果只是一个C里面多了一个R的备份那还好,但是如果有很多其他AB包Cx都备份了一个R,那么这就是资源的冗余,没有必要,这也就提示了我们应该把R打包成AB包(我们称为D),那么这些Cx就只会多出一个依赖于D包的依赖,不会多出那么多资源。 而AB包在加载还原的时候,如果依赖了其他AB 阅读详情

相关推荐

GitLab教程(四):分支(branch)和合并(merge)

命令进行合并时,Git具备一定的智能自动化处理能力:如果一个分支仅修改了文件A,而另一个分支独立地修改了文件B,Git能够无缝整合这些更改,自动完成合并过程——即最终的代码既包含了对A文件的修改也包含了对B文件的修改。同样地,若两个分支虽然都修改了同一个文件,但涉及的是文件中互不重叠的部分,比如一个改动发生在第一行,另一个则在第二行,Git同样能巧妙地自动合并这些非冲突性修改。获取了远程分支的最新变化,或者当你想要合并本地的一个分支到当前分支时,就会用到这个命令。,默认会尝试合并远程分支到当前分支。

TracyCoder的博客 7887

Unity AssetBundle资源管理模块:从原理到工程实践

在游戏开发中,资源管理是核心挑战之一,尤其当项目体量增长时,如何高效加载、更新和管理资源直接影响开发效率和用户体验。AssetBundle(AB包)作为Unity官方的资源打包方案,其核心原理在于将资源(如预制体、纹理、音频)打包成独立文件,实现运行时按需加载与卸载。这项技术的关键价值在于支持资源热更新、减小初始包体以及实现精细的内存控制,广泛应用于移动端游戏、大型应用等需要动态更新内容的场景。然而,直接使用Unity原生API会面临依赖管理、内存泄漏和异步加载等工程难题。本文聚焦于构建一个健壮的AB包管理

weixin_30480075的博客 376

EGO_Planner代码学习(三):px4ctrl代码流程

上节阅读了EGO_Planner的轨迹服务器部分的代码,其实质是将规划器生成的轨迹进行离散化,间隔10ms计算当前时刻在轨迹上的位置,并发送到话题上。这两天抽空看了下控制器部分的代码,在l这个软件包里,它的功能是进行px4的模式识别和上层控制,通过线性控制器把发布过来的位置命令解算成飞控的控制量,通过mavros发送给px4。下面就详细看一下它的启动过程。

qq_41069236的博客 6805

AssetDatabase.GetAssetBundleDependencies

AssetDatabase.GetAssetBundleDependencies https://docs.unity3d.com/ScriptReference/AssetDatabase.GetAssetBundleDependencies.html public static string[] GetAssetBundleDependencies(string assetBundleNa...

kuangben2000的博客 651

(2024,DDPM,DDIM,流匹配,SDE,ODE)扩散:基础教程

本文的目标是尽可能简单地教授扩散。第一节介绍扩散的基本原理。第二节和第三节展示如何构建随机和确定性扩散采样器。第四部分介绍了密切相关的流匹配,可看作是扩散的推广。​第五节,强调实践中最重要的一些设计选择,包括采样器、噪声时间表和参数化方法。

qq_44681809的博客 1万+

【AI智能体】AI 编程 + 飞书CLI + Skills 重塑开发新范式实战操作详解

AI 编程 + 飞书CLI + Skills 重塑开发新范式实战操作详解

congge 3667

Unity中AssetDatabase相关的笔记(坑)

如果在编辑器模式下,需要加载资源,除了使用assetbundle外,更方便的是使用Resource.Load和AssetDatabase这个类。相比较而言,AssetDatabase类在编辑器模式下,更易操作。当然,这个类不仅仅只是用于资源的加载。 本篇列举了一些关于AeestDatabase类的一些用法和坑(长期更新) 1、资源加载 使用A...

Tong1993222的博客 3097

Android-Zygote进程的诞生—从init到Zygote启动

Android Zygote进程启动流程解析 Android系统的Zygote进程是所有应用进程的父进程,由init进程创建。启动流程分为: 内核阶段:加载init进程(PID=1) init进程阶段: 挂载基础文件系统(tmpfs、proc等) 设置SELinux安全策略 解析init.rc配置文件 Zygote启动:init进程通过app_process启动Zygote,预加载系统资源 SystemServer:Zygote fork出系统服务进程 关键点: init是用户空间第一个进程......

保持专注,保持热爱 641

AssetBundle Dependencies

如果一个或多个unityEngin.Objects包含对位于另一个bundle中的unityEngin.Object的引用,则资产绑定包可能会依赖于其他资产绑定包。如果unityEngin.object包含对任何资产绑定包中不包含的unity.Engineering对象的引用,则不存在依赖关系。在这种情况下,当您构建资产绑定包时,该包所依赖的对象的副本被复制到包中。如果多个包中的多个对象包含对未分...

林涵宇的博客 791

CMOS Sensor的调试经验分享

我这里要介绍的就是CMOS摄像头的一些调试经验。 首先,要认识CMOS摄像头的结构。我们通常拿到的是集成封装好的模组,一般由三个部分组成:镜头、感应器和图像信号处理器构成。一般情况下,集成好的模组我们只看到外面的镜头、接口和封装壳,这种一般是固定焦距的。有些厂商只提供芯片,需要自己安装镜头,镜头要选择合适大小的镜头,如果没有夜视要求的话,最好选择带有红外滤光的镜头,因为一般的sensor都...

camerall 3764

块存储:AIO的直接写流程注释

提交io流程中aio_write之前函数的注释,可参考“块存储:AIO的直接读流程注释”。

yiyeguzhou100的专栏 1335

The Asset used by component in XXX scene “XXX.fire“ is missing. Detailed information:

刚才使用Cocos Creator出现的问题,已解决。 The Asset used by component in XXX scene “XXX.fire” is missing. 丢失了XXX.fire文件,但看了下原路径,XXX.fire文件是存在的。 最后发现更改图片的type属性时,之前在属性检查器绑定的spriteframe会变为null,在拖动绑定一次就行了。 ...

qq_50121370的博客 2100

uniapp [全端兼容] - 实现全景图Vr 720°全景效果查看预览功能,3D全景图流畅不卡顿渲染+手势拖拽+悬浮工具按钮,uniAPP实现vr看720度全景效果示例代码(H5小程序APP全兼容)

uniapp显示720度全景图,720°全景图显示,在h5中展示720°全景图,浏览全景图,基于uniApp实现vr全景预览,加载全景图,uni-app全景预览插件,UNI-APP实现3D全景图,实现720°全景图展示,uniapp全景视频播放,uniapp项目实现vr720度全景图片预览,在网页上展示760全景图片和视频,全景图场景切换,UNIAPP全景VR图,uniapp加载720全景图_uniapp怎么加载vr图片,uniapp实现vr全景看房,uni-app实现全景效果,加载很慢卡怎么办,实现全景预

🏆 前端领域优质创作者 1万+

cocos creatro工程提交到svn遇到的问题

今天我把creator工程提交到svn上面然后同事下载之后页面显示不正常,像这样: 然后在console控制台显示一些黄色的警告: The Asset used by component “cc.Sprite” in scene “XXXX.fire” is missing. Detailed information:是所有的场景都这样显示的有问题,然后关联的所有脚本都编译失败。但是自己上传

a641832648的博客 4516

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

AssetBundle资源包------2

AssetBundle的具体开发流程。(1)(2)(3)(4)(5)5个流程。这篇文章为第(1)个流程。 1、创建一个Cube,然后创建一个Prefab预制件,将预制件命名为cubeasset ;然后将刚刚创建好的Cube拖曳到        cubeasset上面。点击刚刚创建好的cubeasset,在编辑器界面右下角资源属性窗口底部有一个名为AssetBundle       创建

YuJie1996 422

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

ET框架学习——ResourceComponent资源管理组件

ABInfo类              ResourceComponent组件涉及到几个类——ABInfo(AB资源信息?)和AssetBundleHelper这两个类。ABInfo继承自Component,维护三个字段,一个int类型的refCount属性,(应该是用于依赖计数的?),一个string的Name属性, 一个AssetBundle资源字段。构造函数接受一个名字和ab包资源...

Tong1993222的博客 1660

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

AssetsBundle学习(看一遍不懂不要紧,赶紧收藏!!!)

Unity的AssetsBundle基础学习简介1. 定义与用途2. 准备条件3. 导出方式4.导出包准备方法4.1 按不同类型资源导出到对应类型数据包4.2 全部类型资源导出到同一个数据包5.检查导出包完整性5.1 MD5格式打包方法6.检查文件完整性7.导入包的方法 简介 本篇文章,已经涉及到可以直接使用AssetsBundle的情况,并且是专门为学习AssetsBundle而写,如果觉得看一遍记不住的话,建议自己练习尝试,加深理解,学习无价,如果错过,你将错过“一个亿” 1. 定义与用途 什么是Ass

qq_46005796的博客 4863

unity AssetBundle打包

[MenuItem(&amp;quot;Assets/buildassbundle&amp;quot;)] static void buidassetbundle() { string die = &amp;quot;assetbundles&amp;quot;; if (Directory.Exists(die)==false) { Directory.CreateDirectory(die); } B

weixin_33950757的博客 524

Unity5新的AssetBundle系统使用心得

Unity的AssetBundle系统是对资源管理的一个扩展,动态更新,网页游戏,资源下载都是基于AssetBundle系统的。但是不得不说,这个系统非常恶心,坑很深。至于有多深,请看这篇文章: http://www.cnblogs.com/ybgame/p/3973177.html         原先的AssetBundle系统需要自己写一大坨导出的代码(BuildPipeline),这个新

langresser的专栏 2万+

Unity 打包与加载AssetBundle(加载对应的依赖)

要加载一个资源A,必须先去加载它的所有依赖资源。 要知道这个资源A依赖了哪些资源,必须先去加载AssetBundleManifest。 通过AssetBundleManifest对象的GetAllDependencies(A)方法,获取它依赖的所有资源。 依赖资源都加载了,就可以去真正加载资源A了。 注意点: 1.资源A加载完了后,要记得Unload(false),资源A的依赖资源要在 资源A加载...

linxinfa的专栏 1万+

AssetBundle学习笔记(一)

一、什么是AssetBundle?         1.它存在于硬盘上的文件。可称之为压缩包。该压缩包里面有多个文件,这些文件可分为两类:serialized file和resources file(即序列化文件和源文件)。(1)serialized file:资源被打散放在一个对象中,最后统一被写进一个单独的文件(只有一个)(如:模型资源,prefab资源等)(2)resources file:某

午夜支枕听河流 7627

页面如何加载资源及加载资源的过程

页面加载资源的形式有:1. 输入url(或跳转页面)加载html2.url: www.baidu.com3.加载html中的静态资源4.script标签中资源的加载加载一个资源的过程:1. 浏览器根据DNS服务器得到域名的IP地址2. 向这个IP的机器发送http请求3.服务器收到、处理并返回http请求4.浏览器得到返回内容浏览器渲染页面的过程:1.根据HTML结构生成DOM Tree2.根据C...

weixin_37861326的博客 2809

资源篇 资源加载

1 原因 2 目的 3 实现 实现原理 将加载过程状态化,Update中每帧检测状态。 Bundle的加载状态分为:等待加载、依赖加载、自身加载、加载回调、取消加载; Asset的加载状态分为:等待加载、依赖加载,自身加载、加载回调、取消加载; 看过一些加载的方案,最后还是觉得使用状态的形式是一种好的形式,扩展起来很方便。下面看一下状态的具体含义: 等待加载状态:目的是控制当前帧的加载上限,...

qq_15507535的博客 422

资源加载过程

无论是地址栏输入,还有代码里加载的,都会有一个URL,所以加载资源的第一步是 : URL解析——(提取出URL包含的信息,比如域名) DNS查询——(根据解析出的域名,到DNS服务器上查找该域名对应的IP) 请求资源——(带有所有的请求信息,到这个IP地址上去请求资源,然后再从服务器上把请求的资源下载下来) 浏览器解析——(浏览器拿到这些资源以后,根据不同的类型,做不同方式的解析) 上边4...

仗剑天涯,从摘要开始 287
上一篇: Unity-EmojiUI更新
KubilityDef
博客等级 码龄9年 27粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值