核心知识点:热更新与冷更新概念、AB 包概念与作用、AB 包属性配置、编辑器打包工具、三种压缩算法、Manifest 清单文件、CRC/MD5/SHA1 校验码、分包策略、依赖关系、AB 包卸载、多种加载方式(同步 / 异步、文件 / 内存 / 流、Manifest 逆向加载、UnityWebRequest)
一、热更新与冷更新
1 概念
冷更新 :应用商店完整重新下载安装包,替换整个 App,Android 是 APK、iOS 是 IPA。 热更新:不需要重新安装完整安装包,游戏运行时增量下载资源(模型、贴图、预制体、场景),实现资源更新;C# 编译后的脚本无法直接通过 AB 包热更(IL2CPP 编译后为机器码)。
语言区分:C#/C++ 属于编译型语言;Lua、Python、JS 属于解释型脚本语言,可以运行时解释执行,可做代码热更。
2 特性 / 规则
-
AB 包只能承载资源 (预制体、模型、贴图、音效、场景),不能存放 C# 脚本;
-
热更新一般流程:①设置 AB 资源标记 ②编辑器构建 AB 包 ③服务端存放 AB 包资源 ④客户端下载 ⑤客户端加载 AB 包使用资源。
4 相关知识点对比
冷更新 VS 热更新
冷更新:完整安装包,包体积大,必须应用商店审核; 热更新:只下载变更资源,增量更新,不需要重装 App;仅资源可以热更,原生 C# 脚本不行。
5 模块拓展
代码热更需要 Lua 框架(XLua、ToLua)。
二、AssetBundle(AB 包)基础概念
1 概念
Unity 专有资源压缩包,把模型、贴图、音效、预制体、场景打包成独立压缩包;支持分包、记录资源依赖关系,用于热更新,减小初始安装包体积。
2 特性 / 规则
-
不支持 C# 脚本,其他资源均可打包;
-
自带依赖记录,A 资源依赖 B 资源,会在 Manifest 记录依赖;
-
压缩算法:LZ4、LZMA、Uncompressed(不压缩);
-
可以放到服务端,游戏运行下载到本地再加载;
-
Resources 文件夹内资源全部打进安装包,无论是否使用;AB 包资源初始不进主包,可以后续下载。
3 语法 & 编辑器配置
在 Project 窗口选中资源,Inspector 底部设置AssetBundle Name,设置包名(后缀可以自定义,商业项目一般做文件名混淆加密)。
C# 脚本没有 AB 包设置项,脚本不能打入 AB 包。
4 相关知识点对比
Resources VS AssetBundle
Resources:打包全部打入主包,运行时直接 Load,不能热更; AB 包:资源可外置服务端,按需下载加载,支持热更新、分包。
5 模块拓展
商业项目会对 AB 包文件做简单加密,防止资源被直接提取破解。
三、编辑器构建 AB 包(Editor 工具)
1 概念
编写 Editor 文件夹内菜单工具,调用 Unity API 批量构建 AB 包;打包代码必须放在 Editor 文件夹,打包工具仅编辑器可用,打包进 App 会被剔除。
2 特性 / 规则
-
输出路径需要代码判断,不存在就创建文件夹;
-
需要指定目标平台(Windows/Android/iOS),不同平台 AB 包资源格式不互通;
-
指定压缩模式;
-
构建完成会生成 AB 资源文件 +
.manifest清单文件。
3 语法 & 代码片段
using UnityEditor;
using System.IO;
public class BuildABTool{
[MenuItem("Tools/Build AssetBundle")]
static void BuildAllAB(){
string outPath = "AssetBundles";
if (!Directory.Exists(outPath))
Directory.CreateDirectory(outPath);
BuildAssetBundleOptions opt = BuildAssetBundleOptions.None; //有多种压缩方式,None是一种
BuildTarget target = BuildTarget.StandaloneWindows64;
BuildPipeline.BuildAssetBundles(outPath, opt, target);
}
}
4 相关知识点对比
手动拷贝资源 VS AB 分包构建
全部资源打主包:安装包体积巨大,无法增量更新; AB 分包:初始主包小,资源按需下载更新。
5 模块拓展
打包前自动清理旧输出目录。
四、三种 AB 包压缩模式
1 概念
BuildAssetBundleOptions 控制压缩算法,三种模式:LZMA、LZ4、Uncompressed。
2 特性 / 规则
-
None(LZMA):高压缩率,包最小;加载时整体解压;需要完整解压后再使用;CPU 解压开销大。
-
ChunkBasedCompression(LZ4) :折中方案;可以按需局部解压,不需要解压整个包;项目最常用;包体积比 LZMA 大,CPU 开销低。
-
Uncompressed:完全不压缩;体积最大;加载最快,无解压开销;仅本地测试用。
4 相关知识点对比
| 模式 | 压缩算法 | 包大小 | 加载特性 | 适用场景 |
|---|---|---|---|---|
| None (默认打包格式) | LZMA | 最小 | 整体解压,CPU 开销高 | 网络存储,追求极小包体 |
| ChunkBasedCompression | LZ4 | 中等 | 按需局部解压,开销低 | 项目正式发布,首选 |
| Uncompressed | 无 | 最大 | 无需解压加载快 | 本地测试调试 |
5 模块拓展
压缩率越高,CPU 解压开销越大,要在包体大小和性能之间做平衡。
五、Manifest 清单文件 & 校验码 CRC/MD5/SHA1
1 概念
构建 AB 包同时生成 manifest 清单,分为总包 manifest、每个 AB 包自己的 manifest;记录包名、版本号、CRC 校验码、资源列表、依赖关系。
2 特性 / 规则
-
Manifest 核心信息: 版本号:客户端与服务端版本对比,判断是否需要更新资源; CRC/MD5/SHA1 校验码:校验下载后文件完整性,判断传输是否损坏; 资源清单:包内部包含哪些资源; 依赖列表:记录当前 AB 包依赖哪些其他 AB 包。
-
校验码对比: CRC:16 位,速度快; MD5:128 位; SHA1:160 位,校验最严格。
3 语法 & 使用逻辑
客户端下载 AB 包,拿本地文件校验码与服务端 manifest 内校验码对比,不一致说明文件损坏,重新下载。
4 相关知识点对比
没有校验 VS CRC 校验
无校验:网络传输损坏的资源直接加载,会出现贴图丢失、模型异常; CRC 校验:检测文件损坏,自动重下。
5 模块拓展
热更新流程核心:对比版本号→对比校验码→下载损坏 / 新版本 AB 包。
六、AB 包分包策略与依赖
1 概念
多个资源之间存在引用依赖(模型引用贴图);如果模型和贴图分到不同 AB 包,只加载模型 AB 包而没有加载贴图 AB 包,贴图会丢失;必须把所有依赖包提前加载进内存。
2 特性 / 规则
-
分包常见策略 按类型分包:贴图包、模型包、音效包; 按业务模块分包:UI 包、背包资源包、战斗怪物资源包; 按场景分包:场景 A 资源包、场景 B 资源包; 按更新频率分包:经常更新的包、不经常更新的包。
-
分包禁忌:不能出现资源冗余,同一个资源被打进多个 AB 包,内存重复占用。
-
manifest 可以读取 AB 包全部依赖列表,代码自动加载所有依赖包。
3 语法 & 代码片段(依赖加载逻辑伪代码)
//读取manifest拿到某AB包所有依赖包名
string[] deps = manifest.GetAllDependencies("test.ab");
foreach(var depName in deps){
//提前加载每一个依赖AB包
AssetBundle.LoadFromFile(depPath);
}
//再加载主AB包
AssetBundle mainAb = AssetBundle.LoadFromFile(mainPath);
//读取资源并实例化
GameObject cubePrefab = mainAb.LoadAsset<GameObject>("Cube");
GameObject cube = Instantiate(cubePrefab);
4 相关知识点对比
全部资源一个 AB 包 VS 合理分包
单大包:更新微小资源也要下载整个大包,流量消耗大; 合理分包:只更新发生改动的小包。
5 模块拓展
分包粒度权衡:包数量太多管理复杂;包太大增量更新效率低。
七、AssetBundle 卸载 Unload
1 概念
AB 包加载进内存,不用的时候需要卸载释放内存;AssetBundle.Unload(bool unloadAllLoadedObjects)。
2 特性 / 规则
-
Unload(true):卸载该 AB 包加载出来的所有资源对象,哪怕场景中正在使用,也会被卸载,物体材质贴图丢失; -
Unload(false):只卸载 AB 包本身文件内存;已经实例化到场景的资源对象保留不卸载;只释放 AB 包文件内存。 -
长期不用的 AB 包调用 Unload 释放内存,防止内存持续上涨。
3 语法 & 代码片段
AssetBundle ab;
ab.Unload(true); //卸载包+所有由这个包加载出来的资源
ab.Unload(false); //仅卸载AB包文件,已使用的资源保留
4 相关知识点对比
Unload(true) VS Unload(false)
true:彻底释放,但容易造成场景资源丢失;适合完全不再使用该包所有资源; false:只释放包文件内存;场景物体不受影响;适合临时切换,资源还会复用。
5 模块拓展
Resources.UnloadUnusedAssets () 卸载场景未使用资源。
八、AB 包多种加载方式(同步 / 异步)
1 概念
AB 包提供多套加载 API,分为同步、异步;异步用协程 +AssetBundleCreateRequest,不会卡住主线程。
常用三类:LoadFromFile、LoadFromMemory、LoadFromStream;另外 Manifest 逆向加载、UnityWebRequest 网络加载。
2 特性 & 语法
① LoadFromFile(最常用,LZ4/LZ4 压缩包优先)
//同步
AssetBundle ab = AssetBundle.LoadFromFile(path);
//异步
AssetBundleCreateRequest req = AssetBundle.LoadFromFileAsync(path);
yield return req;
AssetBundle ab = req.assetBundle;
优点:不需要把整个包读进托管内存,开销低; 限制:不支持加密 AB 包,只能明文包。
② LoadFromMemory(从字节数组 byte \[\] 内存加载)
byte[] bytes = File.ReadAllBytes(path);
AssetBundle ab = AssetBundle.LoadFromMemory(bytes);
把整个文件全部读进托管堆内存;适合加密后的包,解密得到 byte \[\] 再加载;内存开销更大。
③ LoadFromStream 文件流加载
FileStream fs = File.Open(path,FileMode.Open,FileAccess.Read);
AssetBundle ab = AssetBundle.LoadFromStream(fs);
缓冲区流式读取,适合加密 AB 包;速度相比 File 更慢。
④ Manifest 逆向加载(先读取 manifest,再拿依赖、再加载 AB 包)
正向加载:直接 LoadFromFile 加载 AB 包; 逆向加载:先加载总包 manifest,通过 API 获取所有包名、依赖列表,再动态加载对应 AB 包;热更新项目标准写法。
⑤ UnityWebRequest(网络下载 AB 包,异步)
using UnityEngine.Networking;
UnityWebRequest req = UnityWebRequest.GetAssetBundle(url);
yield return req.SendWebRequest();
AssetBundle ab = DownloadHandlerAssetBundle.GetContent(req);
支持 http 网络地址下载 AB 包;下载完成一般会保存到本地磁盘,下次直接 LoadFromFile 本地读取,不用重复下载。
4 相关知识点对比
同步加载 VS 异步加载
同步:会阻塞主线程,游戏卡顿;小资源可以,大资源禁止在 Update 主线程直接同步 Load; 异步协程:不会卡住游戏,正式项目优先异步加载。
5 模块拓展
下载完成后持久化保存 AB 包到本地 PersistentDataPath 目录。
综合拓展
1 AB 包完整热更新流程 设置资源 AB 标记 → Editor 工具构建 AB 包,生成 manifest、CRC 校验码 → AB 包上传 HTTP 服务端 → 客户端启动:下载 manifest,版本、CRC 对比 → 下载需要更新的 AB 包保存本地 → 异步加载 AB 包、自动加载全部依赖包 → 读取包内资源实例化使用 → 不用时调用 Unload 释放内存。
2 高频 Bug 排查清单
贴图模型丢失:分包后没有加载依赖 AB 包; AB 包打包报错:脚本放在非 Editor 文件夹,打包 API 运行时调用; 资源加载贴图消失:Unload (true) 卸载正在使用的资源; LoadFromFile 加载失败:AB 包做了加密(LoadFromFile 不支持加密,改用 Memory/Stream); 不同平台 AB 包不能混用:Windows 打包出来的 AB 包不能直接在 Android 运行。
3 核心考点 热更新 / 冷更新区别、AB 包三大压缩算法优缺点、Manifest 清单作用、CRC 校验码、分包策略、依赖关系、Unload (true/false) 区别、多种加载 API 适用场景、正向加载与 Manifest 逆向加载。
4 进阶拓展学习方向 XLua 代码热更新、AB 包加密、增量差分更新、PersistentDataPath 本地持久目录、下载进度回调。