09-03-YooAsset生态-与GameFramework-xAsset等框架集成 生态-与GameFramework/xAsset等框架集成篇章09-生态篇-集成与协同状态已完成阅读时间约 20 分钟一、引言1.1 本章在系列中的定位在实际项目中YooAsset 往往不是独立存在的而是与其他游戏框架协同工作GameFramework(GF)Unity 上最流行的全家桶框架包含资源管理、UI、流程、网络、事件等多个模块xAsset早期轻量级 AB 包管理框架ETECS 架构的分布式游戏框架FairyGUIUI 解决方案Fungus可视化叙事框架YooAsset 可以与这些框架共存或集成。本章重点分析最常见的两种GameFramework 集成 和 xAsset 迁移。1.2 本章要解决的核心问题GameFramework 与 YooAsset 如何并存xAsset 项目如何平滑迁移到 YooAsset与第三方插件FairyGUI、Fungus如何配合集成时有哪些常见坑1.3 阅读前置要求了解 YooAsset 的核心 API了解 GameFramework 框架基本使用了解 xAsset 框架基本使用可选二、GameFramework 集成2.1 GameFramework 简介GameFramework(GF) 是 Unity 上 Star 数量最多的全家桶框架之一由 StarForce 团队开源。它提供了模块说明资源管理GameFramework.ResourceUI 管理GameFramework.UI实体管理GameFramework.Entity流程管理GameFramework.Procedure网络GameFramework.Network事件GameFramework.Event声音GameFramework.Sound配置GameFramework.Config数据表GameFramework.DataTableGF 内置的资源管理模块GameFramework.Resource基于原生 AssetBundle 实现。在新项目中可以用 YooAsset 替换 GF 的资源模块。2.2 三种集成方式对比方式描述优点缺点方式 A替换用 YooAsset 替换 GF 资源模块完全发挥 YooAsset 能力改动较大方式 B并存GF 资源 YooAsset 共存改动小资源可能分裂方式 C桥接在 GF 之上封装 YooAsset兼顾两者架构复杂推荐方式 A新项目用 YooAsset 替换 GF 的资源模块。2.3 方式 A用 YooAsset 替换 GF 资源模块2.3.1 移除 GF 资源模块// 在 GameEntry 中注释掉资源模块 public class GameEntry : MonoBehaviour { private void Start() { // 原代码 // GameFrameworkEntry.Start(); // 改为只启动非资源模块 GameFrameworkEntry.Start(); } }或者通过条件编译public class GameFrameworkEntryCustom { public static void Start() { // 启动除 Resource 外的所有模块 var moduleTypes new[] { typeof(UI), typeof(Entity), typeof(Procedure), typeof(Network), typeof(Event), typeof(Sound), typeof(Config), typeof(DataTable), // typeof(Resource), // 禁用 Resource 模块 }; foreach (var type in moduleTypes) { GameFrameworkEntry.GetModule(type); } } }2.3.2 YooAsset 初始化public class GameEntry : MonoBehaviour { public YooAssetComponent YooAsset; private async void Start() { // 1. 启动 GF 非资源模块 GameFrameworkEntryCustom.Start(); // 2. 初始化 YooAsset await YooAsset.InitializeAsync(); // 3. 检查更新 var checkOp YooAsset.RequestCheckVersionAsync(); await checkOp.Task; // 4. 进入游戏流程 var procedure GameFrameworkEntry.GetModuleIProcedureManager(); procedure.StartProcedureProcedureLaunch(); } }2.3.3 资源加载适配器为 GF 编写一个 YooAsset 适配器让其他模块UI、Entity使用public class YooAssetAdapter { /// summary /// 加载资源替代 GF 的 LoadAsset /// /summary public static async TaskT LoadAssetAsyncT(string location) where T : UnityEngine.Object { var op YooAssets.LoadAssetAsyncT(location); await op.Task; return op.Result; } /// summary /// 加载场景替代 GF 的 LoadScene /// /summary public static async Task LoadSceneAsync(string sceneName, LoadSceneMode mode LoadSceneMode.Single) { var op YooAssets.LoadSceneAsync(sceneName, mode); await op.Task; } /// summary /// 卸载资源 /// /summary public static void UnloadAsset(AsyncOperationBase op) { op.Release(); } }2.4 方式 B并存如果项目已深度使用 GF且迁移成本高可以选择并存方案public class GameEntry : MonoBehaviour { void Start() { // GF 资源模块 GameFrameworkEntry.Start(); var gfRes GameFrameworkEntry.GetModuleIResourceManager(); // YooAsset 资源模块 YooAssets.InitializeAsync(); } }适用场景旧资源走 GF避免重打包新资源走 YooAsset通过命名空间区分GF.Resources.LoadAssetvsYooAssets.LoadAsset2.5 GF 资源到 YooAsset 的迁移如果旧项目要从 GF 资源迁移到 YooAsset迁移步骤 ───────────────────────────────────────── 1. 新旧并存 - 老 Bundle 走 GF - 新 Bundle 走 YooAsset - 通过业务层路由按资源命名空间 2. 渐进迁移 - 按资源类型逐步切换先切 UI再切场景 - 灰度验证每个类型切换后 AB 测试 3. 全量切换 - 删除 GF 资源相关代码 - 全部走 YooAsset - 重新打包 ─────────────────────────────────────────迁移工具脚本伪代码public class GFToYooAssetMigrator { public void Migrate(string oldGFAssetPath, string newYooAssetLocation) { // 1. 在 YooAsset 中重新构建这个资源 var newPath GenerateNewBuildRule(oldGFAssetPath); YooAssetCollector.AddPackRule(newPath); // 2. 添加路由老路径 → 新路径 RouteTable[oldGFAssetPath] newYooAssetLocation; // 3. 在 GF 调用处包装一层 var oldCall $GF.Resources.LoadAsset{oldGFAssetPath}(); var newCall $YooAssets.LoadAssetAsync{RouteTable[oldGFAssetPath]}(); } }三、xAsset 迁移3.1 xAsset 简介xAsset是早期轻量级 AB 包管理框架作者为github.com/AMark-GT。它在 Unity 资源管理历史上有重要意义简单代码量小核心逻辑约 2000 行轻量没有复杂抽象缺点功能有限、不支持多包、不支持小游戏3.2 xAsset 与 YooAsset 的对比维度xAssetYooAsset学习曲线平缓中等功能完整度基础完善多包支持❌✅小游戏支持❌✅加密基础完善下载断点续传简单完善社区活跃度已停更活跃推荐度不推荐新项目推荐3.3 迁移方案3.3.1 迁移步骤[xAsset 项目迁移到 YooAsset] │ ├── 1. 评估 │ ├── 统计 xAsset 资源数量 │ ├── 评估 API 使用面 │ └── 评估测试覆盖度 │ ├── 2. 引入 YooAsset │ ├── 通过 UPM 安装 YooAsset │ ├── 不删除 xAsset 代码 │ └── 配置 YooAsset 收集器 │ ├── 3. 并行运行 │ ├── 老资源走 xAsset │ ├── 新资源走 YooAsset │ └── 通过 Adapter 模式兼容 │ ├── 4. 切换 │ ├── 逐个模块切换 │ ├── AB 测试验证 │ └── 灰度发布 │ └── 5. 清理 ├── 删除 xAsset 代码 ├── 删除 xAsset 资源 └── 重新打包3.3.2 API 迁移对照xAsset → YooAsset 常用 API 对照功能xAssetYooAsset加载资源asset.LoadAsyncT()YooAssets.LoadAssetAsyncT()加载场景asset.LoadSceneAsync()YooAssets.LoadSceneAsync()卸载资源asset.Unload()op.Release()异步更新Versions.UpdateAsync()YooAssets.RequestCheckVersionAsync()异步下载Downloader.DownloadAsync()YooAssets.DownloadUpdateAsync()进度查询op.progressop.Progress取消操作op.Cancel()op.Cancel()迁移示例// xAsset 代码 public class XAssetLoader { public async TaskT LoadT(string path) where T : Object { var op asset.LoadAsyncT(path); await op; return op.asset; } } // YooAsset 等价代码 public class YooAssetLoader { public async TaskT LoadT(string location) where T : Object { var op YooAssets.LoadAssetAsyncT(location); await op.Task; return op.Result as T; } }3.3.3 配置迁移xAsset 的配置如Versions.json需要转换为 YooAsset 的格式public class ConfigMigrator { public void MigrateVersionsConfig() { // 读取 xAsset 版本配置 var xassetConfig LoadXAssetConfig(); // 创建 YooAsset 构建配置 var yooAssetConfig new BuildParameters { BuildVersion xassetConfig.Version, // ... 其他映射 }; // 保存 YooAsset 配置 SaveYooAssetConfig(yooAssetConfig); } }3.4 迁移优势迁移到 YooAsset 后获得的好处优势说明功能完整多包、加密、断点续传、VFS 全部支持持续更新社区活跃Bug 修复及时小游戏支持微信/抖音小游戏原生支持性能优异步体系、引用计数、缓存机制完善易扩展丰富的扩展点自定义 FS、Provider 等四、第三方插件集成4.1 FairyGUI 集成FairyGUI是 Unity 上流行的 UI 解决方案。它有自己的包管理机制UIPackage。4.1.1 集成方案public class FairyGUIYooAssetBridge { /// summary /// 从 YooAsset 加载 FairyGUI 资源 /// /summary public static async Task LoadFairyGUIPackage(string packageName) { // 1. 从 YooAsset 加载 FairyGUI 包描述文件 var descOp YooAssets.LoadAssetAsyncTextAsset($FairyGUI/{packageName}_fui); await descOp.Task; // 2. 从 YooAsset 加载 FairyGUI 包图集 var atlasOp YooAssets.LoadAssetAsyncTexture2D($FairyGUI/{packageName}_atlas0); await atlasOp.Task; // 3. 加载到 FairyGUI var uiPackage UIPackage.AddPackage(descOp.Result, atlasOp.Result); } }4.1.2 资源命名规范FairyGUI 资源建议放置在Assets/UI/FairyGUI/下并配置专属 PackRulenew PackRule { Name FairyGUIPack, Filter Assets/UI/FairyGUI/**/*, PackTo EBundlePackTarget.HotUpdatePackage }4.2 Fungus 集成Fungus是 Unity 可视化叙事框架常用于剧情对话。public class FungusResourceLoader { public static async TaskSprite LoadPortrait(string characterName, string portraitName) { // 通过 YooAsset 加载 var op YooAssets.LoadAssetAsyncSprite($Fungus/Portraits/{characterName}/{portraitName}); await op.Task; return op.Result as Sprite; } }4.3 DOTween 集成DOTween 是 Unity 动画插件。DOTween 本身不涉及资源加载所以无需特别集成。但要注意DOTween 的_Demo资源应排除出 YooAsset 收集DOTween 的 settings 文件需要打包到首包new PackRule { Name DOTweenExclusion, Filter Assets/Plugins/DOTween/**/*, PackTo EBundlePackTarget.None // 不打包 }4.4 通用集成模式无论哪种插件集成模式都是[业务层] │ ▼ [YooAsset 加载 API] │ ├── LoadAssetAsyncT(location) ├── LoadSceneAsync(sceneName) └── GetRawFileAsync(path) │ ▼ [插件 API] │ ├── FairyGUI.UIPackage.AddPackage ├── Fungus.Character.SetPortraitSprite └── ...统一入口原则所有资源加载都通过 YooAsset避免插件直接调用 Unity API。public class ResourceManager { public static async TaskT LoadAsyncT(string location) where T : UnityEngine.Object { // 统一入口 var op YooAssets.LoadAssetAsyncT(location); await op.Task; return op.Result as T; } }五、集成最佳实践5.1 集成原则5.1.1 统一入口所有资源加载走同一个ResourceManagerpublic class ResourceManager { // 推荐 public static T LoadT(string location) where T : Object YooAssets.LoadAssetSyncT(location); public static AsyncOperationBase LoadAsyncT(string location) where T : Object YooAssets.LoadAssetAsyncT(location); // 不推荐 public static T LoadFromResourcesT(string path) where T : Object Resources.LoadT(path); // 不允许绕过 YooAsset }5.1.2 统一错误处理public class ResourceExceptionHandler { public static void HandleLoadError(string location, Exception ex) { // 1. 记录日志 Debug.LogError($[Resource] 加载失败: {location}, 错误: {ex.Message}); // 2. 上报到监控系统 ReportToMonitor(resource_load_failed, new { location, ex.Message }); // 3. 降级如果可能 TryFallback(location); } }5.1.3 统一版本管理public class VersionManager { public string CodeVersion { get; private set; } public string ResourceVersion { get; private set; } public string HybridCLRVersion { get; private set; } public bool IsConsistent() { return CodeVersion ResourceVersion; } }5.2 集成测试5.2.1 测试矩阵测试类型内容功能测试单个资源加载、批量加载、并发加载性能测试加载速度、内存占用、GC 次数兼容性测试与其他模块的兼容性边界测试资源不存在、加载失败、超时灰度测试AB 测试新旧方案的差异5.2.2 自动化测试[Test] public async Task TestYooAssetLoad() { var op YooAssets.LoadAssetAsyncSprite(Assets/UI/Icon.png); await op.Task; Assert.IsTrue(op.Status EOperationStatus.Succeed); Assert.IsNotNull(op.Result); } [Test] public async Task TestYooAssetLoadBatch() { var tasks Enumerable.Range(0, 100) .Select(i YooAssets.LoadAssetAsyncSprite($Assets/UI/Icon_{i}.png).Task); await Task.WhenAll(tasks); Assert.IsTrue(tasks.All(t t.IsCompletedSuccessfully)); }5.3 集成文档需要交付的集成文档文档内容集成指南步骤、配置、注意事项API 映射旧 API → 新 API 对照示例代码常见场景的代码示例常见问题集成中遇到的问题与解决方案性能数据集成前后的性能对比六、典型集成案例6.1 案例 1MMO 项目[MMO 项目集成] ├── YooAsset资源管理 ├── GameFramework流程、UI、事件 ├── ET网络、ECS ├── FairyGUIUI 渲染 ├── HybridCLR代码热更 └── 自研战斗框架6.2 案例 2休闲游戏[休闲游戏集成] ├── YooAsset资源管理 ├── FairyGUIUI ├── DOTween动画 ├── xLua 或 HybridCLR脚本热更 └── 自研关卡框架6.3 案例 3小游戏[小游戏集成] ├── YooAsset资源管理 VFS ├── LUA脚本热更 ├── FairyGUIUI └── 自研简易框架七、总结7.1 本章要点回顾GameFramework可以用 YooAsset 替换其资源模块或并存xAsset迁移到 YooAsset 获得更多能力是历史趋势第三方插件通过 YooAsset 统一加载入口避免插件直接调 Unity API最佳实践统一入口、统一错误处理、统一版本管理7.2 与前后章节的关联前章09-02 解决了小游戏平台适配本章解决如何与现有框架集成的工程问题后章09-04 将介绍 UOS CDN 与服务器部署7.3 实践建议新项目直接用 YooAsset 替换 GF 资源模块从源头避免分裂旧项目渐进迁移按业务模块逐步切换降低风险统一资源入口所有加载都走ResourceManager.LoadAsyncT统一监控所有加载错误统一上报便于问题排查保留回退能力迁移过程中保留回退开关上一篇小游戏平台适配下一篇[UOS CDN与服务器部署](./09-04-生态-UOS CDN与服务器部署.md)

本月热点