一、概述与核心概念

1.1 是什么

YooAssets 是一套 Unity 资源管理方案,支持多运行模式(Editor 模拟 / 离线 / 联机 / WebGL)、资源

1.2 核心概念速查

概念

含义

YooAssets

静态入口类:驱动 GameObject、默认包、所有静态加载 API(如 LoadAssetSync)

ResourcePackage

一个「资源包」:绑定一种运行模式、一套文件系统、一个 ActiveManifest

EPlayMode / PlayModes

运行模式:Editor 模拟 / Offline / HostPlay / WebPlay

IFileSystem

抽象「资源从哪来」:本地目录、StreamingAssets、沙盒缓存、CDN

PackageManifest

资源清单:location→资源信息、Bundle 依赖等

ActiveManifest

当前包正在使用的 manifest,加载/下载都依赖它,未设置会报错

OperationSystem

每帧驱动所有异步 Operation(初始化、请求版本、更新 manifest、加载资源),支持时间片

1.3 官方与示例

包(Package)、版本与 Manifest 管理、异步加载与时间片调度。

二、初始化流程(详细步骤与含义)

2.1 整体流程图

YooAssetManager.Init(PlayModes mode)
         │
         ├─ 1. YooAssets.Initialize()               ← 全局只做一次:驱动 + 操作队列
         ├─ 2. YooAssets.SetOperationSystemMaxTimeSlice(30)  ← 每帧给异步操作的时间片(ms)
         ├─ 3. YooAssets.CreatePackage("DefaultPackage")    ← 创建资源包容器
         ├─ 4. YooAssets.SetDefaultPackage(package)          ← 设为默认包,静态 API 用此包
         ├─ 5. InitPackage(package)                         ← 按 PlayMode 建文件系统,**不**    加载 manifest
         ├─ 6. RequestPackageVersion()                       ← 获取当前要用的版本号
         ├─ 7. UpdatePackageManifest(packageVersion)        ← 按版本加载 manifest,并设置 ActiveManifest
         └─ 完成 → 可调用 YooAssets.LoadAssetSync / LoadAssetAsync 等

2.2 各步骤含义说明

步骤

含义

注意

  1. Initialize()

创建 [YooAssets] 驱动、YooAssetsDriver(每帧调 OperationSystem.Update)、初始化 OperationSystem

全局只调一次,重复调用会警告

  1. SetOperationSystemMaxTimeSlice(ms)

限制每帧用于执行 YooAssets 异步任务的最大毫秒数

避免单帧卡顿;不设则默认不限制

  1. CreatePackage(name)

new ResourcePackage,加入静态列表;此时仍是「空壳」

同名校验,重复创建会抛错

  1. SetDefaultPackage(package)

指定后续 YooAssets.LoadAssetSync 等使用的包

未设置时静态 API 会报 Default package is null

  1. InitPackage → InitializeAsync

按 parameters 类型选 PlayMode,创建 ResourceManager、PlayModeImpl,并创建并绑定 IFileSystem(见下文「文件系统绑定」)

此阶段不加载 manifest,ActiveManifest 仍为 null

  1. RequestPackageVersion

从主文件系统取「当前版本号」(如 "Simulate"、"v1.0")

必须 await 完成再调第 7 步

  1. UpdatePackageManifest

用主文件系统按版本号加载 manifest,并执行 _impl.ActiveManifest = manifest

唯一设置 ActiveManifest 的地方;未执行则加载资源会报错

2.3 两阶段设计(必记)

  • 阶段一(步骤 5):只做「基础设施」——文件系统、ResourceManager、PlayModeImpl,读 manifest。

  • 阶段二(步骤 6、7):先拿版本号,再按版本加载 manifest 并赋给 ActiveManifest。

  • 踩坑:若只做了阶段一就调 YooAssets.LoadAssetSync,会报 "Can not found active package manifest !",因为加载时依赖 ActiveManifest != null。

2.4 异步等待注意

  • RequestPackageVersionAsync、UpdatePackageManifestAsync 必须 await 到完成(如 await operation.ToUniTask()),不能只 await UniTask.Yield(),否则状态未完成就往下走,仍会没有 ActiveManifest 或版本号错误。

三、PlayMode 与文件系统

3.1 各模式对应的文件系统

PlayMode

文件系统(顺序)

版本/Manifest 来源

Bundle 来源

缺的从哪来

Editor

DefaultEditorFileSystem

模拟构建输出目录

同上,VirtualBundle 读工程资源

不下载

Offline

DefaultBuildinFileSystem

StreamingAssets 内置包

StreamingAssets

HostPlay

Buildin + Cache

主用 Cache(可请求远程)

Buildin 读内置;Cache 读沙盒/下载

Cache 经 IRemoteServices 从 CDN 下载

WebPlay

WebServer + WebRemote

WebRemote 从 CDN

WebServer 本地;WebRemote 从 CDN 拉

WebRemote

3.2 defaultHostServer 与 fallbackHostServer

  • defaultHostServer:主 CDN 根地址,拼出「主站」资源 URL,优先使用。

  • fallbackHostServer:备用 CDN 根地址,主站失败时重试。

  • 主备建议不同节点/域名,实现容灾;若写死且同源,CDN 故障会影响所有联机/Web 用户。

3.3 文件系统「绑定」发生在哪

  • 持有:PlayModeImpl.FileSystems(List)。

  • 写入:InitializationOperation 在 InitFileSystem 步骤中,对每个 FileSystemParameters 调用 CreateFileSystem(),再 _impl.FileSystems.Add(fileSystemInstance),即「绑定」。

  • 使用:请求版本、更新 manifest 用 GetMainFileSystem()(列表最后一个);加载/下载时用 GetBelongFileSystem(packageBundle) 决定从哪个文件系统读。


四、关键 API 与参数

4.1 SetOperationSystemMaxTimeSlice(ms)

  • 目的:限制每帧用于执行 YooAssets 异步 Operation 的最大时间(毫秒)。

  • 原理:OperationSystem.Update() 每帧遍历 Operation 时,若本帧已用时 ≥ MaxTimeSlice,则本帧不再执行后续 Operation,留到下一帧。

  • 建议:真机可设 20~30ms,在流畅度与加载进度之间折中。

4.2 ActiveManifest 设置位置

  • 仅在 UpdatePackageManifestOperation 内,当 LoadPackageManifestAsync 成功后执行:_impl.ActiveManifest = _loadPackageManifestOp.Manifest。

  • 因此必须完成「请求版本 → 更新 manifest」且成功,才能正常加载资源。


五、踩坑与解决(记录)

5.1 报错:Can not found active package manifest !

  • 原因:只做了包初始化(InitializeAsync),没有做 RequestPackageVersion + UpdatePackageManifest,或异步未 await 完成。

  • 解决:保证 Init 流程中依次执行并 await:RequestPackageVersion() → UpdatePackageManifest(packageVersion)。

5.2 报错:RequestPackageVersion 失败 / 找不到版本文件

  • Editor:先在 YooAssets 窗口执行「模拟构建」,或确认运行时 EditorSimulateModeHelper.SimulateBuild 成功,输出目录内有版本文件与 manifest。

  • Offline/Host:确认已用 YooAssets 做真机构建,且产物在 StreamingAssets 或指定目录,且包名一致。

5.3 打包真机报错:Failed to resolve assembly: 'HotUpdate'

  • 原因:AOT 层(如 Assembly-CSharp 里的 Launcher)直接引用了 HotUpdate 程序集里的类型(如 BokeMedical、YooAssetsLoader)。打包时 HotUpdate 以 .dll.bytes 存在,不参与链接,链接器找不到 HotUpdate 程序集。

  • 解决:AOT 层不要直接引用 HotUpdate 中的类型;改为「加载 HotUpdate 程序集后,通过反射调用入口」(例如 GameEntry.Run(playMode, mainBg))。所有使用 YooAssetsLoader、BokeMedical.UI 等的逻辑放在 HotUpdate 内,由入口统一执行。

5.4 真机运行报错:BokeMedical.GameEntry not found in HotUpdate

  • 原因:设备上的 HotUpdate.dll.bytes 是旧版(不含 GameEntry),或类型全名与反射用的字符串不一致。

  • 解决

    • 每次改 HotUpdate 代码后,重新生成 HotUpdate.dll 并放入 StreamingAssets/Bytes/,再打真机包。

    • 反射时兼容多种类型名:先试 BokeMedical.GameEntry、GameEntry,再通过 assembly.GetTypes() 查找 Name == "GameEntry" 的类型;找不到时打印程序集内类型列表便于排查。

5.5 发布包选错 PlayMode

  • 现象:真机需要热更却打成 Offline,或误用 Editor,导致无法更新或初始化失败。

  • 解决:Launcher 的 playMode 在 Inspector 配置,打包前检查;或在构建脚本中按构建目标自动设置/校验 PlayMode。

5.6 CDN 主备同源

  • 风险:defaultHostServer 与 fallbackHostServer 写死且相同,CDN 故障或迁移时所有联机/Web 用户无法拉取资源。

  • 建议:主备使用不同 CDN 或节点;CDN 地址配置化(配置文件/远程配置),便于紧急切换。


六、与 HybridCLR 配合要点

6.1 程序集划分

  • AOT 层(如 Assembly-CSharp、BuildIn):只做启动、加载 HotUpdate.dll.bytes、通过反射调用 HotUpdate 入口;引用 HotUpdate 内的类型(如 BokeMedical、YooAssetsLoader)。

  • HotUpdate 层:放 YooAssets 初始化、YooAssetsLoader、业务 UI 等;提供静态入口(如 GameEntry.Run(playMode, mainBg))供 AOT 反射调用。

6.2 推荐启动流程(AOT)

  1. 加载 HotUpdate 程序集(真机读 StreamingAssets/Bytes/HotUpdate.dll.bytes)。

  2. 用反射取入口类型(如按名 "GameEntry" 或 "BokeMedical.GameEntry"),再取静态方法 Run。

  3. Invoke 传入参数(如 playMode、mainBg),后续逻辑全在 HotUpdate 内执行(YooAssets Init、RequestVersion、UpdateManifest、加载界面等)。

6.3 热更 dll 与资源一致性

  • 热更脚本(HotUpdate.dll)与 YooAssets 资源包建议版本对应(同构建号/版本号),避免只更其一导致引用缺失或表现异常。

  • 发布前校验:热更包 = 指定版本的 DLL + 对应资源包,一起测试、一起上线。


七、学习路线建议

  1. 先通读本文档:建立「初始化 7 步、两阶段、ActiveManifest、PlayMode 与文件系统」的整体图。

  2. 跑一遍 Space Shooter 示例:对照初始化 → 请求版本 → 更新 manifest → 加载资源,与文档对应。

  3. 按源码层级看:YooAssets → ResourcePackage → OperationSystem → InitializationOperation / UpdatePackageManifestOperation → IFileSystem 实现。

  4. 单步跟一次加载:对 LoadAssetSync 下断点,从 YooAssetsExtension → ResourcePackage(ActiveManifest)→ ResourceManager。

  5. 按需看 Editor:收集规则、构建管线、模拟构建与真机构建输出目录。


文档随项目实践持续补充,便于记录与学习。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐