unity 资源管理之AssetBundle

上一篇讲了unity 资源管理的总体结构链接,这里主要讲unity AssetBundle 相关的内存管理内部机制

AssetBundle 由header 和data segment两部分组成

header包含AssetBundle 一些相关信息 唯一标识、压缩类型、清单文件(identifier, compression type, and a manifest)
清单文件是个查找表 key是对象名称,每个条目对一个data segment 字节位置。在大部分平台这个查找表实现的是一个平衡搜索树,具体在pc平台,windows、ios 实现的是红黑树。
data segment 是序列化AssetBundle中资源的数据,根据压缩选择有些不同
LZMA:所有资源被压缩在一起
LZ4 :每一个资源被分别压缩
没压缩:原始的数据资源

note:5.3之前的unity版本 对象不能被单独压缩,当读取一个或者多少的时候会解压整个AssetBundle 为了提高效率unity会缓存解压后的AssetBundle

加载AssetBundle

提供了5个api来加载,每一个都是同步和异步方法,这些api的不同根据两个条件
1. 平台的不同
2. 压缩类型LZMA , LZ4 ,未压缩

这些api可以随意混合使用
它们是:
AssetBundle.LoadFromMemory(Async optional)
AssetBundle.LoadFromFile(Async optional)
AssetBundle.LoadFromStream(Async optional)
UnityWebRequest’s DownloadHandlerAssetBundle
WWW.LoadFromCacheOrDownload (版本5.6或者低于)

AssetBundle.LoadFromMemory(Async)

unity 官方是建议不要使用该api的,因为c# 加载之后会把他拷贝到一块新的连续的内存里面,如果压缩格式是LZMA 那个会拷贝加载解压之后的整个文件,如果是没有压缩的和LZ4 的则会拷贝当前的全部字节。这样会造成内存的峰值至少为AssetBundle的两倍,最后加载一个asset 还需要把该资源拷贝一次,拷贝到gup 或者系统内存里面

AssetBundle.LoadFromFile(Async)

该api 对于未压缩和LZ4 压缩的文件加载时很高效的因为调研该函数时仅仅夹AssetBundle 的header 只有当需要时才会从文件中加载Object 如InstanceID 被引用或者调用AssetBundle.Load()

对于LZMA 格式的AssetBundle 加载整个文件并保存解压的拷贝

在Unity Editor 会直接加载整个文件到内存中,和AssetBundle.LoadFromMemory 类似,真实测试需要在真机上面

UnityWebRequest’s DownloadHandlerAssetBundle

提供了一个下载储存assetBundle 的方法,是否储存和储存位置都配置,最简单的使用
UnityWebRequest.GetAssetBundle. 下载一个资源,如果assetBundle 是LZMA 格式的在下载过程中可以储存为LZ4 格式,根据设置Caching.CompressionEnabled.。下载完成之后可以直接获取到assetBundle 加载过程和AssetBundle.LoadFromFile类似
如果当前文件已经下载那么会直接读取文件,加载过程和AssetBundle.LoadFromFile类似

WWW.LoadFromCacheOrDownload

在2017.1之后改还是弃用了,请使用UnityWebRequest 相关方法

在之前版本中改行为类似UnityWebRequest ,每次调用改方法会创建一个线程来下载。多次调用需要注意

对于下次LoadFromCacheOrDownload 和UnityWebRequest 都需要Dispose 推荐是有using 语法

加载Asset 从AssetBundle中

有3个加载方法都在AssetBundle 对象上,他们是同步异步都存在的
LoadAsset (LoadAssetAsync)
LoadAllAssets (LoadAllAssetsAsync)
LoadAssetWithSubAssets (LoadAssetWithSubAssetsAsync)

同步:同步方法加载会快于异步方法,至少快一帧(异步是调用的下一帧开始的)
异步:会加载多个对象直到达到当前时间限制

LoadAllAssets :会加载该AssetBundle中的全部资源,只要需要该AssetBundle大部分比如超过66%的时候官方才推荐使用
LoadAssets:加载单个资源
LoadAssetWithSubAssets :加载资源及其子类资源:如fbx的模型资源及嵌入的animation或者相关纹理等

加载资源不是在主线程上面的,与线程不敏感的unity系统(scripting, graphics)会转换到工作线程上面,列如VBO从mesh上面创建,textures解压等
5.3之后的版本,是并行反序列化多个Object 的。这些处理和整合是在工作线程上面的,当物体加载完成后会调用Awake ,在下一帧Object会变得可用。
同步方法会暂停主线程直到加载完成

AssetBundle 依赖关系

追踪依赖关系有两种API方法,它们和具体的环境有关
Unity Editor:AssetDatabase
运行时:AssetBundleManifest

object 直接的引用是通过GUID 和 localID 的(具体内容查看上一篇),在运行时是instancID 。当加载AssetBundle时会给每一个Object分配一个instanceID,当instanceID被其他对象引用时会自动创建出来,AssetBundle 之间的加载顺序没有要求,只要被引用的(object所在的AssetBundle)是已经被加载就好。

AssetBundle manifests

使用BuildPipeline.BuildAssetBundles 打包时,unity会序列化AssetBundle的依赖关系到一个独立的文件中,类型是AssetBundleManifest
储存位置在打包文件夹下,以文件夹为名称如:打包路径(projectroot)/build/Client/ 那么这个文件的路径是(projectroot)/build/Client/Client.manifest

AssetBundleManifest 提供了操作该文件的一些方法:如
GetAllAssetBundles:获取所有AssetBundle 的名称
GetAllDependencies :获取给定AssetBundle 的所有依赖关系
GetDirectDependencies 获取直接子对象的依赖关系

卸载AssetBundle

使用AssetBundle.Unload(unloadAllLoadedObjects )api
当unloadAllLoadedObjects 为true 时会卸载所有资源包括在使用的
unloadAllLoadedObjects 为false 时没有被引用到的资源会被卸载,之后重新加载AssetBundle会生成新的instanceID,重新加载Object 会重新生成一份,这种情况会造成内存多占用了一份(一次这样的操作)
有些情况需要重新加载资源如unity失去对设备的控制权(如pc被锁定,app被切换到后台),gpu会清理掉当前内存,需要从新加载资源

如果使用了false 那么之后可以使用Resources.UnloadUnusedAssets.来卸载,当切换场景不是add模式时会自动调用该方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity是一款流行的跨平台游戏开发引擎,可以用于开发各种类型的游戏和应用程序。微信小程序是一种在微信平台上运行的轻量级应用程序,具有快速、高效和便捷的特点。在Unity中使用微信小程序的AssetBundle功能,可以实现更好的资源管理和加载效率。 AssetBundleUnity中一种打包资源的方式,可以将游戏中的各种资源(如模型、贴图、音频等)打包成一个独立的文件,通过异步加载的方式在运行时进行动态加载和卸载。在微信小程序中使用AssetBundle功能,可以将游戏所需的资源打包成一个bundle文件,然后在小程序启动时进行加载,避免了一次性加载所有资源导致的内存消耗和加载时间过长的问题。 使用AssetBundle可使微信小程序在运行时按需加载资源,提高了程序的运行效率和性能。同时,AssetBundle还可以通过版本管理和差异打包的方式,实现资源的增量更新,减少了资源更新的大小和下载时间。 Unity与微信小程序的AssetBundle功能的结合,可以使开发者在开发小程序时更加高效地管理和优化游戏资源。通过合理的资源打包和加载方式,可以减少游戏的大小和加载时间,提升游戏的用户体验。此外,通过AssetBundle功能,还可以实现动态更新游戏内容,增加游戏的可玩性和持续性。综上所述,Unity微信小程序AssetBundle是一个强大的工具,可以帮助开发者更好地开发和优化微信小程序的游戏应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值