【Unity】AssetBundle的加载与卸载方式摘要

    xiaoxiao2022-07-04  121

    AssetBundle的加载与卸载方式摘要

    文中Object和Asset两个词用的比较混乱,但是Unity的官方英文文档里就是不停地在用这两个词,所以这里也没有替换为中文。


    用于加载AssetBundle的API

    AssetBundle.LoadFromFile[Async]() 首选方法(在速度、磁盘使用和内存占用方面都很高效)适用于从本地存储加载未压缩或LZ4压缩的AssetBundle使用LZMA压缩的AssetBundle会被解压到内存中使用LZ4压缩或未压缩的AssetBundle会直接从磁盘读取 AssetBundle.LoadFromStream[Async]() 适用于从流式数据中加载AssetBundle使用LZMA压缩的AssetBundle会被解压到内存中使用LZ4压缩或未压缩的AssetBundle会直接从流数据中读取加载过程中不能Dispose流式对象 UnityWebRequest[AssetBundle].GetAssetBundle() 适用于从远程下载AssetBundle能够缓存已下载的AssetBundle以便重用缓存系统中的AssetBundle仅以文件名进行标识而不是使用URL AssetBundle.LoadFromMemory[Async]() 不推荐使用会产生AssetBundle的冗余副本

    方括号[]用来表示类或方法的其他版本,下同。


    用于从AssetBundle中加载Asset的API

    AssetBundle.LoadAsset[Async]() 首选方法适用于加载AssetBundle中的单个Object当要加载AssetBundle中超过66%的Object时,考虑使用LoadAllAssets()方法 AssetBundle.LoadAllAssets[Async]() 适用于一次性加载AssetBundle中的全部Object比多次调用LoadAsset()更快 AssetBundle.LoadAssetWithSubAssets[Async]() 适用于从AssetBundle中加载含有多个嵌套Object的复合Asset如果要加载的Object都来自于同一Asset并且他们和很多不相关的其他Object放在同一AssetBundle内,那么应该使用此方法

    当Object被加载完成后,会调用它的Awake()方法,并在下一帧对Unity引擎可用。


    用于查询AssetBundle依赖的API

    AssetBundleManifest.GetAllDependencies() 返回被AssetBundle所直接和间接依赖的所有AssetBundle的名称 AssetBundleManifest.GetDirectDependencies() 返回被AssetBundle所直接依赖的AssetBundle的名称

    加载AssetBundle时不能自动加载该AssetBundle所依赖的其他AssetBundle,但从AssetBundle中加载Asset时能够自动加载该Asset所依赖的其他Asset。

    AssetBundle和其所依赖的AssetBundle的加载顺序并不重要,只要在从其中加载Asset时保证被依赖的AssetBundle已经加载即可。


    用于卸载AssetBundle的API

    AssetBundle.Unload() 卸载此AssetBundle如果参数unloadAllLoadedObjects传入false 此AssetBundle中的Asset的压缩数据文件将被卸载无法再从此AssetBundle中加载任何Object已经从此AssetBundle中加载的Object仍能正常工作 如果参数unloadAllLoadedObjects传入true 首选方式所有从此AssetBundle中加载的Object都将被销毁Scene中对这些Object的引用将会丢失 AssetBundle.UnloadAllAssetBundles() 卸载当前已加载的所有AssetBundle参数作用与AssetBundle.Unload()方法的参数相同 Resources.UnloadUnusedAssets() 卸载所有未被使用的Asset

    Asset的清理会在特定时期触发,但也可以手动触发。

    当从AssetBundle中加载的Object被从活动的Scene中移除时,Unity不会自动将其卸载。

    卸载AssetBundle但不卸载从其中加载的Object将会破坏此AssetBundle与Object之间的链接关系。如果之后再次加载了此AssetBundle并加载同一Object,内存中就会产生新的Object副本,而不是使用未被卸载的那个Object。

    最好将那些需要同时加载或者更新的Object打包到同一个AssetBundle中。


    Asset分配策略

    AssetBundle太少 增加运行时内存占用增加加载时间需要下载的内容更大 AssetBundle太多 增加构建时间使开发更复杂增加整体下载时间 分组Object的基本策略 根据逻辑实体分组根据Object类型分组根据同时使用的内容分组 选择AssetBundle压缩方式时需要考虑的问题 加载时间:从本地加载未压缩的AssetBundle要比加载压缩过的AssetBundle快得多构建时间:LZMA和LZ4压缩文件的速度非常慢应用大小:如果AssetBundle被附带在项目中,将它们压缩可以减小应用程序的体积内存占用:如果考虑内存占用量,请使用不压缩或者以LZ4压缩的AssetBundle下载时间:如果AssetBundle很大或者用户网络带宽有限,那可能需要压缩如果AssetBundle中的主要内容是使用紧密压缩算法进行压缩的DXT压缩纹理,那么这个AssetBundle不应该再被压缩强烈建议开发者不要在WebGL项目中使用压缩的AssetBundle

    AssetBundle补丁更新

    使用AssetBundle进行补丁更新只需简单的使用新AssetBundle替换已有的AssetBundle即可。如果正在使用UnityWebRequest[AssetBundle]管理应用程序的AssetBundle缓存,那么传递一个不同的version参数即可触发下载新的AssetBundle。

    补丁系统需要维护两个信息列表:

    含有当前已下载的AssetBundle及其版本信息的列表含有服务器上的AssetBundle及其版本信息的列表

    补丁系统应该下载服务器上的AssetBundle的信息,然后与本地的AssetBundle信息进行比对,重新下载缺失的和版本信息发生变化的AssetBundle。

    最新回复(0)