03-03-架构篇-Runtime加载系统架构

Runtime 端系统架构

篇章 :03-架构篇 阅读时间 :约 40 分钟 前置知识:了解 Editor 端系统架构


一、引言

本章将深入解析 YooAsset 的 Runtime 端系统架构。Runtime 端是 YooAsset 的运行层,在游戏运行时工作,负责资源的加载、管理、缓存和卸载。Runtime 端是玩家实际使用的部分,其架构设计的优劣直接影响游戏的性能和体验。

YooAsset 的 Runtime 端采用了 YooAssets → ResourcePackage → ResourceManager → Provider 的分层架构设计,职责清晰,分工明确。本章将详细解析 Runtime 端的各个核心模块。


二、YooAssets 静态入口

2.1 YooAssets 的概念

YooAssets 是 YooAsset 框架的全局静态入口,提供了统一的 API 让开发者与 YooAsset 进行交互。

YooAssets 的设计理念:

YooAssets 采用静态类设计,提供了全局唯一的入口点。开发者只需要调用 YooAssets 提供的静态方法就可以完成所有资源管理操作。

YooAssets 的特点:

  • 静态入口:全局唯一的静态类,便于调用
  • 统一 API:提供统一的 API 屏蔽内部实现
  • 多 Package 支持:支持同时管理多个 ResourcePackage

YooAssets 的 API 设计:

csharp 复制代码
public static class YooAssets
{
    public static ResourcePackage CreatePackage(string packageName);
    public static bool InitPackage(ResourcePackage package);
    public static void DestroyPackage(ResourcePackage package);
    public static ResourcePackage GetPackage(string packageName);
    public static void SetDefaultPackage(ResourcePackage package);
    public static ResourcePackage GetDefaultPackage();
}

2.2 YooAssets 的初始化流程

YooAssets 的初始化流程如下:

  1. 创建 YooAssets 设置:配置 YooAssetsSettings,包括文件服务器 URL、加密密钥等
  2. 创建 ResourcePackage:通过 YooAssets.CreatePackage 创建 ResourcePackage
  3. 初始化 ResourcePackage:通过 YooAssets.InitPackage 初始化 ResourcePackage
  4. 设置默认 Package:通过 YooAssets.SetDefaultPackage 设置默认 Package
  5. 开始使用资源:通过 ResourcePackage 加载资源

YooAssetsSettings 配置详解:

YooAssetsSettings 是 YooAssets 的全局配置,包括:

  • 文件服务器 URL:用于资源下载的服务器地址
  • 加密密钥:用于资源解密的密钥
  • 备用 URL:备用文件服务器地址
  • 超时设置:下载超时、连接超时等
  • 重试策略:下载失败时的重试策略

初始化参数详解:

csharp 复制代码
public class InitializeParameters
{
    public string LocationToLower;         // 地址转小写
    public string ScreenOrientation;        // 屏幕方向
    public AssetBundleDecryptionServices AssetBundleDecryptionServices; // 解密服务
    public IDeliveryQueryServices DeliveryQueryServices;     // 远端查询服务
    public IBuildinQueryServices BuildinQueryServices;        // 内置查询服务
    public IRemoteServices RemoteServices;                     // 远端服务
    public ICacheSystem CacheSystem;                          // 缓存系统
}

2.3 多 Package 架构

YooAssets 支持同时管理多个 ResourcePackage:

多 Package 的使用场景:

  • 游戏分包:将游戏分成多个 Package,便于热更新
  • DLC 支持:支持 DLC 的独立加载和更新
  • 模块化设计:支持游戏模块的独立加载

多 Package 的管理:

csharp 复制代码
// 创建多个 Package
var packageA = YooAssets.CreatePackage("PackageA");
var packageB = YooAssets.CreatePackage("PackageB");

// 初始化 Package
YooAssets.InitPackage(packageA);
YooAssets.InitPackage(packageB);

// 切换默认 Package
YooAssets.SetDefaultPackage(packageA);

// 加载资源
packageA.LoadAssetAsync<GameObject>("prefab_a");
packageB.LoadAssetAsync<GameObject>("prefab_b");

多 Package 的实现:

YooAssets 内部维护了一个 Dictionary<string, ResourcePackage>,用于管理所有 Package。每个 Package 都有自己的 Manifest、FileSystem 和 ResourceManager。


三、ResourcePackage 资源包

3.1 ResourcePackage 的概念

ResourcePackage 是 YooAsset 资源管理的核心抽象,封装了一组相关资源的加载、卸载和管理。

ResourcePackage 的设计理念:

ResourcePackage 抽象了"一个完整的资源包"的概念,包括资源的加载、卸载、缓存、热更新等所有功能。

ResourcePackage 的特点:

  • 封装性:封装了资源管理的所有细节
  • 独立性:每个 Package 独立管理自己的资源
  • 可配置性:Package 的配置可以独立修改

3.2 ResourcePackage 的组成

ResourcePackage 由以下核心组件组成:

arduino 复制代码
ResourcePackage 组成
├── PackageManifest:包清单,记录所有 Bundle 的信息
├── FileSystem:文件系统,负责跨平台文件访问
├── ResourceManager:资源管理器,负责资源加载和缓存
├── DownloadManager:下载管理器,负责资源下载
├── CacheSystem:缓存系统,负责缓存管理
└── Provider Pool:Provider 池,缓存已创建的 Provider

PackageManifest 详解:

PackageManifest 是 ResourcePackage 的清单文件,包含了所有 Bundle 的信息。ResourcePackage 通过 PackageManifest 来定位资源。

FileSystem 详解:

FileSystem 是 ResourcePackage 的文件系统,负责跨平台文件访问。YooAsset 通过 IFileSystem 抽象层屏蔽了不同平台的差异。

ResourceManager 详解:

ResourceManager 是 ResourcePackage 的资源管理器,负责资源加载、缓存和引用计数管理。

DownloadManager 详解:

DownloadManager 是 ResourcePackage 的下载管理器,负责资源下载和热更新。

CacheSystem 详解:

CacheSystem 是 ResourcePackage 的缓存系统,负责缓存管理和过期清理。

Provider Pool 详解:

Provider Pool 是 ResourcePackage 的 Provider 池,缓存已创建的 Provider,避免重复创建。

3.3 ResourcePackage 的生命周期

ResourcePackage 的生命周期如下:

  1. 创建:通过 YooAssets.CreatePackage 创建 Package
  2. 初始化:通过 YooAssets.InitPackage 初始化 Package
  3. 加载资源:通过 Package.LoadAssetAsync 加载资源
  4. 热更新:通过 UpdatePackageManifestAsync 进行热更新
  5. 销毁:通过 YooAssets.DestroyPackage 销毁 Package

创建详解:

Package 的创建只是创建一个内存对象,初始化必要的字段(如 PackageName)。实际的资源加载会在初始化阶段进行。

初始化详解:

Package 的初始化会进行以下操作:

  1. 加载 PackageManifest 文件
  2. 初始化 FileSystem
  3. 初始化 ResourceManager
  4. 初始化 DownloadManager
  5. 初始化 CacheSystem

加载资源详解:

Package 提供了多种资源加载方式:

  • LoadAssetAsync:异步加载资源
  • LoadSceneAsync:异步加载场景
  • LoadSubAssetsAsync:异步加载子资源
  • LoadAllAssetsAsync:异步加载所有资源

热更新详解:

Package 的热更新流程:

  1. 请求服务器 Manifest
  2. 与本地 Manifest 对比
  3. 下载差异 Bundle
  4. 切换到新版本

销毁详解:

Package 的销毁会进行以下操作:

  1. 卸载所有已加载资源
  2. 清空 Provider Pool
  3. 关闭 FileSystem
  4. 释放内存资源

四、ResourceManager 架构

4.1 ResourceManager 的概念

ResourceManager 是 YooAsset 的资源管理器,负责资源加载、缓存、引用计数等核心功能。

ResourceManager 的设计目标:

ResourceManager 旨在提供高效、灵活、可靠的资源管理能力。它是 Runtime 层的核心模块。

ResourceManager 的职责:

  • 资源加载:根据资源地址加载 AssetBundle 中的资源
  • 资源缓存:管理已加载资源的内存缓存
  • 引用计数:使用引用计数管理资源的引用关系
  • 依赖管理:管理资源之间的依赖关系
  • 资源释放:根据引用计数释放不再使用的资源

4.2 ResourceManager 的内部结构

ResourceManager 内部维护了多个重要的集合:

csharp 复制代码
public class ResourceManager
{
    // Provider 缓存
    private Dictionary<string, ProviderBase> _providerCache;
    
    // 加载中队列
    private List<ProviderOperation> _loadingQueue;
    
    // 加载完成列表
    private List<ProviderOperation> _loadingCompleted;
    
    // Bundle 加载器池
    private Dictionary<string, BundleLoader> _bundleLoaders;
}

Provider 缓存详解:

Provider 缓存用于存储已创建的 Provider 对象。当请求加载某个资源时,ResourceManager 会先在 Provider 缓存中查找是否已存在对应的 Provider。

加载中队列详解:

加载中队列用于管理正在加载的 Provider。当多个请求同时加载同一资源时,ResourceManager 会复用同一个 Provider。

加载完成列表详解:

加载完成列表用于在每帧结束时检查加载完成的 Provider,并触发回调通知。

Bundle 加载器池详解:

Bundle 加载器池用于管理已加载的 AssetBundle。Bundle 加载器通过引用计数管理 Bundle 的生命周期。

4.3 资源加载流程

ResourceManager 的资源加载流程如下:

  1. 接收资源加载请求:通过 Package.LoadAssetAsync 发起请求
  2. 查找 Provider:在 Provider 缓存中查找是否已存在对应的 Provider
  3. 创建 Provider:如果不存在,创建新的 Provider
  4. 将请求加入 Provider:将加载请求加入 Provider 的等待队列
  5. Provider 执行加载:Provider 开始执行实际的加载操作
  6. 触发回调通知:加载完成后触发回调通知

查找 Provider 详解:

查找 Provider 时使用资源地址作为 Key。ResourceManager 会先在缓存中查找,如果存在则复用,否则创建新的 Provider。

创建 Provider 详解:

创建 Provider 时会根据资源类型创建对应类型的 Provider。常见的 Provider 类型包括:

  • AssetProvider:普通资源 Provider
  • SceneProvider:场景资源 Provider
  • ComponentProvider:组件资源 Provider
  • RawAssetProvider:原生资源 Provider

加载请求处理详解:

Provider 使用引用计数管理加载请求。每次 LoadAsync 调用会增加引用计数,每次 Release 调用会减少引用计数。当引用计数为 0 时,Provider 会自动销毁。

4.4 引用计数机制

引用计数是 YooAsset 资源管理的核心机制:

引用计数的概念:

引用计数记录了资源被引用的次数。每次资源被引用时,引用计数加 1;每次资源被释放时,引用计数减 1。当引用计数为 0 时,资源会被卸载。

引用计数的实现:

csharp 复制代码
public abstract class ProviderOperation
{
    public int RefCount;  // 引用计数
    
    public void Acquire()
    {
        RefCount++;
        // 通知子依赖增加引用
    }
    
    public void Release()
    {
        RefCount--;
        if (RefCount <= 0)
        {
            // 销毁资源
        }
    }
}

引用计数的应用:

引用计数用于管理资源生命周期。当多个对象引用同一资源时,资源不会因为某个对象释放而被错误卸载。

引用计数的优点:

  • 避免内存泄漏:确保资源在不再使用时及时释放
  • 避免重复加载:相同资源只加载一次
  • 自动管理:自动管理资源的生命周期

引用计数的注意事项:

开发者必须严格遵守"Acquire-Release 配对"的原则,避免出现引用计数泄漏或重复释放。


五、Provider 体系

5.1 Provider 的概念

Provider 是 YooAsset 的资源提供者,封装了资源加载的具体逻辑。

Provider 的设计理念:

Provider 模式是 YooAsset 资源加载的核心设计模式。每个 Provider 对应一个资源,封装了资源的加载逻辑、状态管理和回调通知。

Provider 的特点:

  • 单一职责:每个 Provider 只负责一个资源的加载
  • 状态管理:Provider 维护了资源的加载状态
  • 回调通知:Provider 支持加载完成、失败等的回调通知
  • 引用计数:Provider 内置引用计数管理

5.2 Provider 类型

YooAsset 提供了多种 Provider 类型:

Provider 类型 用途 特点
AssetProvider 普通资源 最常用的 Provider
SceneProvider 场景资源 异步加载场景
SubAssetsProvider 子资源 加载包含多个资源的 AssetBundle 中的特定子资源
RawAssetProvider 原生资源 加载原生格式(图片、文本等)
BundleProvider Bundle 资源 加载整个 AssetBundle

AssetProvider 详解:

AssetProvider 是最常用的 Provider,用于加载普通资源(如 Prefab、Texture、Material 等)。它会加载包含资源的 AssetBundle,然后从 AssetBundle 中加载目标资源。

SceneProvider 详解:

SceneProvider 用于加载场景资源。它使用 Unity 的 SceneManager 进行异步场景加载,并管理场景的激活和卸载。

SubAssetsProvider 详解:

SubAssetsProvider 用于加载子资源。例如,一个 Sprite Atlas 包含多个 Sprite,可以使用 SubAssetsProvider 加载特定的 Sprite。

RawAssetProvider 详解:

RawAssetProvider 用于加载原生格式资源。它不会将资源转换为 Unity 对象,而是返回原始的字节数据。

5.3 Provider 的状态机

Provider 内部维护了一个状态机:

css 复制代码
Provider 状态机
├── None:初始状态
├── Loading:加载中
├── Checking:检查中
├── Success:加载成功
├── Failed:加载失败
└── Destroyed:已销毁

状态流转详解:

Provider 的状态流转如下:

  • None → Loading:开始加载
  • Loading → Checking:加载完成,进入检查阶段
  • Checking → Success:检查通过
  • Checking → Failed:检查失败
  • Success/Failed → Destroyed:资源被销毁

状态机的作用:

状态机确保 Provider 在正确的状态下执行正确的操作。例如,只有在 Loading 状态下才能处理加载进度更新,只有在 Success 状态下才能返回资源对象。


六、BundleLoader 体系

6.1 BundleLoader 的概念

BundleLoader 是 YooAsset 的 AssetBundle 加载器,负责加载和缓存 AssetBundle。

BundleLoader 的设计理念:

BundleLoader 抽象了 AssetBundle 的加载过程,提供了统一的接口。它管理 AssetBundle 的加载、缓存、引用计数和卸载。

BundleLoader 的特点:

  • 统一接口:提供统一的接口屏蔽不同平台的差异
  • 引用计数:使用引用计数管理 AssetBundle 的生命周期
  • 缓存机制:缓存已加载的 AssetBundle,避免重复加载
  • 异步加载:支持异步加载,避免阻塞主线程

6.2 BundleLoader 类型

YooAsset 提供了多种 BundleLoader 类型:

复制代码
BundleLoader 类型
├── AssetBundleLoader:标准 AssetBundle 加载器
├── RawBundleLoader:原生 Bundle 加载器
├── DecryptedBundleLoader:解密 Bundle 加载器
└── EncryptedBundleLoader:加密 Bundle 加载器

AssetBundleLoader 详解:

AssetBundleLoader 是标准的 AssetBundle 加载器,使用 Unity 的 AssetBundle.LoadFromFile 或 AssetBundle.LoadFromMemory 加载 AssetBundle。

DecryptedBundleLoader 详解:

DecryptedBundleLoader 是解密 Bundle 加载器,用于加载已解密的 AssetBundle。它会先解密数据,然后从解密后的数据加载 AssetBundle。

6.3 BundleLoader 的工作流程

BundleLoader 的工作流程如下:

  1. 接收加载请求:接收 AssetBundle 加载请求
  2. 检查缓存:检查是否已加载该 AssetBundle
  3. 执行加载:如果没有缓存,执行实际的加载操作
  4. 缓存 AssetBundle:将加载完成的 AssetBundle 缓存
  5. 管理引用计数:管理 AssetBundle 的引用计数
  6. 释放 AssetBundle:引用计数为 0 时释放 AssetBundle

检查缓存详解:

BundleLoader 维护了一个 AssetBundle 缓存字典。检查缓存时使用 Bundle 的路径或名称作为 Key。

执行加载详解:

执行加载时使用 Unity 的 AssetBundle 加载 API。具体的加载方式取决于 Bundle 的类型和位置。

引用计数管理详解:

BundleLoader 使用引用计数管理 AssetBundle 的生命周期。每个资源依赖一个 AssetBundle,资源的引用计数变化会影响 AssetBundle 的引用计数。


七、总结

本章深入解析了 YooAsset Runtime 端的系统架构,包括:

  • YooAssets 静态入口:全局统一的 API 入口
  • ResourcePackage 资源包:封装了一组相关资源的加载和管理
  • ResourceManager 资源管理器:负责资源加载、缓存和引用计数
  • Provider 资源提供者:封装了资源加载的具体逻辑
  • BundleLoader 体系:负责 AssetBundle 的加载和缓存

Runtime 端架构是 YooAsset 框架的核心,理解 Runtime 端架构是掌握 YooAsset 资源管理机制的关键。接下来的章节将分别深入解析文件系统、异步操作系统和资源下载器等核心组件。


上一篇 :Editor 端系统架构 下一篇 :文件系统架构(IFileSystem)

相关推荐
SmalBox1 小时前
03-02-架构篇-Editor打包系统架构
unity3d·游戏开发
Yeah1271 小时前
当 LLM 进入游戏玩法:从收权到放权
游戏开发
Behavior1 小时前
Unity 手游 iOS Deep Link 唤醒全流程:从 URL Scheme / Universal Links 到 C# 层参数投递
c#·unity3d·游戏开发
SmalBox1 小时前
03-01-架构篇-整体架构总览
unity3d·游戏开发
RobinDevNotes2 小时前
用 godot-rust 给 Godot 写 Rust 扩展
rust·游戏开发
SmalBox2 小时前
02-08-原理篇-异步加载与性能优化
unity3d·游戏开发
字节暗面2 小时前
Unity AssetBundle 热更新安全排查:从 CDN 清单到本地缓存
unity3d·图片资源
SmalBox6 天前
02-07-原理篇-文件系统与跨平台适配
unity3d·游戏开发
只睡四小时6 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas