https://learn.unity.com/tutorial/assets-resources-and-assetbundles#5c7f8528edbc2a002053b5a7 Unity官方的资产管理教程
资产管理目标:
- 加载时间短
- 内存占用低
- 更小的包体大小
- 方便更新内容
Unity定位Object的方式:
Editor -> File GUID + Local ID File GUID是存在.meta文件里的,所以如果.meta文件没能正确更新,所有对于这个Asset内Object的引用都会丢失。
.meta = File GUID + Import Settings
Runtime -> Instance ID
- 通过Instance ID,可以快速在内存中找到加载的Object,如果没有加载,则使用File GUID和Local ID来将Object加载到内存中。
- Instance ID Cache在初始化时,会加载所有built scene中依赖的Objects,以及Resources文件夹下所有的Objects,这也就是为什么不要用Resources API的原因
- Instance ID entries在运行时从AssetBundle中导入新资产时增加
- Instance ID entries在运行时从AssetBundle卸载资产时被移除
资产的import包含一些耗时操作,比如纹理压缩。所以被导入的资产会缓存在Library中,避免每次都需要重新导入。这也就是为什么,一个Unity工程在只有Assets文件夹的情况下,仍然可以包含所有项目信息,但是打开时会加载比较久。
一个常见的,资源从内存中被移除,但后续需要快速重新载入的例子: 手机游戏App被切换到后台,此时OS将所有图像资源从GPU显存中移出;后续App切换到前台时,Unity必须重新加载所有图像资源到GPU
从磁盘读取大型预制体会导致性能问题,消耗的CPU时间与GameObject和Component数量成正比,也会受到目标平台的存储介质的IO速度影响。
在项目编译时,Resources文件夹中的所有资产会被序列化到同一个文件中,这个文件包含metadata和索引信息。在大多数平台上,这个索引的查找数据结构是平衡搜索树,构造时间复杂度为O(nlog(n)),随着Resouces文件夹中的资产增加,它的复杂度会超线性增长。在低端手机上,Resources文件夹下如果有10000个资产,就要花费几秒钟来加载,即便是其中大部分资产在第一个Scene中并不需要出现。
AssetBundle定性: 一种Unity中的主要工具,用于在游戏安装后更新非代码内容 从而 减小基础包体大小,降低运行时内存压力,选择性地载入内容 主要服务于手机项目 手机和Console平台的没有虚拟内存,或非常受限,因此不能使用Resources或非常大的AssetBundle
AssetBundle文档 https://docs.unity3d.com/Manual/AssetBundlesIntro.html
AssetBundle = Header + Data Segment 压缩方式:LZMA;LZ4;Uncompressed
Addressable文档: https://docs.unity3d.com/cn/current/Manual/com.unity.addressables.html 用法示例: https://github.com/Unity-Technologies/Addressables-Sample
需求:运行时加载和卸载资源 游戏通常需要处理大量的资源(模型、纹理、音频),不可能在启动时一次性加载所有资源,而通过运行时卸载不再使用的资源,可以减少内存占用,降低卡顿。
Unity官方对Resources方案给出的最佳实践:不要用
- 难以进行内存管理
- 增加启动时间和包体大小
- 资产管理困难
- 难以针对特定平台交付特定内容
- 难以进行增量内容更新
AssetBundle方案的改进点
- 允许开发者将多个资源打包成一个文件
- 支持资源的版本控制和增量更新
- AssetBundle可以包含任意类型资源,并在不同AssetBundle之间建立依赖
- 后台异步加载资源
Addressable方案的改进点
- 自动处理资源打包和加载
- 自动管理资源依赖
- 开发者使用标签和地址来组织和定位资源
- Addressable构建在AssetBundle的上层,提供更高效和灵活的资源管理方案