Unity Addressable Assets 全面解析
篇章 :01-认知篇 · 基础 阅读时间 :约 30 分钟 前置知识:了解 Unity 基本资源加载方式
一、引言
Addressable Assets 是 Unity 官方推出的高级资源管理方案,它在原生 AssetBundle 的基础上提供了一层高级抽象,旨在简化资源管理的复杂性。本章将全面解析 Addressable Assets 的核心概念、工作原理、使用方法和最佳实践。
二、Addressable Assets 概述
2.1 什么是 Addressable Assets?
Addressable Assets 是 Unity 官方在 2019 年推出的资源管理方案,2021 年正式发布为 Unity Package。它的核心设计理念是:通过一个统一的、基于字符串的寻址系统来管理资源,让开发者无需关心资源是存储在本地还是远程服务器上。
Addressable Assets 的底层仍然使用 AssetBundle 作为资源存储格式,但通过 Provider 系统实现了加载逻辑的插件化。这意味着开发者可以通过配置来改变资源的加载方式,而无需修改代码。
2.2 核心架构
Addressable Assets 的架构可以分为三个层次:
- 资源层:AssetBundle 文件,存储实际的资源数据
- 管理层:ResourceManager,负责资源的加载、卸载、缓存和引用计数
- 抽象层:Provider 系统,负责具体的资源加载逻辑(本地文件、网络下载、内存加载等)
三、核心概念
3.1 Address(寻址)
Address 是 Addressable Assets 的核心概念。每个可寻址资源都有一个唯一的字符串地址,用于标识和访问该资源。
Address 的命名规则:
- 默认情况下,Address 是资源在 Project 窗口中的相对路径(去掉扩展名)
- 可以自定义 Address,使其更简洁易读
- Address 区分大小写
- 建议使用有意义的名称,如 Player/Prefabs/PlayerCharacter
3.2 Group(分组)
Group 是 Addressable Assets 中资源的逻辑分组。每个 Group 对应一个或多个 AssetBundle 文件。
Group 的打包策略:
- Pack Together:组内所有资源打成一个 Bundle
- Separate Each:每个资源单独打成一个 Bundle
- By Extension:按文件扩展名分组打包
- By Layout:按目录结构打包
3.3 Label(标签)
Label 是跨 Group 的资源标记方式。通过 Label,可以批量操作一组资源,而不需要知道它们具体在哪个 Group 中。
Label 的使用场景:
- 批量加载:通过 Label 一次性加载所有敌人资源
- 条件加载:根据游戏状态动态加载不同 Label 的资源
- 资源分类:按功能或场景对资源进行分类管理
3.4 Provider(提供者)
Provider 是 Addressable Assets 的插件化加载系统。每种资源类型都有对应的 Provider:
- Asset Provider:负责加载 Asset 资源
- Scene Provider:负责加载场景
- Atlas Provider:负责加载 Sprite Atlas
- Bundle Provider:负责加载 AssetBundle 文件
Provider 系统允许开发者自定义资源加载逻辑,例如实现自定义的下载策略或缓存机制。
四、Addressable Assets 使用示例
4.1 基本加载
csharp
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
// 通过 Address 加载单个资源
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>("Player");
handle.Completed += (op) =>
{
if (op.Status == AsyncOperationStatus.Succeeded)
{
GameObject player = op.Result;
Instantiate(player);
}
};
// 通过 Label 加载多个资源
AsyncOperationHandle<IList<GameObject>> handles = Addressables.LoadAssetsAsync<GameObject>("Enemy", null);
// 加载场景
AsyncOperationHandle<SceneInstance> sceneHandle = Addressables.LoadSceneAsync("Level1", LoadSceneMode.Additive);
// 释放资源
Addressables.Release(handle);
Addressables.Release(sceneHandle);
4.2 异步操作模式
Addressable Assets 支持多种异步操作模式:
- 委托回调:通过 Completed 事件处理加载结果
- 协程:使用 yield return 等待异步操作完成
- Task:使用 async/await 模式(Unity 2021+)
4.3 资源释放
Addressable Assets 使用引用计数来管理资源的生命周期。每次加载资源时引用计数加 1,每次调用 Addressables.Release() 时引用计数减 1。当引用计数为 0 时,资源才会被真正卸载。
五、Addressable Assets 的优势
5.1 自动化依赖管理
Addressable Assets 自动处理 Bundle 之间的依赖关系,开发者无需手动管理。这是 Addressable Assets 相比原生 AB 包最大的优势。
5.2 统一的 API
无论资源存储在本地还是远程服务器上,开发者都使用相同的 API 来加载资源。这种统一性大大简化了代码的编写和维护。
5.3 内建缓存
Addressable Assets 内建了资源缓存系统,自动管理资源的缓存和过期策略。
5.4 可视化编辑器
Addressable Assets 提供了可视化的编辑器窗口,可以方便地管理资源的 Address、Group 和 Label。
六、Addressable Assets 的局限性
6.1 性能开销
Provider 系统虽然灵活,但带来了额外的性能开销。每次资源加载都要经过 Provider 链的分发和路由,在大量小资源的频繁加载场景下,性能表现不如直接使用 AB 包。
6.2 自定义能力受限
Addressable Assets 的定位是通用方案,对于有特殊需求的项目,它的定制能力有限。例如,难以修改打包算法的核心逻辑,难以深度集成自定义的下载策略。
6.3 学习曲线
Addressable Assets 的概念体系相当庞大,包括 Address、Group、Label、Provider、ResourceManager 等。一个完整的工作流涉及数十个配置选项。
6.4 小游戏适配
微信小游戏、抖音小游戏等平台有特殊的文件系统限制。Addressable Assets 对这类平台的支持相对滞后。
七、Addressable Assets 与原生 AB 包的对比
| 维度 | Addressable Assets | 原生 AB 包 |
|---|---|---|
| 依赖管理 | 自动 | 手动 |
| 加载 API | 统一、简易 | 多种、复杂 |
| 版本管理 | 内建 | 需自建 |
| 资源寻址 | Address/Label | 路径 |
| 引用计数 | 自动 | 手动 |
| 性能开销 | 较高 | 较低 |
| 自定义能力 | 受限 | 灵活 |
八、总结
Addressable Assets 是 Unity 官方在资源管理领域的重要尝试。它通过高级抽象简化了 AB 包的使用,提供了自动化的依赖管理和统一的 API。然而,它也带来了性能开销和自定义能力受限等问题。理解 Addressable Assets 的优缺点,有助于我们在技术选型时做出更明智的决策。
上一篇 :Unity 原生 AssetBundle 全面解析 下一篇 :Unity 资源管理痛点分析