[Unity笔记]热更Part1:关于AB包与热更

avatar
作者
猴君
阅读量:0
  • Resources不能热更,对资源的更新需要重新打包
  • AB可以热更,不需要对整个游戏重新打包,一般是对非代码资源的热更
  • HybridCLR或者LUA是对脚本的热更

AB包

【官方文档】概念理解
Unity Documentation - AssetBundle
Unity Documentation - 本机使用 AssetBundle
【基础知识】
CSDN - Unity中AB包详解(超详细,特性,打包,加载,管理器)
AssetBundle热更新完整工作流与知识点解析

不可以包含代码文件:AssetBundle是Unity中用于打包和分发资源的一种文件格式。它是一个包含特定平台非代码资源的存档文件,例如模型、纹理、预制件、音频剪辑,甚至整个场景

可能具有依赖关系:可以在一个AB包引用另一个AB包的东西,可以压缩(便于传输),内含序列化数据或者资源文件(纹理、音频、Prefab乃至场景等二进制数据块,加载他们是在Unity的另一个线程进行的)

用于动态加载:动态加载的资源打AB包,非动态加载的资源不用打。什么是动态加载?是指在游戏运行时根据需要从外部加载资源,而不是在游戏启动时将所有资源都加载到内存中。所以粗略划分来讲从loading到进入游戏到主界面这个流程以外的东西都可以动态加载。

压缩是可选的:默认是压缩的,但是可以不压缩。压缩减少网络占用(但是解压也耗时间和计算资源),不压缩就加载快(不用解压嘛)。默认压缩是LZMA,但是也支持LZ4。LZ4是块压缩,LZMA是字典压缩(基于Lempel-Ziv算法和马尔可夫链,把数据看做流)

AB文件构成

AssetBundle文件构成:

  • 清单(Manifest):清单文件包含了AssetBundle的元数据信息,如依赖关系、哈希值和变体数据。它的作用在于帮助管理AssetBundle之间的依赖关系,以及确保正确的资源加载和版本控制。
  • 包体(Bundle)本身组成:实际包含资源的文件,例如模型、纹理、预制件等。
  • 变体(Variant)配置文件:指定不同平台或设备上的资源变体,以便在不同环境下提供最佳的性能和用户体验。

AB的载入

载入:下载+加载

AB包的使用分两种情况,一是本地直接LoadFromFile,二是UnityWebRequestAssetBundle从指定URL下载,然后按照下面的方法读取其中资源使用:

// LoadAsset<T>(string)会把资源转换为T类型 // 例如下面函数从叫做bundl的AB包中加载名为"myObject"的资源 GameObject obj = bundle.LoadAsset<GameObject>("myObject"); 

AB卸载

AssetBundle的卸载使用.Unload(bool),需要注意的是传入的bool对应两种卸载策略

AssetBundle.Unload(true) 卸载从 AssetBundle 加载的所有游戏对象(及其依赖项)。这不包括复制的游戏对象(例如实例化的游戏对象),因为它们不再属于 AssetBundle。

如果应用程序必须使用 AssetBundle.Unload(false),则只能以两种方式卸载单个对象:

  • 在场景和代码中消除对不需要的对象的所有引用。完成此操作后,调用 Resources.UnloadUnusedAssets
  • 以非附加方式加载场景。这样会销毁当前场景中的所有对象并自动调用 Resources.UnloadUnusedAssets

Resources.UnloadUnusedAssets并不是专门针对 “Resources” 文件夹的内容,而是针对在内存中加载的所有资源。

其它

StreamingAssets与AB

官方文档:Unity Documentation - StreamingAssets

CSDN - 详解Unity中的StreamingAssets文件夹


Unity中的StreamingAssets文件夹通常用于存放需要在运行时动态加载的资源文件,事实上StreamingAssets文件夹和Resource文件夹在打包时都会原封不动地加入游戏包中。

StreamingAssets:流媒体资源,典型的例子是视频,不是一直用得到,也没必要一直放在内存中,需要时加载就行

Resources是压缩且加密的,StreamingAsset是原封不动的不作任何处理的。

特点:

  • 需要时加载
  • 可替换(替换文件名字和被替换的一样就行了)
  • 内容不会被压缩(Resource会压缩)
  • 不同平台路径不同
  • 适合放流式文件(二进制文件)

AB包打包时涉及到这个文件夹(一般会有Copy to StreamingAsset选项),这是显而易见的,把AB放在这里可以满足动态加载的需要

Resource和AB区别

Unity Blog - Asset Bundles vs. Resources: A Memory Showdown
Unity Learn - Assets, Resources and AssetBundles
Unity 资源加载的两种方式:Resources和AssetBundle最详细的解析

使用Resources.Load方法从Resource文件夹里加载。Resource会将Resource文件夹的所有资源打包到安装包中(相应地,包体增大)。但是运行游戏时,这个文件夹并不是全部加载的,而是按需通过Resources.Load加载,但是Resources.Load加载的资源会一直存在于内存中(可以手动卸载)

AssetBundle允许按需加载和动态加载资源,可以根据需要进行资源的加载和卸载,从而降低内存占用。

重复与忽略

  • 在 Unity 中,如果将资源打包到 AssetBundle(AB包)中,那么这些资源将会在构建时从项目中单独复制一份,而不是与项目中原始的资源文件共享。
  • Resources 目录下的资源在构建 AssetBundle 时会被忽略,而不会被包含在 AssetBundle 中。不要在Resources下存放直接打包进AB的东西,不过AB包的资源可以引用Resources的资源

AA与AB

CSDN - 【游戏开发探究】Unity Addressables资源管理方式用起来太爽了,资源打包、加载、热更变得如此轻松(Addressable Asset System | 简称AA)

AA底层也是AB(能够轻松逆向),但是中国版AA多了加密功能

热更流程

  1. 资源部署到原创服务器上
  2. 客户端检查更新:客户端启动时,首先向服务器发送请求,检查是否有新的AssetBundle版本可供更新。
  3. 下载更新:如果服务器上存在新版本的AssetBundle,客户端会下载这些更新的AssetBundle文件到本地存储,通常是将更新的 AssetBundle 文件下载到持久化数据路径中,然后再进行加载和应用。
  4. 更新本地清单:客户端会更新本地的AssetBundle清单文件,记录最新的AssetBundle版本信息和哈希值等元数据。
  5. 应用更新:客户端使用新的AssetBundle中的资源来更新游戏内容,例如替换旧的模型、纹理或其他资源。不过如果是在游戏进行中未必需要立即应用更新(如果不是立马需要的话,因为占IO)
  6. 重启或刷新:在完成更新后,客户端可能需要重启或者刷新游戏内容,以确保新的资源得到正确加载和应用。
    实际开发时还要提高容错性:考虑到网络异常、更新失败的处理、版本兼容性等问题,以确保热更新的流程稳定可靠。

补充:

  • 下载完热更包需要本地资源校对(计算MD5和清单中的比较)

关于下载部署完热更的选择:资源校对通过后不一定跳转到Launch场景,也可能是去重启游戏

关于判断是否需要热更

  • 版本号分为大版本号和热更新版本号,大版本号不同就不用比对清单了,直接热更

结合上述两节谈内存优化

针对内存占用较高的情况,可以采取以下优化措施:

  1. 使用AssetBundle进行资源管理: 将大部分资源打包成AssetBundle,并在运行时按需加载和卸载,以降低初始内存占用。
  2. 资源共享: 合理设计资源的共享机制,避免重复加载相同的资源,减小内存占用。
  3. 异步加载: 使用异步加载资源的方式,避免在主线程同步加载大量资源导致内存占用过高。
  4. 资源释放: 及时释放不再需要的资源,避免资源长时间占用内存。
  5. 动态加载: 对于大型场景或地图,可以采用动态加载的方式,根据玩家位置或需求动态加载和卸载场景资源,减小内存占用。
  6. 内存优化工具: 使用Unity内置的Memory Profiler等工具进行内存优化分析,找出内存占用较高的原因,并进行针对性的优化。

要指出的是资源压缩只是减少磁盘空间占用,而且还得额外耗费CPU资源解压,解压之后还和原先占用的内存是一样的

第五点说的动态加载得是AB包方式,因为如果是Resource方式,即便是动态加载,资源确实会一直存在内存中

CSDN - Unity文件操作路径

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!