做Unity项目做久了,资源这块迟早会撞上Addressables。不少朋友在群里问,说照着官方文档看完前面几章,加载、卸载、依赖管理都跑通了,结果卡在最后一步构建上,出包量大、加载卡顿、ab包文件对不上,甚至构建一次要半小时,构建完了资源又加载不出来。我最早上手Addressables的时候也在这块折腾了不少时间,网上资料大多零散,要么只讲流程不讲原理,要么塞一堆配置让人更迷糊。这一篇就专门把Addressables的构建环节彻底拆开讲清楚,覆盖构建整体原理、关键配置选择、完整实操步骤、多平台与自动构建方案,以及高频踩坑排查。无论你是刚接触Addressables的新人,还是已经在项目里用了但想优化构建流程的开发者,这篇内容都值得认真看一遍。
1. 构建这件事到底在干什么
1.1 构建不只是“打个包”
很多Unity开发者第一次接触Addressables构建时,会有个根深蒂固的误解:觉得Addressables的构建和AssetBundle的BuildPipeline.BuildAssetBundles差不多,就是把资源打进包里而已。这个理解只对了一半。
Addressables的构建,本质上是做三件事:街量资源并生成bundle文件、生成用于运行时寻址的Catalog文件、把构建结果和Unity的Player构建流程衔接起来。如果你不理解这三件事是怎么串起来的,后面遇到任何构建问题都会很头大。
我先打个比方。你开了一家仓库(项目),货架上堆满了各种商品(资源),平时玩家需要什么就去货架上取。Addressables构建干的事,就是把所有商品按照你的分类方案(Group)装箱,每个箱子外面贴上清晰的标签清单(Catalog),然后把箱子运到不同的门店(bundle文件)。运行时玩家需要某样东西,只凭一个逻辑地址(Address)去查清单,就能找到对应箱子,然后精准拆箱取货。
所以构建产出物最少有两类:
- bundle文件:实际承载资源的数据文件,扩展名常见为
.bundle,但实际文件类型取决于平台和设置。 - Catalog文件:JSON格式的清单文件,记录所有资源的地址(Address)到bundle文件的映射关系,包括依赖关系、类型信息、资源hash等。运行时Addressables初始化就是读取这个文件,它错了或者缺失,整个寻址体系就瘫痪。
还有一类会被很多人忽略的产物,是构建记录和日志文件。Unity会在Library/com.unity.addressables目录下生成一系列构建过程的数据文件,它们不是给玩家用的,而是给编辑器用的——用来做增量构建判断、内容更新差分、异常排查。
1.2 构建流程中的关键节点
Addressables的构建入口看似简单,菜单里就是Window > Asset Management > Addressables > Build > New Build > Default Build Script,但这里面的执行链路很长,我把关键节点列出来:
- 收集资源:遍历所有标记为Addressable的资源,以及它们的隐式依赖(比如Prefab引用的材质、贴图、Shader、动画控制器,C#脚本里的SerializedField引用的资源)。
- 分析依赖图:构建资源之间的引用关系图,确定哪些资源应该被打进哪个bundle,哪些资源是共享依赖,如何在bundle之间建立引用。
- 分组与打包:根据Group的设置(比如Bundle Mode是Pack Together还是Pack Separately),把资源打包成对应的bundle文件。
- 生成内容Hash:对每个bundle计算内容hash,生成AddressablesContentState文件,用于构建缓存和内容更新。
- 生成Catalog:把最终的所有映射信息写入Catalog文件。
- 构建后处理:根据设置决定是否将构建产物拷贝到StreamingAssets,或者等待外部构建系统使用。
这几个节点里,最容易出问题的就是第2步和第3步——依赖图分析不完整、分组设置不合理会导致构建产物巨大、加载异常。这些在后面实操部分会展开讲。
2. 动工之前:构建方案选型与关键配置
2.1 三种构建模式,实际项目怎么选
Addressables提供了三种核心构建模式,分别对应不同需求场景,很多刚接触的人会在这一步卡住:
Build Script(打包整个Player):完整构建所有内容,生成Play Mode Script需要的bundle,并把结果拷入Player中。这个模式适合正式发布、或者做完整版本出包时使用。Update a Previous Build(增量更新):这个模式是在已有构建记录和内容状态的基础上,只构建变化的内容。它通常和远程资源热更新配合,适合已经上线运营的项目做版本更新。Clear(清理):清除缓存、构建数据和Catalog文件,一般建议在切换平台或者遇到构建数据混乱时执行。
除了这三种,实际项目里还有一个经常会用到的**Use Asset Database(直接使用AssetDatabase)和Simulate Groups(模拟分组)**开关。前者不生成bundle,而是直接让运行时从Assets目录加载资源,适合开发期快速迭代,速度极快,但不代表真实包体性能。后者模拟打包规则,主要用于分析资源归属,不推荐日常使用。
我实际的做法是:日常开发一律用Use Asset Database模式,只有需要真机测试、出包、检查负载表现时才切到完整构建模式。这样能省掉大量非必要的构建时间。
2.2 关键参数:压缩格式、Bundled Asset Provider、LOD等
构建参数全部集中在Window > Asset Management > Addressables > Settings中,先说三个影响最直接的:
压缩格式(Compression),这个和AssetBundle构建时的设置一致:
- LZ4:压缩率低,体积相对大,但运行时解压速度快,适合加载频繁的核心资源。Addressables构建推荐用LZ4,因为它采用按块压缩策略,解压时可以只解某一片段,内存占用更友好。
- LZMA:压缩率高,体积小,但解压时需要整体解到内存,加载慢,适合不常访问的冷资源。
- Uncompressed:完全不解压,加载最流畅但体积最大,基本只有在特殊平台或者性能极端敏感的场景才用。
我一般建议核心游戏资源用LZ4,皮肤类动画用LZMA,同时配合按需加载。如果你项目大部分是UI、角色、场景,做成混合策略比较合适。
Bundled Asset Provider:这个是决定"bundle中资源如何被加载"的Provider。默认是BundledAssetProvider,运行时通过AssetBundle.LoadFromFileAsync等方式加载资源。如果你需要自定义资源加载方式,可以继承ResourceProviderBase并注册到Provider列表中。这个对性能敏感项目很重要,但普通项目默认即可。
LOD设置:主要影响模型、贴图的自动LOD。Addressables有一个选项叫Build Remote Catalog(给远程内容做目录),还有Player Version——这个值参与Catalog文件名的生成,热更新时改它就能让客户端强制拉新目录。很多项目做远程更新时Catalog不刷新,就是这里没设对。
2.3 资源分组策略,直接决定包体和加载性能
到了构建阶段,Group的划分策略是最影响产物质量的环节。Group是逻辑分类,Addressables构建时以Group为单位产出bundle。
以我参与过的一个ARPG项目为例,最初我们直接把所有资源扔进一个Group,构建产物2G,加载进游戏要卡十几秒。后来我们按下面规则重划Group:
- 常驻核心资源(基础UI面板、公共图集、通用Shader、全局配置):单独一组,采用Pack Together模式,打进一个bundle,启动时预加载。
- 按场景/玩法模块划分(主城、副本、战斗特效、特定NPC):每个模块一个Group,采用Pack Together模式,进入对应场景时加载。
- 单个大资源独立成组(过场CG、巨型模型、超清贴图):采用Pack Separately模式,每个资源一个bundle,按需加载、用后释放。
- 更新频率高的资源(运营活动UI、新角色):单独Group,配合远程构建和热更新策略。
规律就一句话:把相同生命周期、相同加载时机、相同更新频率的资源放一组。这能大大减少冗余依赖、降低bundle数量,同时又避免把八竿子打不着的资源强塞在一起。
2.4 平台与构建目标,提前规划省下一大笔时间
很多人一开始没想清楚多平台问题。Addressables构建产物和所选Build Target强相关:iOS、Android、Windows产出的bundle格式不通用,必须在File > Build Settings中切好平台再执行Addressables构建。
如果项目要发多个平台,我强烈建议:
- 为每个平台单独配置一个Addressables Profile(
Window > Asset Management > Addressables > Profiles),把构建路径、加载路径、变量分开管理。 - 使用
Platform变量来做条件约束,确保打包iOS时不会用到Android的bundle路径。 - 在CI/CD流水线中把平台切换和Addressables构建串成一个步骤,避免人工切来切去。
还有一个比较隐蔽的坑:不同平台允许的bundle数量上限不同。比如WebGL平台对bundle数量、总大小有限制,小游戏平台还有单独的bundle管理方案。做微信小游戏的同学要注意,Addressables的默认构建方案在小游戏平台上会有兼容性问题,可能需要自定义Build Script来适配小游戏运行时。这一点到第4节自动构建那里再展开。
3. 完整构建实操:从配置到出包
3.1 前期准备:检查依赖与清理旧构建数据
在点击构建按钮之前,有几项检查动作一定要做,否则后面排查问题会非常痛苦。
第一步,检查依赖资源是否完整。Addressables构建最怕的是资源引用了缺失文件。你可以用Window > Asset Management > Addressables > Analyze工具,选择Check Scene to Addressable Duplicate Dependencies和Check Resources to Addressable Duplicate Dependencies等规则。这个分析器会列出所有潜在问题,比如同一个资源既在Resources目录又在Addressables分组里、或者同一个依赖被多个bundle重复引用等。
第二步,清理旧构建数据。长期迭代后,Library/com.unity.addressables下的缓存数据很容易出现脏数据,导致增量构建异常。我习惯在切分支、升Unity版本、或者发现构建行为诡异时,先执行一次Assets > Addressables > Clean Build > All,再重新构建。虽然构建时间会变长,但换来的干净状态值得。
第三步,确认Profile中的Build Path和Load Path设置正确。这两个路径决定了bundle输出的位置和运行时加载的位置:
LocalBuildPath:本地构建产物的输出目录,默认是[UnityEngine.AddressableAssets.Addressables.BuildPath]/[BuildTarget]。LocalLoadPath:本地运行时加载路径,默认是[UnityEngine.AddressableAssets.Addressables.RuntimePath]/[BuildTarget]。RemoteBuildPath:远程构建产物的输出目录,用于上传CDN。RemoteLoadPath:远程运行时加载URL,一般是https://yourapi.com/[BuildTarget]这类。
一个常见的报错是LocalLoadPath和LocalBuildPath指向不一致,导致Editor里加载正常,真机却找不到bundle。建议用变量模板,不要硬编码绝对路径。
3.2 执行构建:命令行与图形界面两种方式
图形界面构建很简单:菜单栏Window > Asset Management > Addressables > Build > New Build > Default Build Script,构建过程中可以在Console看到日志输出。
但实际项目里我更推荐使用命令行方式,尤其是接入CI后,图形界面构建基本不可用。Unity支持用-executeMethod执行静态方法,下面这个写法适用性很高:
using UnityEditor; using UnityEditor.AddressableAssets; using UnityEditor.AddressableAssets.Settings; using UnityEngine; public static class AddressableBuildTools { public static void BuildAddressables() { string buildTargetStr = GetArgument("buildTarget"); BuildTarget target = BuildTarget.StandaloneWindows64; if (!string.IsNullOrEmpty(buildTargetStr)) { target = (BuildTarget)System.Enum.Parse(typeof(BuildTarget), buildTargetStr); } EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, target); AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings; if (settings == null) { Debug.LogError("Addressables settings not found."); return; } // 如果没有对应平台的Profile,可以动态切换变量 AddressableAssetProfileSettings profileSettings = settings.profileSettings; string profileId = profileSettings.GetProfileId("Default"); if (!string.IsNullOrEmpty(profileId)) { settings.activeProfileId = profileId; } AddressableAssetSettings.BuildPlayerContent(); // 构建完成后,用日志确认产物是否生成 string outputPath = settings.profileSettings.GetValue(settings.activeProfileId, AddressableAssetSettings.kRemoteBuildPath); Debug.Log($"Addressables build complete. Output: {outputPath}"); } private static string GetArgument(string name) { string[] args = System.Environment.GetCommandLineArgs(); for (int i = 0; i < args.Length; i++) { if (args[i] == "-" + name && i + 1 < args.Length) { return args[i + 1]; } } return null; } }然后命令行这样调用:
/Applications/Unity/Hub/Editor/2022.3.0f1/Unity.app/Contents/MacOS/Unity \ -batchmode \ -nographics \ -quit \ -projectPath /path/to/your/project \ -executeMethod AddressableBuildTools.BuildAddressables \ -buildTarget Android \ -logFile /path/to/logs/addressables_build.logWindows下路径改成Unity.exe的位置,参数一致。注意-quit要放在-executeMethod后面,确保方法执行完成后再退出。
3.3 构建产物的目录结构与验证方法
构建完成后,去BuildPath目录下看看,一般能看到这些文件:
ServerData/ ├── StandaloneWindows64/ │ ├── catalog_2023.06.01_12.00.00.hash │ ├── catalog_2023.06.01_12.00.00.json │ └── addressables_StandaloneWindows64.bundle.json文件是catalog本体,.hash文件是校验信息,运行时先下载hash再下载json。.bundle文件是真正的资源包,命名规则和分组相关。addressables_content_state.bin在Assets/AddressableAssetsData目录下,这是增量构建和更新判断的关键文件,不要删。
验证构建是否成功,第一步看Console有没有Addressable content build completed之类的日志,第二步打开Window > Asset Management > Addressables > Builds面板查看Build Logs,第三步从catalog中随机抽几个地址,用Addressables.LoadAssetAsync<GameObject>("myAddress")加载试试。
一个我常用的做法是:构建完做一次"无Project加载测试"——把ServerData拷到别处,用一个空的Unity工程通过Addressables初始化加载远程/本地目录中的资源,确保不依赖AssetDatabase也能正确加载。这一步能提前发现路径、依赖缺失问题,而不是等到打完整包后才发现。
3.4 控制台日志和构建报告的解读
构建日志很多人不爱看,但我强烈建议至少学会看两个地方:
第一是Console窗口里的Addressables类别日志,常见错误信息都带明确编号:
Dependency tree violation表示依赖图分析出问题,比如同资源被多个bundle引用但设置不一致。No AssetReference found表示绑定到外部资源的Addressable引用断裂了。Addressable content is built for another platform是典型的Platform不匹配。
第二是构建报告(Build Report),可以通过Window > Asset Management > Addressables > Builds > View Build Report查看。报告里最有用的是每个bundle的资源清单和大小分布。我排查包体膨胀时,先看报告里哪个bundle最大,再看最大bundle里装了什么资源,十有八九能定位到问题的根源——比如一份巨型贴图因为被某个Prefab间接引用而被打进常驻bundle里。
4. 进阶构建策略:增量更新、CI/CD与多平台并行
4.1 增量构建与内容更新:Update a Previous Build怎么用最稳
Addressables支持内容更新,这也是很多人选它而不是自己写AssetBundle工具链的主要原因。思路是:首次发布时保留addressables_content_state.bin文件,后续更新时基于它构建出变化部分,上传到远程,客户端启动时读取远程Catalog判断是否有新版本,有则下载新bundle。
实操流程:
- 首次完整构建,产出本地内容+远程Catalog。
- 把
addressables_content_state.bin和ServerData上传到版本服务器。 - 修改资源(比如替换某个Prefab)。
- 构建时选择
Update a Previous Build,Unity会对比content_state.bin找出变化的bundle,只重新构建这些bundle,并生成新Catalog。 - 把新生成的远程目录上传到CDN。
- 客户端启动时
checkForCatalogUpdates,如果发现哈希不同就下载新catalog。
这套流程有几处极容易出问题:
- Content Update Restriction设置。在Group的Advanced选项里如果选择了
Can Change Post Release,这个Group里的资源才能作为可更新内容独立构建。如果设成Cannot Change Post Release,这个Group的资源一旦发布就彻底锁死,更新时会整体打包进入App包。默认设置下,依赖资源如果被哪怕是可更新资源间接引用了,很容易被归入内嵌bundle导致更新失效。这个坑我踩过,经验是:宁可多开几个Group,也不要让不可更新资源引用了可更新资源。 - 版本号管理。
Player Version如果不变,某些缓存策略下客户端拿到的还是旧catalog。我建议把它和构建流水号绑定,保证每次更新都是新值。 - 本地bundle不能随便删。很多人更新后为了包体干净,把本地旧bundle删掉,结果依赖关系断裂,加载报错。Local Bundles和Content Update Bundles的引用关系是跨版本存在的,建议始终保留完整本地资源。
4.2 接入GitLab CI/CD或Jenkins:无人值守构建
做商业化项目,每个版本都要出包,CI/CD是绕不开的。Addressables构建接入CI的理念很简单:把上面AddressableBuildTools里的构建方法作为Unity命令行的-executeMethod目标执行,把产物路径设为构建产物,在CI脚本里创建和归档。
下面这个是GitLab CI/CD中的一个简单示例,核心步骤一样适用于Jenkins:
stages: - build_addressables - build_player - upload variables: UNITY_VERSION: "2022.3.0f1" build_addressables: stage: build_addressables image: unityci/editor:ubuntu-2022.3.0f1-base script: - unity-editor -batchmode -nographics -quit -projectPath ./ -executeMethod AddressableBuildTools.BuildAddressables -buildTarget Android -logFile build_ab.log artifacts: paths: - ./ServerData/ - ./*.bin expire_in: 1 week build_player: stage: build_player image: unityci/editor:ubuntu-2022.3.0f1-android script: - unity-editor -batchmode -nographics -quit -projectPath ./ -buildTarget Android -executeMethod BuildScript.BuildAndroidPlayer dependencies: - build_addressables artifacts: paths: - ./AndroidBuild/ expire_in: 1 week upload: stage: upload image: alpine script: - apk add --no-cache curl - curl -T ServerData/ https://cdn.example.com/upload这里的关键点:
addressables_content_state.bin文件是增量更新的命根子,把它作为CI产物持久化存储。如果CI每次都从干净工作区构建,这个文件在job结束后就丢了,后续内容更新就无从谈起。要把.bin文件单独归档到一个固定的存储路径,每次构建前拷贝回工作区。- 构建机的Unity路径、许可证激活、模块安装(Android SDK/NDK)都要提前配置好,这些不属于Addressables构建范畴,但少了任何一个都会卡死在前面。
- 每个平台单独跑一个job,Artifacts按platform命名,Upload阶段分别上传到对应CDN目录。
4.3 WebGL、微信小游戏等特殊平台的构建注意点
WebGL平台的Addressables构建和原生平台有些差异:默认构建会把bundle输出到StreamingAssets,WebGL加载bundle的方式走Unity WebGL的缓存机制,不会像原生平台那样直接从文件流加载。需要注意:
- 如果资源量很大,WebGL会一次性加载大量数据,前端内存体验会比较差,建议严格做好按需加载和资源释放。
- Catalog路径和WebGL的BaseURL要匹配,否则域名、端口不一致拿不到包。
微信小游戏更特殊。微信小游戏运行时没有Unity WebGL标准的文件系统,bundle需要上传到微信CDN,并通过wx.request等接口拉取。Addressables默认的WebGL构建并不能直接用,需要自定义Provider和Build Script。实际项目中,常见做法是:
- 用Addressables构建生成bundle后,写一个后处理脚本把bundle传成微信小游戏可识别的分包格式。
- 运行时发起网络请求,加载完bundle后调用
AssetBundle.LoadFromMemoryAsync或WebRequestQueue,再走Addressables的IResourceProvider接口。 - 总包体超过微信平台限制时,还要配合小游戏分包。
如果你不是专门做小游戏这块,记住一条结论:把"构建bundle"和"构建平台运行环境"两件事分开,先在Editor里确保bundle加载正常,再单独处理平台侧的加载适配层,排查问题时能省一大半力气。
5. 高频问题与排查技巧实录
5.1 构建报错与解决方案速查表
下表是我在几个项目里遇到的、以及其他团队问得最多的构建问题,直接列为对照表:
| 现象 | 常见原因 | 排查手段 | 解决方案 |
|---|---|---|---|
构建时报An item with the same key has already been added | Catalog里资源键重复 | 查看Console堆栈;查看Addressables Analyze | 查找重复Addressable地址,把资源重新命名或用唯一字符串作为Address |
| 构建产物巨大,远超预期 | 依赖分析不完整,共享依赖被打进多个bundle;或者图集/贴图无意义引用到了大型资源 | 看Build Report中各大bundle资源明细 | 用Analyze查重复依赖;把共享资源单独成组并调整依赖方向 |
运行时加载KeyNotFound | catalog和实际加载的地址对不上 | 检查已生成的catalog json内容;确认代码里用的Address和Inspector里的Address是否一致 | 统一使用常量或AddressableAssetReference,避免手写字符串 |
| 构建完成后Player包里没有bundle | Player构建时没把Addressables构建产物拷贝到StreamingAssets | 检查StreamingAssets下有无aa目录;检查构建日志 | 确认在Build Player Content中勾选了对应选项;或者手动把产物拷贝进StreamingAssets |
| 加载资源时URL网址404 | RemoteLoadPath和RemoteBuildPath不一致 | 看Profile设置;看加载日志中的URL | 统一Profile变量;检查CDN目录是否归档正确 |
Content update build is not allowed | content_state.bin缺失或过期 | 确认是否做了完整构建;检查bin文件时间戳 | 重跑一次完整构建,生成新的content_state.bin作为更新基线 |
这个表不是一个万能咒语,但它覆盖了大多数"构建正常但运行异常"的常见套路。真正遇到问题的时候,先对照这个表看没有匹配项,再用二分法缩小范围:先定位是构建阶段错误还是运行时错误,再定位是资源问题还是路径问题。
5.2 一次真实的"bundle可以加载但资源丢失"排查记
有一次我在新项目里启用Addressables,构建完在编辑器里一切正常,但打到Android真机上,场景能进,贴图却全是紫色。这个问题很有代表性,排查过程记录一下。
第一次反应是Shader没打进去。确实,Addressables构建时Shader如果只是被某个材质引用,理论上会自动包括进去;但如果Shader通过Shader.Find运行时查找,或者材质是运行时动态创建再赋值Shader的,这个Shader就不在依赖图里,只是恰好编辑器里有这个Shader所以正常,真机没有就紫了。
我打开Build Report检查,发现bundle里果然没有对应Shader。解决方案:把用Shader.Find的Shader制成ShaderVariantCollection并作为Addressable引用了,同时在构建前调用ShaderVariantCollection收集变体。
还有一个次生问题:场景里预制体引用了同一个材质,材质引用的Shader被打进另一个bundle里,虽然依赖关系存在,但加载顺序问题导致Shader资源还没就绪资源就被渲染了。这个通过给关键材质加上预加载(Addressables.LoadAssetAsync)或者调整资源加载顺序解决。
这类问题的通用排查思路是:在真机上查看运行时日志。Addressables的Log在真机上默认也会输出,用Android Profiler或者adb logcat抓取,能看到具体的加载失败路径和资源地址。别在Editor里反复猜,直接看设备日志比什么都快。
5.3 包体优化技巧:构建阶段能做些什么
很多人优化包体时只盯着原始资源压缩,忽略了构建阶段能做的两件重要事:
第一,分析bundle间重复内容。同一个图集、同一个FBX模型如果被多个bundle引用,构建时Addressables默认会尝试把共享依赖抽出来放到一个独立bundle。但如果你分组时改动了依赖方向,或者某个资源设置了Include In Build为false但又在依赖链里,就会出现同一份资源被多个bundle各打一份的情况。用Analyze的Check Duplicate Bundle Dependencies能发现,修正后包体可能会有显著下降。
第二,减小catalog体积。catalog文件会记录所有资源地址、类型、依赖关系,资源数量上了几万条以后,catalog可能膨胀到几十MB。构建阶段可以通过Include Build Layouts、Continuous Integration等设置来控制细节信息的保留程度,也可以自定义catalog生成逻辑过滤掉不必要的字段。这个优化对加载速度影响很大,尤其是走远程Catalog的项目,同样几MB的catalog,网络加载时体验差异明显。
5.4 仓库与团队协作:构建产物纳入版本控制的边界
构建产物该不该提交进Git仓库?这是一个常有争议的问题。纯个人项目我建议不提交,本地构建即可;团队项目则需要分情况:
Assets/AddressableAssetsData目录下的Settings、Profiles、Group等序列化配置必须提交。这是团队共用的逻辑配置,不提交会导致每个人打包结果不一致。addressables_content_state.bin建议放在一个固定且不随构建变动的路径下提交仓库,作为更新基线,同时配合CI定期归档。- ServerData目录(构建产物)不提交。它的体积大、二进制文件多、每次构建全变,放进Git会让仓库迅速膨胀。正确做法是让需要产物的人从CI里拉取,或者通过CDN分发。
- 如果团队用Unity Cloud Build或Build Automation,配置里能指定构建任务用的脚本和参数,这部分内容也建议纳入版本控制。
用一句话总结:把"生产配方"提交进仓库,"生产出来的商品"不要提交。
6. 从构建出发,反推Addressables的设计逻辑
把构建流程完整走通之后,其实能更清晰地理解Addressables整体设计。它比裸用AssetBundle强的地方在于:构建不只是生成bundle,还生成了catalog、content_state、profile等一套"元信息链",让资源在运行时能被寻址、被分析、被更新。理解了构建,就等于理解了这套系统的记忆和神经。
很多人在博客、社区问Addressables好不好用、值不值得换,我的个人看法是:如果你的项目还停留在小规模、单场景、捆绑式加载的资源阶段,那确实不需要Addressables;但凡是中大型项目、有热更新需求、需要控制包体、需要团队并行开发的,Addressables这套构建体系虽然前期成本高,长期省的心比写自定义AssetBundle工具链要少得多。
最后分享一个我用的习惯:每次构建Addressables之后,我都会顺手看一眼构建日志中生成的bundle数量和总大小,把这些数据和上一次对比记录在项目的构建看板上。资源增长有没有异常、分组策略有没有失守、依赖有没有意外膨胀,这些变化都会在构建数据上体现出来。刚开始可能觉得麻烦,坚持几个版本后,你对自己项目的资源变化曲线会了如指掌,排查问题时比翻文档好用得多。