首页 > 其他分享 >AB包

AB包

时间:2023-12-27 20:13:36浏览次数:23  
标签:包中 AB AssetBundle 内存 资源 加载

1.AB包内部结构

AB包简单说就是一串二进制数据,这串数据存的是资源(预制、材质、贴图、模型等)。这串数据分为:

1.头文件

AssetbundleFileHeader

记录这个AB的信息:版本号、压缩格式等信息。

AssetFileHeader

记录AB的文件信息(一个文件列表、记录了每个资源的name、offset、length等信息,后面读取具体资源的使用用)

2.具体的资源

头文件后面跟着的是n段数据,一段数据就是一个资源(也有一些信息、其中比较重要的就是资源类型id(0:Object、1:GameObject等)、对外部资源的引用情况)。

2..mainfest文件

。。。

3.AB变体

简单说就是一个资源的分类标签,如同一个图片的高清和低清资源。

4.压缩格式

LZMA和LZ4

LZMA需要完整解压之后才能加载包内资源(但是压缩出来的包体小),LZ4不需要完整解压就可以加载包内资源(数据被分为大小相同的块,并被分别压缩,加载时只加载Header,用哪块的数据就解压对应的块就可以,内存占用小)。

默认使用LZMA压缩方式,因为第一次解压之后,该包又会使用LZ4再次压缩。(这就是为什么第一次加载时间长,后面就没这么长了)

5.获取AB包

AssetBundle.LoadFromFile(string path)
AssetBundle.LoadFromFileAsync(string path)

最常用的方法,从文件中加载AB包,它从一个给定的路径来加载AB包。如果AB包是LZ4加载方式,它只会加载AB包的Header,之后需要什么资源再加载那部分的AB包chunk。极大的减少了内存占用。

AssetBundle.LoadFromStream(Stream stream)
AssetBundle.LoadFromStreamAsync(Stream stream)

不咋用,从流中加载AB包,它从一个Stream中加载AB包。跟LoadFromFile一样,如果AB包是LZ4加载方式,它也是只会加载AB包的Header。(LoadFromStreamAsync是它的异步版本)

AssetBundle.LoadFromMemory(byte[] binary)
AssetBundle.LoadFromMemoryAsync(byte[] binary)

一般是网络接口用,LoadFromMemory是从内存中加载AB包,它从内存中的byte[]中加载AB包。它会完整的把AB包加载出来,适用于ab包已经被加载进内存的情况(参数是byte数组)。

6.内存占用

 现在的主流做法是在进游戏之前下载热更的包并存在本地,所以不会有WebStream这部分,当然,如果是运行时下载资源就还是要用到这个。

Assetbundle的内存占用:压缩的AB包 + 解压缩的AB包(也就是具体的资源,LZ4的不会全解,只解要用的部分)+ 实例化的资源。

三个ID

一份Asset对应一个meta文件,meta的id是GUID。

而localID是Asset内部的id,比如一个预制体有两个子节点,localID用来标记这两个子节点,Unity用它来记录资源内部的具体引用/层级关系

InstanceID是由这两个ID计算得到的全局唯一的

7.资源卸载

1.AssetBundle.Unload(false) : 卸载掉紫色部分(压缩的AB包)。会解除紫色部分和绿色部分的链接关系(Instance ID的GUID和Local ID引用变无效),再次加载一个紫色部分,原来的绿色部分不会受新加载的紫色部分的管理。因此如果不注意的话可能会导致一些不可控的问题,Unity中有Resources.UnloadUnusedAssets()方法可以很好地解决这个问题。

2.AssetBundle.Unload(true) : 卸载掉紫色部分(压缩的AB包)以及绿色部分(具体的Asset),注意这个举动可能会引发最上面的区域(实例化区)引用的资源丢失

3.Resources.UnloadUnusedAssets : 卸载掉没有引用的绿色部分(压缩的AB包)。

8.依赖问题

依赖问题,通俗的话来说就是A包中某资源用了B包中的某资源。然而如果A包加载了,B包没有加载,这就会导致A包中的资源出现丢资源的现象。

所以要尽量避免加载A包之前还要加载B包的问题。

在Unity5.0后,BuildAssetBundleOptions.CollectDependencies永久开启,即Unity会自动检测物体引用的资源并且一并打包,防止资源丢失遗漏的问题出现,但会导致资源冗余(同一份资源被打进不同的包中)。

最好就是将一些公共资源单独打到一个ab包中,并提前加载完成,尽可能减少AB包的依赖。

todo Tools.AnarysicsResources

9.细粒度问题

细粒度问题即每个AB包分别放入多少资源的问题,一个好的策略至关重要。
加载资源时,先要加载AB包,再加载资源。如果AB包使用了LZMA或LZ4压缩算法,还需要先给AB包解压。
AB包数量较多,包内资源较少
AB包数量较少,包内资源较多
加载一个AB包到内存的时间短,玩家不会有卡顿感,但每个资源实际上加载时间变长。
加载一个AB包到内存的时间较长,玩家会有卡顿感,但之后包内的每个资源加载很快。
热更新灵活,要更新下载的包体较小。
热更新不灵活,要更新下载的包体较大。
IO次数过多,增大了硬件设备耗能和发热压力。
IO次数不多,硬件压力小。

策略:

1.建一个DaBao文件夹(里面存的是需要打热更包的文件),以文件夹为单位去打包(如果有的包体过大(超过100m),可以分开打)。

2.经常更新和不经常更新的对象拆分到不同的AB包中。

3.同时加载的对象放在一个AB包中。

4.不可能同时加载的对象拆分到不同的AB包中。

5.公共资源和非公共资源拆分到不同的AB包中。

6.根据项目逻辑功能来分组打AB包。

7.公共资源和非公共资源拆分到不同的AB包中。

8.依赖文件根据上面说的就行

10.资源校验

验证本地文件的hashcodeunity的hashcode(这两个code是固定的,不会随着设备的不同而变化)

散列算法就是一种以较短的信息来保证文件唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。

也就是说这两个code变了,这个文件也就变了(损坏了)。

标签:包中,AB,AssetBundle,内存,资源,加载
From: https://www.cnblogs.com/mcyushao/p/17931032.html

相关文章

  • 【C语言数据结构】对Lua Table源码的一次劣质学习
    /*new_key*/KLcBoolKLcmCreateMapKeyValue(KLCMAP_PTRpTag,KLCTVALUE_PTRpKv){ KLcBoolkbRet =KL_FALSE; KLcBoolkbIsKvLegal =KL_FALSE; DWORDdwInsertPos =0; DWORDdwFreePos =0; DWORDdwCollisionPos =0; KLCTVALUE_PTRptMainNo......
  • swagger报错Unable to render this definition
    问题描述:访问swagger时,报错endofthestreamoradocumentseparatorisexpected,UnabletorenderthisdefinitionTheprovideddefinitiondoesnotspecifyavalidversionfield.PleaseindicateavalidSwaggerorOpenAPIversionfield.Supportedversionfields......
  • C#中 abstract class和interface有什么区别?
    abstractclassabstract声明抽象类抽象方法,一个类中有抽象方法,那么这个类就是抽象类了。所谓的抽象方法,就是不含主体(不提供实现方法),必须由继承者重写。因此,抽象类不可实例化,只能通过继承被子类重写。interface声明接口,只提供一些方法规约,在C#8之前的版本中不提供任何实现,在C#......
  • C++ Qt开发:TableView与TreeView组件联动
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TableView与TreeView组件联动的常用方法及灵活运用。本章我们继续实现表格的联动效果,当读者点击T......
  • 深度学习:Stable Diffusion API 快速上手教程
    StableDiffusion是一个先进的深度学习模型,用于创造和修改图像。这个模型能够基于文本描述来生成图像,让机器理解和实现用户的创意。使用这项技术的关键在于掌握其API,通过编程来操控图像生成的过程。在探索StableDiffusionAPI的世界前,需要把握以下基本概念:API(应用程序编程接口......
  • hackthebox absolute insane
     信息收集Payattentiontothelastlinessl-date:wehave7hourclockskew,whichshouldkeepinmindifdoinganykeberosauth.SMB-TCP445smbclient-N-L//10.10.11.181#对面拒绝连接crackmapexecsmbabsolute.htb  #对面存在smbcrackmapexec......
  • Zabbix 监控Dell EMC Unity 480
    Zabbix监控DellEMCUnity4801、使用EMCUnityREST-APIv3,参考https://www.zabbix.com/integrations/emc?linkId=165523208https://github.com/aklyuk/zabbix-emc-unity 2、Zabbix注意事项 unity_get_state.py放入zabbix安装目录的externalscripts文件内,并赋予执行......
  • AbstractQueuedSynchronizer源码阅读
    AbstractQueuedSynchronizer源码阅读目录AbstractQueuedSynchronizer源码阅读例子Overview-CLH锁Overview的剩余内容代码分析cleanQueueacquireacquire总结acquire共享模式补充release内部类ConditionObject参考链接本人的源码阅读主要聚焦于类的使用场景,一般只在java层面进行分......
  • 解决前端vue2报错 Error: Can't resolve cache-loader和Error: Can't resolve babel-l
    总得说来报这种Error:Can'tresolve+模块名字的错误,一般就只有两种原因:一、少了这个包(直接安装:pnpmadd-D模块名字@版本),二、有这个包,但是版本在package.json中不正确。需要和你的vue/cli-service的版本对应上,该降级的时候降级,降级一般先删除再安装新的pnpmremovecss-loaderpn......
  • Linux Debian12使用podman安装upload-labs靶场环境
    一、upload-labs简介PHP语言编写,持续收集渗透测试和CTF中针对文件上传漏洞的靶场,总共21关,每一关都包含着不同的上传绕过方式。二、安装podman环境LinuxDebian系统如果没有安装podman容器环境,可以参考这篇文章先安装podman环境,LinuxDebian11使用国内源安装Podman环境三、pod......