Addressable使用说明
下面我把你这整套 Addressables 运行时框架 + Editor 工具链 按“每个脚本做什么、怎么用、完整日常流程怎么走、UI/图片/精灵/预制体/模型/音频怎么打包加载”系统讲清楚。
先说总原则:
- Addressables 的内容构建不是自动的,要么在 Editor 里手动构建,要么通过
AddressableAssetSettings.BuildPlayerContent()脚本触发。 - 资源释放要和加载镜像对应,这是 Addressables 正常内存管理的核心。
- 预下载推荐先用
GetDownloadSizeAsync算大小,再用DownloadDependenciesAsync下载依赖。已缓存内容返回 0。 - 场景用
LoadSceneAsync/UnloadSceneAsync。 - 构建后真实下载体积要看官方 Build Layout / Addressables Report,不是看你自己统计的源文件大小。官方也提供了 Addressables Report window。
一、你现在这套目录,建议这样理解
Editor 目录
Assets/
Editor/
AddressablesTools/
AddressablesEditorUtility.cs
AddressablesValidationWindow.cs
AddressablesKeyGenerator.cs
AddressablesBuildTools.cs
AddressablesSizeReport.cs / AddressablesSourceInventoryReport.cs
AddressablesTeamTools.cs
AddressablesKeyCodeGenerator.cs
AddressablesBuildGuard.cs
AddressablesNamingValidator.cs
AddressablesBuildReportTools.cs
AddressablesPostBuildChecklist.cs
AddressablesGroupTemplateCreator.cs
PreloadConfigGenerator.cs
AddressablesProjectBootstrapper.cs
AddressablesFolderRules.cs
AddressablesFolderAutoOrganizer.cs
AnalyzeRules/
PathLikeKeyAnalyzeRule.cs
DuplicateLabelAnalyzeRule.cs
MissingAssetAnalyzeRule.cs
InvalidRemoteGroupAnalyzeRule.cs
InvalidGroupNameAnalyzeRule.cs
InvalidKeyNamingAnalyzeRule.cs
ModelMustBePrefabAnalyzeRule.cs
RegisterCustomAnalyzeRules.cs
Runtime 目录
Assets/
Scripts/
Runtime/
AddressablesSystem/
Bootstrap.cs
ResourceKeys.cs
ResourceManager.cs
ResourceDiagnostics.cs
ResourceDiagnosticRecord.cs
ResourceLoadStage.cs
PreloadRule.cs
PreloadCatalogConfig.cs
PreloadManager.cs
PreloadUI.cs
SceneUpdatePopup.cs
GameConfig.cs
DemoUsage.cs
二、每个 Editor 脚本到底是干什么的
1. AddressablesEditorUtility.cs
这是公共工具类。
它一般负责:
- 拿到
AddressableAssetSettings - 遍历 groups / entries
- 根据 GUID 找资源路径
- 做一些通用字符串处理
- 给别的工具类复用
你平时不直接点它,它是底层公共库。
2. AddressablesValidationWindow.cs
这是可视化检查窗口。
它通常检查:
- 重复 key
- 空 key
- 缺失资源
- 路径式 key
- Remote 路径异常
什么时候用
- 日常开发时
- 导入一批新资源后
- 构建前快速人工检查
怎么用
菜单打开后点:
- “检查全部”
- 或单独检查某类问题
它的定位
它是“给人看”的,不是自动阻断构建的。
真正阻断构建的是 AddressablesBuildGuard.cs。
3. AddressablesKeyGenerator.cs
这是自动生成 Addressable key 的工具。
它会按你的规则把资源路径转成规范 key,例如:
Assets/AddressableRes/UI/Login/Panel.prefab
-> ui/login/panel
什么时候用
- 新资源刚做成 Addressable 后
- 批量导入资源后
- 你调整目录结构后
怎么用
你一般会用这两个菜单:
Tools/Addressables/Generate Keys/全部 Addressables 条目Tools/Addressables/Generate Keys/仅选中资源
作用
避免手工写一堆风格混乱的 key。
4. AddressablesBuildTools.cs
这是基础构建工具。
通常包含:
Build Player Content- 清构建缓存
- 打开 Addressables Groups / Settings / Analyze
什么时候用
- 日常手工构建 Addressables 内容
- 清缓存排查问题
- 快速跳转到 Addressables 面板
重点
Addressables 内容构建不是自动的,必须手动或 API 调用。
5. AddressablesSizeReport.cs / AddressablesSourceInventoryReport.cs
这是源码盘点报表,不是最终下载体积报表。
它统计的是:
- group
- key
- asset path
- label
- 源文件大小
什么时候用
- 内容盘点
- 查哪些资源在哪个组
- 跟内容团队对资源归属
不能做什么
它不能代表真实热更包体积。
真实 bundle 大小和依赖关系要看官方 Build Layout / Addressables Report。
6. AddressablesTeamTools.cs
这是团队级一键修复 / 汇总工具。
它一般负责:
- 自动补
Remote.BuildPath - 自动补
Remote.LoadPath - 自动把
Remote_*组绑定到远程路径 - 校验 label
- 导出汇总 CSV
- 给 Build Guard 提供“静默修复”能力
什么时候用
- 新项目初始化后
- Remote 组很多时
- 构建前先一键修路由
最常用菜单
Tools/Addressables/Team/Fix Remote Paths
7. AddressablesKeyCodeGenerator.cs
这是自动生成 ResourceKeys.cs 的工具。
它会扫描所有 Addressable entry,然后生成代码常量,例如:
public static class ResourceKeys
{
public const string UiLoginPanel = "ui/login/panel";
public const string SceneBattle01 = "scene/battle_01";
}
什么时候用
- key 批量变更后
- 新增大量资源后
- 构建前
为什么非常重要
运行时代码不再手写字符串,减少拼写错误和风格混乱。
8. AddressablesBuildGuard.cs
这是构建阻断器。
它会在真正 build 前检查硬错误,例如:
- 重复 key
- 空 key
- 缺失资源
- Remote 组路径异常
如果有这些问题,就不允许继续 Build。
什么时候用
- 每次正式构建前
- CI / 团队固定打包流程里
最常用菜单
Tools/Addressables/Build/Build With Guard
9. AddressablesNamingValidator.cs
这是命名规范检查器。
它负责检查:
- group 是否以
Local_/Remote_开头 - key 是否全小写、无扩展名、无空格
- label 是否全小写、无空格
什么时候用
- 新资源整理后
- 构建前
- 日常规范巡检
最常用菜单
Tools/Addressables/Validate/Naming Rules
10. AddressablesBuildReportTools.cs
这是打开官方报表与分析窗口的辅助工具。
它会给你菜单去打开:
- Analyze 窗口
- Addressables Report 窗口
- 构建后直接复盘的入口
什么时候用
- build 完之后
- 做包体积治理时
- 查重复依赖时
官方较新版本已经明确提供了 Addressables Build Report window。
11. AddressablesPostBuildChecklist.cs
这是构建后检查清单弹窗。
它不是功能核心,而是把团队流程固化下来,提醒大家:
- 看最大 bundle
- 看是否有隐式依赖
- 看是否重复打包
- 看依赖链是否异常
什么时候用
- build 完之后
12. AddressablesGroupTemplateCreator.cs
这是一键创建标准 Group 模板。
它会自动创建:
Local_CoreRemote_Common_UIRemote_Login_UIRemote_MainCity_EnvRemote_Battle01_Enemy- 等标准组
并自动绑定本地/远程 Build & Load Path。
什么时候用
- 新项目初始接入
- 老项目重构分组时
13. PreloadConfigGenerator.cs
这是自动生成预下载配置表的工具。
会生成:
PreloadCatalogConfig.asset
里面默认放:
loginmain_citybattle01
这些规则,每条规则带:
- labels
- 网络策略
- 自动下载策略
- 大小阈值
什么时候用
- 新项目初始化
- 预下载策略重置
14. AddressablesProjectBootstrapper.cs
这是一键初始化标准 Addressables 工程骨架。
它通常会串起来做:
- 创建标准 Groups
- 生成预下载配置表
- 修复 Remote 路径
- 生成
ResourceKeys.cs
什么时候用
- 新项目第一次接入时
最推荐的菜单
Tools/Addressables/Templates/Bootstrap Standard Project Setup
15. AddressablesFolderRules.cs
这是目录规则定义。
它本身不执行任何事情,只是定义:
- 哪个目录 -> 哪个 group
- 哪些 labels
- 是否自动生成 key
例如:
Assets/AddressableRes/UI/Login/ -> Remote_Login_UI + preload_login
什么时候改
- 你调整项目目录规范时
- 新增一个新阶段、新模块时
16. AddressablesFolderAutoOrganizer.cs
这是按目录自动归组 + 自动打 label + 可选自动规范 key 的核心工具。
什么时候用
- 大批量导入新资源后
- 资源已按目录放好后
- 你想自动归组而不是手工拖来拖去时
最常用菜单
Tools/Addressables/Organize/Auto Assign Groups And Labels By FolderTools/Addressables/Organize/Auto Assign Selected Assets By Folder
它内部会用:
AssetDatabase.FindAssets(...)搜目录。CreateOrMoveEntry(...)把资源放进正确 group。SetLabel(...)自动打 label。
三、AnalyzeRules 目录里每个脚本怎么理解
这些都是挂到 Addressables Analyze 窗口里的规则。
PathLikeKeyAnalyzeRule.cs
检查是否有人把 key 写成:
Assets/...xxx.prefabxxx.png
这种“路径式 key”。
DuplicateLabelAnalyzeRule.cs
检查:
- 没有 label
- label 大小写混用
- label 风格混乱
MissingAssetAnalyzeRule.cs
检查 entry 指向的资源是否已经丢失。
InvalidRemoteGroupAnalyzeRule.cs
检查 Remote 组有没有绑对远程路径。
有些版本里还可以做成 CanFix = true,直接在 Analyze 里点 Fix。
InvalidGroupNameAnalyzeRule.cs
检查 group 是否符合 Local_ / Remote_阶段_职责 的规范。
InvalidKeyNamingAnalyzeRule.cs
检查 key 是否符合小写、无扩展名、业务路径风格。
ModelMustBePrefabAnalyzeRule.cs
检查动态模型类资源是否直接用了 .fbx/.obj,而不是 prefab。
这条非常适合你现在的模型规范。
RegisterCustomAnalyzeRules.cs
作用只有一个:
把这些规则注册到 Analyze 窗口里。
没有它,规则不会出现在 Analyze 面板。官方自定义 Analyze 规则就是这么注册的。
四、运行时脚本分别怎么用
1. Bootstrap.cs
职责:
- 显式
InitializeAsync(false) CheckForCatalogUpdatesUpdateCatalogs
为什么要显式初始化
因为官方明确说显式初始化可以把第一次资源加载的初始化抖动前置掉。
场景里怎么放
启动场景放一个空物体:
Bootstrap
2. ResourceKeys.cs
职责:
- 所有 key / label 常量统一收口
用法
运行时代码不要再写:
"ui/login/panel"
改成:
ResourceKeys.UiLoginPanel
3. ResourceManager.cs
这是你运行时最核心的加载器。
负责:
LoadAssetAsync<T>(key, scope)加载图片、Sprite、Texture、AudioClip、TextAsset、ScriptableObject、Material 等InstantiateAsync(key, ..., scope, usePool)加载 prefab / 模型 prefab / UI 面板 prefabLoadSceneAsync(...)GetDownloadSizeAsync(...)DownloadDependenciesAsync(...)- 引用计数
- 并发去重
- 对象池
- scope 批量释放
重要规则
- 共享资源:
LoadAssetAsync<T>加载后要ReleaseAsset - Prefab 实例:
InstantiateAsync后要ReleaseInstance - 场景:
LoadSceneAsync后要UnloadSceneAsync - scope:离开阶段时用
ReleaseScopeAsync(scope)
这正符合 Addressables 的“load/release 镜像对应”规则。
4. ResourceDiagnostics.cs / ResourceDiagnosticRecord.cs / ResourceLoadStage.cs
职责:
- 统一错误记录
- 记录失败阶段
- 记录 key / label / scene / 体积 / URL / catalog 状态
为什么需要
以后你看到加载失败时,能知道是:
- 初始化失败
- 检查 catalog 失败
- 更新 catalog 失败
- 下载失败
- key 不存在
- 场景加载失败
而不是只有一个 Debug.LogError("加载失败")。
5. PreloadRule.cs
描述一条预下载规则,例如:
- 登录页规则
- 主城规则
- battle01 规则
6. PreloadCatalogConfig.cs
一个 ScriptableObject 配置表,里面放很多 PreloadRule。
7. PreloadManager.cs
职责:
- 根据 ruleId 查规则
- 统计这次需要下载多少
- 判断是否允许自动下载
- 按 label 顺序预下载
常用接口
CheckRuleAsync(ruleId)DownloadRuleAsync(ruleId)
8. PreloadUI.cs
职责:
- 弹窗显示预下载体积
- 显示下载进度
- 控制确认 / 取消
用法
例如:
preloadUI.RunRule("login");
9. SceneUpdatePopup.cs
职责:
- 进入某个场景前弹窗提示“本次需要更新多少资源”
- 用户确认后再下载,再进场景
用法
例如:
sceneUpdatePopup.CheckAndDownloadRule("battle01", async ok =>
{
if (!ok) return;
await ResourceManager.Instance.LoadSceneAsync(ResourceKeys.SceneBattle01, LoadSceneMode.Single, true, "battle_01");
});
10. GameConfig.cs
这是一个 ScriptableObject 配置示例。
说明配置也可以做成 Addressable。
11. DemoUsage.cs
这个一般只是示例,不建议长期作为正式业务入口。它的作用是让你快速验证:
- 图片能加载
- 音频能加载
- prefab 能加载
- 场景能切
五、从 0 到能跑的完整流程
下面是最重要的部分:你平时到底按什么顺序用。
阶段 A:项目初始化
第 1 步:安装并初始化 Addressables
在 Unity 里:
- Package Manager 安装 Addressables
- 打开
Window > Asset Management > Addressables > Groups - 让项目生成 Addressables Settings
第 2 步:一键初始化标准模板
执行:
Tools/Addressables/Templates/Bootstrap Standard Project Setup
它会帮你:
- 创建标准 Groups
- 生成
PreloadCatalogConfig.asset - 修复 Remote 路径
- 生成
ResourceKeys.cs
阶段 B:资源导入与归类
第 3 步:把资源放到规范目录
例如:
Assets/AddressableRes/UI/Login/
Assets/AddressableRes/Common/UI/
Assets/AddressableRes/MainCity/Env/
Assets/AddressableRes/MainCity/Characters/
Assets/AddressableRes/Battle01/Enemies/
Assets/AddressableRes/Audio/
Assets/AddressableRes/Config/
第 4 步:一键按目录自动归组和打 label
执行:
Tools/Addressables/Organize/Auto Assign Groups And Labels By Folder
或者只处理选中资源:
Tools/Addressables/Organize/Auto Assign Selected Assets By Folder
这一步会自动:
- 创建/移动 entry 到对应 group
- 打对应 labels
- 可选自动生成 key
阶段 C:规范与代码生成
第 5 步:自动生成或修正 key
执行:
Tools/Addressables/Generate Keys/全部 Addressables 条目
或者只对选中的资源执行。
第 6 步:生成 ResourceKeys.cs
执行:
Tools/Addressables/Team/Generate ResourceKeys.cs
之后你的运行时代码一律用 ResourceKeys.xxx。
第 7 步:检查规范
执行:
Tools/Addressables/Validate/Run All
Tools/Addressables/Validate/Naming Rules
需要更深入就打开:
Window > Asset Management > Addressables > Analyze
阶段 D:预下载配置
第 8 步:检查 PreloadCatalogConfig.asset
确认里面有这些规则:
loginmain_citybattle01
每条规则包含:
- labels
- 网络策略
- 自动开始策略
- 体积阈值
例如:
login:preload_login + feature_common_ui + feature_common_configmain_city:preload_main_city + feature_main_city_envbattle01:preload_battle_01 + feature_battle_01_enemy
阶段 E:构建前
第 9 步:一键修复与预检查
执行:
Tools/Addressables/Pipeline/Run Full Pre-Build Pipeline
或者手工走:
Tools/Addressables/Team/Fix Remote PathsTools/Addressables/Validate/Run AllTools/Addressables/Validate/Naming Rules- Analyze
第 10 步:构建阻断
执行:
Tools/Addressables/Build/Build With Guard
有硬错误就不让构建。
阶段 F:构建内容
第 11 步:真正构建 Addressables 内容
执行:
Build With Guard- 或
Build Player Content
构建后会生成:
- catalog
- hash
- bundles
Addressables 内容构建必须显式执行。
阶段 G:上传到服务器
第 12 步:上传构建产物
上传到:
https://vipar.cn/game/addressables/[BuildTarget]/
例如:
https://vipar.cn/game/addressables/StandaloneWindows64/
上传这些:
catalog_*.json或二进制 catalog 对应文件catalog_*.hash*.bundle
第 13 步:浏览器验证
至少测试:
- catalog 能访问
- hash 能访问
阶段 H:构建后复盘
第 14 步:看源码盘点报表
执行:
Tools/Addressables/Report/Generate Source Inventory CSV
第 15 步:看真实构建报表
执行:
Tools/Addressables/Report/Open Addressables Report Window
Tools/Addressables/Report/Open Analyze Window
Tools/Addressables/Report/Show Post-Build Checklist
记住:
- 源码盘点 ≠ 真实下载体积
- 真实体积和依赖布局要看官方 Build Report / Analyze。
阶段 I:运行时加载与冒烟测试
第 16 步:启动场景放常驻对象
放 4 个:
BootstrapResourceManagerResourceDiagnosticsPreloadManager
如果有下载弹窗,再加:
PreloadUISceneUpdatePopup
六、UI、图片、精灵、预制体、模型、音频到底怎么打包和加载
这是你最关心的部分,我按资源类型讲。
1. UI 图片 / 精灵(Sprite)
资源准备
例如:
Assets/AddressableRes/Common/UI/Icon_Coin.png
建议:
- 如果是给
Image用,就导入成Sprite - 放到合适 group,例如
Remote_Common_UI - key 例如:
ui/common/icon_coin
加载方式
Sprite sp = await ResourceManager.Instance.LoadAssetAsync
image.sprite = sp;
释放
ResourceManager.Instance.ReleaseAsset(ResourceKeys.UiCommonIconCoin, "login");
2. RawImage 背景图 / Texture2D
资源准备
例如:
Assets/AddressableRes/UI/Login/BG_Main.png- 导入为
Texture2D
加载方式
Texture2D tex = await ResourceManager.Instance.LoadAssetAsync
rawImage.texture = tex;
释放
ResourceManager.Instance.ReleaseAsset(ResourceKeys.UiBgMain, "login");
3. UI 面板 Prefab
资源准备
例如:
Assets/AddressableRes/UI/Login/LoginPanel.prefab
建议:
- 直接做成 prefab
- panel 上需要的 Image / Button / Text / 动画都配置好
- 放到
Remote_Login_UI - key 例如:
ui/login/panel
加载方式
用 新的统一方式:
优先用 InstantiateAsync,不要自己 LoadAssetAsync<GameObject> + Instantiate。
GameObject panel = await ResourceManager.Instance.InstantiateAsync(
ResourceKeys.UiLoginPanel,
parent: uiRoot,
scope: "login",
usePool: false
);
释放
ResourceManager.Instance.ReleaseInstance(panel, "login", toPool: false);
4. 角色 / 模型 / 怪物 / 环境物体
资源准备
统一做成 prefab,再 Addressable。
例如:
Knight.prefabSlime_01.prefabTree_01.prefab
不要直接拿裸 FBX / OBJ 做运行时加载。因为 prefab 会把:
- 模型
- 材质
- 动画
- LOD
- 挂点
- 脚本
一起作为依赖被 Addressables 追踪。
加载方式
GameObject knight = await ResourceManager.Instance.InstantiateAsync(
ResourceKeys.CharKnight,
scope: "main_city",
usePool: true
);
回收
如果是高频对象:
ResourceManager.Instance.ReleaseInstance(knight, "main_city", toPool: true);
如果是一次性对象:
ResourceManager.Instance.ReleaseInstance(knight, "main_city", toPool: false);
5. 音频(AudioClip)
资源准备
例如:
Assets/AddressableRes/Audio/BGM_Main.wav- group:
Remote_Common_Audio - key:
audio/bgm_main
加载方式
AudioClip clip = await ResourceManager.Instance.LoadAssetAsync
audioSource.clip = clip;
audioSource.Play();
释放
ResourceManager.Instance.ReleaseAsset(ResourceKeys.AudioBgmMain, "main_city");
6. 配置(TextAsset / ScriptableObject)
TextAsset
例如:
config/game_text
TextAsset txt = await ResourceManager.Instance.LoadAssetAsync
ScriptableObject
例如:
GameConfig.asset- key:
config/game
GameConfig cfg = await ResourceManager.Instance.LoadAssetAsync
7. 场景(Scene)
资源准备
- 把场景设为 Addressable
- key:
scene/battle_01 - group:
Remote_Battle01_Scene或类似
进入场景
await ResourceManager.Instance.LoadSceneAsync(
ResourceKeys.SceneBattle01,
LoadSceneMode.Single,
true,
"battle_01"
);
离开场景
await ResourceManager.Instance.UnloadSceneAsync(ResourceKeys.SceneBattle01, "battle_01");
七、预下载到底怎么用
这是“新的加载方式”里非常重要的一部分。
1. 进入登录页前
preloadUI.RunRule("login");
2. 进入主城前
preloadUI.RunRule("main_city");
3. 进入 battle01 前
sceneUpdatePopup.CheckAndDownloadRule("battle01", async ok =>
{
if (!ok) return;
await ResourceManager.Instance.LoadSceneAsync(ResourceKeys.SceneBattle01, LoadSceneMode.Single, true, "battle_01");
});
这里用的是:
- 先
GetDownloadSizeAsync - 显示这次需要更新多少
- 用户确认
- 再
DownloadDependenciesAsync - 下载完再进场景
这是官方推荐的预下载思路。
八、运行时新的加载方式总结
你现在后面的业务代码,应该统一改成下面这种风格。
图片 / 精灵
await ResourceManager.Instance.LoadAssetAsync
贴图
await ResourceManager.Instance.LoadAssetAsync
音频
await ResourceManager.Instance.LoadAssetAsync
配置
await ResourceManager.Instance.LoadAssetAsync
UI 面板 / 模型 / 预制体
await ResourceManager.Instance.InstantiateAsync(key, parent, false, scope, usePool);
场景
await ResourceManager.Instance.LoadSceneAsync(key, mode, true, scope);
离开一个阶段
await ResourceManager.Instance.ReleaseScopeAsync(scope, unloadUnusedAssets: true, unloadUnusedAssetsDelaySeconds: 0.5f);
这样你资源生命周期、预下载、对象池、诊断、场景切换就全都统一了。
九、我建议你每天实际这么用
平时导资源
- 把资源放到规范目录
- 执行:
Auto Assign Groups And Labels By Folder
- 执行:
Generate KeysGenerate ResourceKeys.cs
日常检查
Validate/Run AllValidate/Naming Rules- Analyze
构建前
Run Full Pre-Build PipelineBuild With Guard
构建后
- 上传到
vipar.cn - 浏览器验 catalog/hash
- 看 Addressables Report / Analyze
- 冒烟测试:
- 登录页
- 主城
- battle01
- 图片 / prefab / 模型 / 音频 / 场景
十、你现在最值得记住的 10 条规则
- 模型统一 prefab 化再 Addressable
- Prefab 一律优先
InstantiateAsync - 共享资源一律
LoadAssetAsync<T> - 每次显式加载都要显式释放
- 预下载先查大小再下载
- Addressables 内容构建必须显式执行
- 源码大小报表不等于真实下载体积
- Build 后必须看官方 Report / Analyze
- Remote 组路径必须统一走 Profile
- 运行时代码不要再手写 key 字符串
十一、你下一步最适合做什么
你这套框架现在已经很完整了。
下一步最有价值的是二选一:
如果你更偏运行时体验,就继续做:
- 下载失败重试 UI
- 更细的下载队列
- 热更版本提示
如果你更偏团队效率,就继续做:
- 目录规则配置资产化(不是写死在代码里)
- 一键预览“这批资源会被分到哪里”
- CI 构建前自动跑 Guard
从你现在的进度看,更推荐你先做:目录规则配置资产化 + 预览模式。