尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

10-03-YooAsset实战-Unity-Addressable-Assets实战

10-03-YooAsset实战-Unity-Addressable-Assets实战
📅 发布时间:2026/7/26 23:47:42

实战-Unity Addressable Assets实战

篇章:10-实战篇-从零搭建
状态:已完成
阅读时间:约 25 分钟


一、引言

1.1 本章在系列中的定位

Addressable Assets(简称 AA)是 Unity 官方推出的资源管理解决方案,目的是取代传统 AssetBundle。它的核心理念是"资源位置 + 资源标签"的解耦,让开发者只关心"我想要什么资源"而不必关心"资源在哪个包里"。

作为 Unity 官方的资源管理方案,AA 与 YooAsset 在设计上有许多相似之处。本章将系统对比 AA 与 YooAsset,帮助你深入理解 YooAsset 的设计取舍。

1.2 本章要解决的核心问题

  • Addressable Assets 的核心概念是什么?
  • AA 与 YooAsset 在架构上有何异同?
  • AA 的最佳实践是什么?
  • 什么场景下选 AA?什么场景下选 YooAsset?

1.3 阅读前置要求

  • 完成 10-01 YooAsset 项目搭建
  • 完成 10-02 Unity 原生 AB 实战
  • 了解 Unity 编辑器扩展基础

二、Addressable Assets 核心概念

2.1 安装

通过 Package Manager 安装:

Window → Package Manager → 搜索 "Addressables" → Install

安装后,菜单栏会出现Window → Asset Management → Addressables。

2.2 核心概念

2.2.1 Address(地址)

Address是资源的唯一标识符,类似 YooAsset 的Location:

// YooAsset var op = YooAssets.LoadAssetAsync<Sprite>("Assets/UI/Button.png"); // Addressable var op = Addressables.LoadAssetAsync<Sprite>("Button_Normal");

AA 的 Address 可以是:

  • 资源路径
  • 自定义标签
  • 资源 GUID
2.2.2 Group(组)

Group是资源的容器,类似 YooAsset 的 Group:

AA ├── Group_Default ← 默认组 │ ├── UI_Button_Normal.png │ ├── UI_Icon_Home.png │ └── ... ├── Group_Battle │ ├── Hero_Assassin.prefab │ ├── Skill_Fireball.prefab │ └── ... └── Group_Shared └── Atlas_Common.png
2.2.3 Label(标签)

Label是资源的"软分组",可以在运行时按标签批量加载:

Addressables.LoadAssetsAsync<Sprite>("ui_icons", null);
2.2.4 Catalog(目录)

AA 的 Catalog 类似 YooAsset 的 Manifest,记录所有资源与 Group 的映射。

2.3 Addressable 的工作流

[Editor 端] 1. 标记资源为 Addressable 2. 配置 Group 3. 构建(Build → New Build) [Runtime 端] 1. Addressables.InitializeAsync() 2. LoadAssetAsync(address) 3. Release(handle)

三、Addressable 实战

3.1 标记资源

步骤 1:开启 Addressable

Window → Asset Management → Addressables → Groups

步骤 2:标记资源

选中资源 → Inspector 中勾选Addressable:

Sprite Icon_Home ├── Asset Name: Home ├── Address: icons/home └── Labels: [ui, icons]

3.2 配置 Group

// Group 配置示例 public class MyGroupConfig { public string GroupName = "Default Local Group"; public BundleNamingStyle Naming = BundleNamingStyle.NoHash; // 或 FileNameHash public bool IncludeInBuild = true; public bool UseAssetBundleCache = true; public bool UseAssetBundleCrc = true; }

3.3 加载资源

using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; public class AddressableLoader { /// <summary> /// 同步获取句柄 /// </summary> public AsyncOperationHandle<Sprite> LoadSprite(string address) { return Addressables.LoadAssetAsync<Sprite>(address); } /// <summary> /// 异步加载 /// </summary> public async Task<Sprite> LoadSpriteAsync(string address) { var handle = Addressables.LoadAssetAsync<Sprite>(address); await handle.Task; return handle.Result; } /// <summary> /// 按标签批量加载 /// </summary> public async Task<List<Sprite>> LoadSpritesByLabel(string label) { var handle = Addressables.LoadAssetsAsync<Sprite>(label, null); await handle.Task; return new List<Sprite>(handle.Result); } /// <summary> /// 释放 /// </summary> public void Release<T>(AsyncOperationHandle<T> handle) { Addressables.Release(handle); } }

3.4 加载场景

public async Task LoadSceneAsync(string address) { var handle = Addressables.LoadSceneAsync(address, LoadSceneMode.Single); await handle.Task; } public void UnloadScene(AsyncOperationHandle<SceneInstance> handle) { Addressables.UnloadSceneAsync(handle); }

四、AA 高级特性

4.1 远端分发

public class RemoteDistribution { /// <summary> /// 配置远端 CDN /// </summary> public void SetupRemote() { // Profile 配置 var profile = AddressableAssetSettingsDefaultObject.Settings.profileSettings.GetProfile("Remote"); var remoteLoadPath = profile.GetValueByName("RemoteLoadPath"); var remoteBuildPath = profile.GetValueByName("RemoteBuildPath"); } /// <summary> /// 检查更新 /// </summary> public async Task CheckForCatalogUpdates() { var checkHandle = Addressables.CheckForCatalogUpdates(false); await checkHandle.Task; if (checkHandle.Result.Count > 0) { // 有更新,更新 Catalog var updateHandle = Addressables.UpdateCatalogs(checkHandle.Result, false); await updateHandle.Task; } Addressables.Release(checkHandle); } }

4.2 资源变体(Variants)

AA 支持按变体打包(如中/英/日语言包):

Group_UI ├── ui_textures_zh ├── ui_textures_en └── ui_textures_ja
public async Task<Sprite> LoadWithVariant(string baseAddress, string variant) { var address = $"{baseAddress}[{variant}]"; return await Addressables.LoadAssetAsync<Sprite>(address).Task; }

4.3 资源预加载

public class ResourcePreloader { public async Task PreloadByLabel(string label, int priority = 0) { var handle = Addressables.LoadAssetsAsync<Object>( label, null, Addressables.MergeMode.Union, releaseDependenciesOnFailure: false, priority: priority ); await handle.Task; } }

4.4 内存管理

public class AAMemoryManager { public void ReleaseAll() { // 释放所有引用 Resources.UnloadUnusedAssets(); } public long EstimateMemory() { // AA 不直接提供内存查询 // 需结合 Profiler return Profiler.GetTotalAllocatedMemoryLong(); } }

五、AA vs YooAsset 对比

5.1 架构对比

维度AddressableYooAsset
厂商Unity 官方tuyoogame 团队
内核资源管理框架资源管理框架
上层抽象ResourceManagerYooAssets
异步系统AsyncOperationHandleAsyncOperationBase
引用计数自动(基于 handle)显式(基于 Release)
缓存Resource LocatorIFileSystem
加密无内置支持
断点续传内置内置
跨平台完整完整(含小游戏)
VFS 抽象无完整支持
性能高高
易用性★★★★★★★★
文档丰富中等
社区庞大活跃
中文支持一般完善

5.2 API 对比

功能AddressableYooAsset
加载资源LoadAssetAsync<T>(address)LoadAssetAsync<T>(location)
按标签加载LoadAssetsAsync<T>(label, callback)不直接支持(需遍历)
加载场景LoadSceneAsync(address, mode)LoadSceneAsync(name, mode)
释放Release(handle)op.Release()
检查更新CheckForCatalogUpdatesRequestCheckVersionAsync
更新目录UpdateCatalogsRequestPackageManifestAsync
加载进度handle.PercentCompleteop.Progress
取消加载Release(handle)op.Cancel()
实例化InstantiateAsync(address)自己实现

5.3 详细对比

5.3.1 异步操作
// Addressable var handle = Addressables.LoadAssetAsync<Sprite>("icon"); await handle.Task; var sprite = handle.Result; // YooAsset var op = YooAssets.LoadAssetAsync<Sprite>("icon"); await op.Task; var sprite = op.Result;

差异:AA 的 handle 需要手动 Release,YooAsset 的 op 同样需要 Release。两者 API 高度相似。

5.3.2 批量加载
// Addressable:按 Label 加载 var handles = Addressables.LoadAssetsAsync<Sprite>( "ui_icons", sprite => Debug.Log($"Loaded: {sprite.name}") ); // YooAsset:按 Tag 或遍历加载 // YooAsset 没有直接的批量加载 API // 需自己遍历资源

差异:AA 的 Label 系统更强大,YooAsset 需要自己遍历。

5.3.3 多 Package
// Addressable:通过不同的 Group 实现 // 一个 Group = 一个 Package // 运行时通过 Address 自动路由 // YooAsset:内置多 Package var package = await YooAssets.LoadPackageAsync("ActivityPackage"); var op = package.LoadAssetAsync<Sprite>("activity_icon");

差异:YooAsset 的多 Package 更显式,适合复杂业务场景。

5.4 选型建议

场景推荐理由
全新 Unity 项目AA 或 YooAsset 均可两者都能满足
中文项目YooAsset中文文档完善
小游戏项目YooAssetYooAsset VFS 专为小游戏设计
海外项目AA 或 YooAsset都支持
已有 AA 项目继续用 AA迁移成本高
已有 YooAsset 项目继续用 YooAsset迁移成本高
多 Package 复杂业务YooAsset内置多 Package
单机游戏AA简单易用
联机游戏两者均可看团队偏好

六、AA 性能优化

6.1 内存优化

// 1. 及时释放 public void OnDestroy() { if (_handle.IsValid()) Addressables.Release(_handle); } // 2. 预加载控制 public async Task PreloadCritical(string label) { var handle = Addressables.LoadAssetsAsync<Object>(label, null); await handle.Task; _criticalHandles.Add(handle); } // 3. 异步释放 public async Task UnloadCritical() { foreach (var handle in _criticalHandles) { Addressables.Release(handle); } _criticalHandles.Clear(); Resources.UnloadUnusedAssets(); }

6.2 加载优化

// 1. 并发控制 public async Task BatchLoad(List<string> addresses, int maxConcurrent = 10) { var semaphore = new SemaphoreSlim(maxConcurrent); var tasks = addresses.Select(async address => { await semaphore.WaitAsync(); try { return await Addressables.LoadAssetAsync<Sprite>(address).Task; } finally { semaphore.Release(); } }); return await Task.WhenAll(tasks); }

6.3 构建优化

// 1. 压缩配置 public class BuildConfig { public void Optimize() { // 在 Group 配置中 BundleMode = BundlePackMode.PackTogetherByLabel; IncludeAddressInCatalog = false; IncludeGUIDInCatalog = false; IncludeLabelsInCatalog = true; } }

七、AA 踩坑记录

7.1 常见问题

问题原因解决方案
资源找不到Address 拼写错误启用Addressable Asset Settings → Send Diagnostic Event
内存泄漏忘记 Release配合 weak reference
加载失败构建时未包含检查 Group 的 Include In Build
跨域错误CDN 配置错误检查 Profile 中的 RemoteLoadPath
场景加载慢资源未预加载用PreloadDependenciesAsync
Hash 变化资源被修改启用Use Asset Bundle Cache

7.2 调试技巧

// 开启诊断事件 [InitializeOnLoadMethod] public static void EnableDiagnostics() { Addressables.ResourceManager.ResourceProviders .OfType<IResourceProvider>() .ToList() .ForEach(p => { if (p is ResourceProvider rp) rp.DiagnosticEvent += (op, type, ctx) => Debug.Log($"[AA] {type}: {ctx}"); }); }

7.3 监控面板

public class AAMonitor { public void ShowStatus() { Debug.Log($"正在下载: {Addressables.WebRequestOverride}"); Debug.Log($"已加载 Bundle: {GetBundleCount()}"); Debug.Log($"总内存: {Profiler.GetTotalAllocatedMemoryLong() / 1024 / 1024} MB"); } }

八、迁移到 YooAsset

8.1 迁移评估

评估项内容
AA 资源数统计需要迁移的资源
API 使用面列出所有 LoadAssetAsync 调用
跨域资源是否有 CDN 资源
自定义 Provider是否有自定义 ResourceProvider

8.2 迁移工具

public class AAToYooAssetMigrator { public void MigrateAddressables() { // 1. 读取 AA 配置 var aaSettings = AddressableAssetSettingsDefaultObject.Settings; // 2. 创建 YooAsset Group foreach (var group in aaSettings.groups) { var yooGroup = new PackRule { Name = group.Name, Filter = "Assets/...", // 根据 Group 配置生成 }; } // 3. 转换 Address foreach (var entry in aaSettings.GetAllAssets()) { // entry.address → YooAsset Location } } }

九、总结

9.1 本章要点回顾

  • AA 核心:Address + Group + Label + Catalog
  • AA 工作流:Editor 标记 → Build → Runtime Load
  • AA 优势:Unity 官方、Label 系统、丰富的文档
  • AA 痛点:没有原生加密、引用计数相对隐式
  • YooAsset 优势:VFS(小游戏)、中文支持、多 Package

9.2 与前后章节的关联

  • 前章:10-02 介绍了 Unity 原生 AssetBundle
  • 本章:对比 Addressable,介绍 AA 与 YooAsset 的异同
  • 后章:10-04 将介绍资源组织与依赖管理

9.3 实践建议

  1. 新项目选型:根据团队熟悉度、是否需要小游戏、是否多语言决定
  2. 不轻易切换:AA ↔ YooAsset 切换成本高,选定后就坚持用
  3. 混合使用:理论上可行,但不推荐(增加复杂度)
  4. 关注性能:两者都需要关注内存、并发、构建时长

上一篇:Unity 原生 AssetBundle 实战
下一篇:资源组织与依赖管理实战

相关新闻

  • 2026年7月湖南省衡阳市移动单宽带攻略与避坑指南 - 找卡家园
  • 微服务架构进阶:Spring Cloud Alibaba实战
  • 2026年7月湖南省常德市电信500M单宽带实测办理全流程 - 找卡家园

最新新闻

  • 2026年咒术回战cos假发厂家哪家靠谱选购实用指南 - 热点品牌推荐
  • 北京税务师事务所怎么选?2026中小企业避坑全攻略,榜首专业与性价比双优 - 互联网科技品牌测评
  • QQ空间历史记录备份终极指南:3分钟快速获取所有说说内容
  • 多模态时空联合对齐:广域异构相机联动下的跨镜特征自持与盲区轨迹智能补全技术白皮书
  • 剪映AI智能抠像→达芬奇级合成输出:打通ProRes 4444 Alpha链路的6步工业级工作流(含LUT嵌入校准方案)
  • 深圳尼龙棒采购难题解析:如何选择可靠供应商与优化采购流程 - 热点品牌推荐

日新闻

  • OpenClaw开源智能体网关:AI助手与即时通讯的完美融合
  • 写一个简单的sh脚本
  • 2026年 西安缝隙天线厂家:5G通信与车载天线专业定制供应商深度分析 - 卓企推荐

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号