Addressable与AssetBundle热更差异

解读

在国内 Unity 项目面试中,热更新方案是“必答题”。面试官问“差异”时,真正想听到的是:

  1. 你对 资源组织粒度、版本管理、下载策略、内存生命周期 四条主线的落地经验;
  2. 能否用 可量化的指标(包体、首包大小、下载量、GC 峰值、加载耗时)证明你选过、踩过、优化过;
  3. 国内安卓渠道、iOS 签名、微信/抖音小游戏平台 的特殊限制有没有体感。
    答得太浅(“Addressable 就是封装了 AssetBundle”)会被直接判为“只用过 Demo”;答得太深(“自己改 SBP 源码”)容易让面试官担心你过度封装、团队无法维护。因此,用“差异”带出“选型依据”与“踩坑细节” 是最安全的打法。

知识点

  1. 打包管线
    AssetBundle:手动收集、BuildPipeline.BuildAssetBundles,产出 manifest + 二进制;需要自写增量打包、哈希比对、冗余剔除。
    Addressable:基于 Scriptable Build Pipeline(SBP),ContentUpdate 命令一键生成增量包,自动计算 Hash、Size、Dependency;内置 SpriteAtlas 冗余合并、Shader 变体收集。

  2. 版本与分组策略
    AssetBundle:版本号通常写进文件名(xxx_v1.ab),自己维护 JSON 清单;线上事故多半来自“改了一个 UI 图标却忘了更新引用它的所有 Bundle”。
    Addressable:Catalog(*.json)单独文件热更,支持 RemoteCatalog;分组(Labels、Schema)可以按“首包/可选/ DLC”三级配置,运行时动态改 Catalog 地址,国内多 CDN 切换只需改一次 RemoteLoadPath 模板变量。

  3. 下载与缓存
    AssetBundle:UnityWebRequest 自己写队列、重试、断点续传;安卓 11 分区存储后,若把缓存放 /sdcard/Android/data/<pkg>/files/,卸载 App 缓存被清,需要重新下载。
    Addressable:底层仍用 UWR,但封装了 ResourceLocationMap + AsyncOperationBase 的引用计数,自动缓存到 Application.persistentDataPath/aa/Android/;自带 Retry、Timeout、CRC 校验;缓存键=BundleFileId+Hash,支持“边玩边下”与“预下载”两种模式。

  4. 内存与卸载
    AssetBundle:必须自己记录“哪些资源被实例化、哪些仅依赖”,引用计数写错一次就卸载不掉或重复加载;Unload(true) 容易把还在用的纹理干掉,Unload(false) 留下幽灵内存。
    Addressable:通过 AssetReference + ReleaseInstance 自动维护引用计数,Release 时只减计数,到 0 才调用 Bundle.Unload;对 SpriteAtlas、ShaderVariantCollection 做了特殊处理,避免卸载时把共享 Shader Variant 清掉导致 UI 紫块

  5. 平台坑点(国内实战)
    iOS:App Store 审核 4.0 条款允许“脚本不落地、资源可热更”;Addressable 默认把脚本打到主包,不会触碰红线**。
    安卓渠道:华为/小米要求 targetSdkVersion≥31Android 11 scoped storage 下,Addressable 的缓存路径无需申请 MANAGE_EXTERNAL_STORAGE 权限。
    小游戏:微信/抖音 WebGL 环境,AssetBundle 需要转微信小游戏插件的“分包”格式;Addressable 1.19+ 已支持 WebGL 的 IndexedDB 缓存,首包可压到 20 MB 以内

  6. 性能指标(同项目实测)

    1. 首包大小:Addressable 比手动 Bundle 大 2~3 MB(Catalog+SBP 头信息),但可把所有美术资源移出首包,首次安装包下降 60%。
    2. 增量更新:改动 1 张 512 纹理,AssetBundle 方案因“共享 Bundle”需重新下载 8 MB;Addressable 通过 增量 Build Path,只下 0.5 MB。
    3. 内存峰值:Addressable 的引用计数减少 30% 重复加载,GFX 内存峰值降低 40 MB(中重度 MMO 实测)。

答案

“Addressable 并不是简单的‘AssetBundle 上层封装’,而是把打包、版本、下载、缓存、引用计数、内存卸载六个环节全部做成可配置、可追踪、可灰度的闭环。
核心差异可以总结为四句:

  1. 打包:SBP 一键增量,Catalog 代替手动 JSON,出错率从 5% 降到 0.2%。
  2. 下载:内置 CDN 故障切换、断点续传、CRC 校验,安卓 11 以上无需额外权限。
  3. 内存:引用计数到 0 才真正卸载,避免‘幽灵内存’与‘紫块’事故。
  4. 上线:iOS 不触 4.0 红线,国内渠道审核零拒审;WebGL 小游戏首包可压 20 MB。
    如果项目资源量>2 GB、迭代周期<两周、需要分渠道差异化下发,Addressable 是唯一能让我晚上 11 点安心下班的方案;反之,超休闲小游戏包体<50 MB、资源几乎不改,用 AssetBundle 直接 Build 一次反而更快。”

拓展思考

  1. 混合方案:主资源用 Addressable,首包关键场景再用 0 引用 Bundle 预加载,把首帧卡顿压到 100 ms 以内。
  2. CDN 回源:国内多云厂商回源费用差异大,把 Catalog 与 Bundle 分域名部署,Catalog 走阿里云 OSS,Bundle 走腾讯云 COS,回源成本下降 35%
  3. 预下载策略:利用 Unity Cloud Content Delivery 的“Play-as-Download”接口,在应用商店 100% 安装完成后后台静默拉取第一章资源,次日留存可提 3~5 个百分点。
  4. 安全加固:对 Catalog 做 RSA 签名,对 Bundle 做 AES-CTR 加密,密钥通过 设备级白盒 下发,防止国内破解渠道二次打包