Addressables 远程资源更新¶
起因¶
第一次用 Addressables 做远程更新时,我以为把新打出来的 Bundle 覆盖到 CDN 上就行了。结果客户端还在读旧 Catalog,资源地址没变,但文件内容已经换了,最后出现加载到一半失败、缓存和清单对不上的情况。
后来才理清:资源文件、Catalog 和客户端缓存是三条独立的时间线,更新时必须一起考虑。
三个容易混淆的东西¶
| 对象 | 作用 | 更新时要注意 |
|---|---|---|
| AssetBundle | 实际资源数据 | 路径最好不可变,按构建版本分目录 |
| Catalog | 地址、依赖和 Bundle 的映射 | 客户端要主动拉取新版本 |
| Profile | 构建路径和加载路径的变量 | 本地路径与远程路径不要混用 |
简单来说,Catalog 决定“去哪拿”,Bundle 是“拿到的内容”。只换 Bundle 不换 Catalog,客户端通常不知道新文件在哪里。
分组不要按文件夹来¶
Addressables 的 Group 更适合按“会不会一起加载、一起更新、一起回退”来分。1 例如:
scene-common:多个关卡共用,更新频率低。battle-01:一个关卡或一个玩法模块。ui-activity:活动资源,可能每周更新。local-tutorial:跟随包体发布,不走远程。
把同一个功能的贴图、预制体和配置放在同一个 Group 里,更新时更容易控制下载量。按 Textures、Prefabs 这种文件夹分,最后往往会把所有模块绑在一起。
客户端更新流程¶
启动时先初始化,再更新 Catalog,最后按 Label 或 Address 下载依赖:
public async Task UpdateRemoteContentAsync(string label)
{
var init = Addressables.InitializeAsync();
await init.Task;
Addressables.Release(init);
var update = Addressables.UpdateCatalogs(false, null);
await update.Task;
Addressables.Release(update);
var sizeHandle = Addressables.GetDownloadSizeAsync(label);
var size = await sizeHandle.Task;
Addressables.Release(sizeHandle);
if (size == 0)
return;
var download = Addressables.DownloadDependenciesAsync(label);
try
{
await download.Task;
}
finally
{
Addressables.Release(download);
}
}
GetDownloadSizeAsync 只计算还没进缓存的资源,适合在加载界面显示体积。DownloadDependenciesAsync 默认不会自动释放 Handle,所以这里手动 Release。
发布目录按版本隔离¶
远程加载路径可以配置成:3
BuildVersion 是自定义 Profile 变量,每次构建生成一个新值,例如 2026.11.14-01。每次发布上传到新目录,CDN 上的旧目录先保留。需要回退时,把客户端读取的 Catalog 指回旧版本就行,不用重新打包。
本地构建路径和远程加载路径要分开:
LocalBuildPath = Library/Addressables/{BuildTarget}
LocalLoadPath = {UnityEngine.AddressableAssets.Addressables.RuntimePath}/{BuildTarget}
RemoteBuildPath = ServerData/{BuildTarget}/{BuildVersion}
RemoteLoadPath = https://cdn.example.com/aa/{BuildTarget}/{BuildVersion}
这样可以先把内容构建到本地,再由发布脚本上传,避免编辑器直接写 CDN。
内容更新不是普通重建¶
如果线上已经有玩家,直接重新 Build 全部内容会生成新的 Catalog,但旧包里的静态资源可能和新包不兼容。Addressables 提供了 Content Update 流程:先比较上次构建,再只打包发生变化的组,同时检查静态内容的限制。2
实际操作时要注意:
- 不要修改已经发布的 Address 或 Group 名,除非准备好迁移。
- 更新包和完整包分别验证,不能只测编辑器里的 Play Mode。
- Catalog 下载成功不代表 Bundle 下载成功,两个失败要分开统计。
- 活动资源可以预下载,但不要在战斗过程中突然开始大文件下载。
- 旧 Catalog 和旧 Bundle 至少保留一个版本的回退窗口。
下载放在加载界面¶
可以在登录或主城阶段完成 Catalog 更新,把实际资源下载放到玩家进入副本前的加载界面。这样登录流程不会因为 CDN 慢而卡太久,进入战斗时也不会临时读远程文件。
另外,建议在启动时关闭自动 Catalog 更新,改成显式调用 UpdateCatalogs。自动更新失败时不容易提示玩家,也不方便记录当前使用的是哪个版本。