Files
YooAssetScene/Assets/YooAsset/Runtime/ResourcePackage
..
2025-07-23 11:07:29 +08:00
2025-07-17 20:59:15 +08:00
2025-10-09 16:14:31 +08:00
2025-10-09 16:14:31 +08:00
2025-10-09 16:14:31 +08:00
2026-01-06 17:12:07 +08:00

ResourcePackage 资源包管理模块

模块概述

ResourcePackage 是 YooAsset 资源管理系统的核心模块,作为资源操作的统一入口,负责资源包的完整生命周期管理。该模块提供资源加载、清单管理、下载更新、缓存清理等核心功能。

核心特性

  • 统一入口:ResourcePackage 作为资源操作的门面,提供所有公开 API
  • 多模式支持:支持 Editor/Offline/Host/Web/Custom 五种运行模式
  • 高效查询:字典缓存实现 O(1) 资源定位
  • 异步优先:所有操作基于 AsyncOperationBase 异步框架
  • 灵活下载:支持按标签、按路径、按资源的多种下载方式

设计目标

目标 说明
统一门面 ResourcePackage 封装所有资源操作,简化使用复杂度
模式抽象 通过 IPlayMode 接口统一不同运行模式的行为
高效索引 清单初始化时构建多个字典,加速运行时查询
生命周期 完整管理包裹从创建到销毁的全过程

文件结构

ResourcePackage/
├── ResourcePackage.cs              # 包裹管理门面
├── PackageManifest.cs              # 资源清单
├── PackageAsset.cs                 # 资源元数据
├── PackageBundle.cs                # 资源包元数据
├── ManifestTools.cs                # 清单序列化工具
├── ManifestDefine.cs               # 清单常量定义
├── AssetInfo.cs                    # 资源信息(公开API)
├── BundleInfo.cs                   # 资源包信息(内部)
├── PackageDetail.cs                # 包裹详情
├── EBuildBundleType.cs             # 资源包类型枚举
├── EFileNameStyle.cs               # 文件名风格枚举
├── Interface/                      # 接口定义
│   ├── IPlayMode.cs                # 播放模式接口
│   └── IBundleQuery.cs             # 资源包查询接口
├── PlayMode/                       # 播放模式实现
│   ├── PlayModeImpl.cs             # 播放模式核心实现
│   └── EditorSimulateModeHelper.cs # 编辑器模拟辅助
└── Operation/                      # 操作类
    ├── InitializationOperation.cs  # 初始化操作
    ├── DestroyOperation.cs         # 销毁操作
    ├── RequestPackageVersionOperation.cs   # 请求版本
    ├── UpdatePackageManifestOperation.cs   # 更新清单
    ├── PreDownloadContentOperation.cs      # 预下载
    ├── ClearCacheFilesOperation.cs         # 清理缓存
    ├── DownloaderOperation.cs              # 下载操作基类
    └── Internal/
        └── DeserializeManifestOperation.cs # 清单反序列化

核心类说明

ResourcePackage

包裹管理门面类,提供所有资源操作的公开 API。

核心属性

属性 类型 说明
PackageName string 包裹唯一标识
InitializeStatus EOperationStatus 初始化状态
PackageValid bool 包裹是否有效(清单已加载)

生命周期方法

// 异步初始化包裹
InitializationOperation InitializeAsync(InitializeParameters parameters);

// 异步销毁包裹
DestroyOperation DestroyAsync();

清单操作方法

// 请求最新版本号
RequestPackageVersionOperation RequestPackageVersionAsync(
    bool appendTimeTicks = true, int timeout = 60);

// 更新资源清单
UpdatePackageManifestOperation UpdatePackageManifestAsync(
    string packageVersion, int timeout = 60);

// 预下载指定版本内容
PreDownloadContentOperation PreDownloadContentAsync(
    string packageVersion, int timeout = 60);

// 获取包裹版本
string GetPackageVersion();

// 获取包裹详细信息
PackageDetails GetPackageDetails();

资源加载方法(5种模式)

// 1. 加载单个资源
AssetHandle LoadAssetSync<T>(string location);
AssetHandle LoadAssetAsync<T>(string location);
AssetHandle LoadAssetAsync<T>(AssetInfo assetInfo);

// 2. 加载子资源
SubAssetsHandle LoadSubAssetsSync<T>(string location);
SubAssetsHandle LoadSubAssetsAsync<T>(string location);

// 3. 加载资源包内全部资源
AllAssetsHandle LoadAllAssetsSync<T>(string location);
AllAssetsHandle LoadAllAssetsAsync<T>(string location);

// 4. 加载场景
SceneHandle LoadSceneSync(string location, LoadSceneMode sceneMode);
SceneHandle LoadSceneAsync(string location, LoadSceneMode sceneMode);

// 5. 加载原生文件
RawFileHandle LoadRawFileSync(string location);
RawFileHandle LoadRawFileAsync(string location);

资源信息查询方法

// 按定位地址获取资源信息
AssetInfo GetAssetInfo(string location);

// 按 GUID 获取资源信息
AssetInfo GetAssetInfoByGUID(string assetGUID);

// 按标签获取资源信息列表
AssetInfo[] GetAssetInfos(string tag);
AssetInfo[] GetAssetInfos(string[] tags);

// 获取全部资源信息
AssetInfo[] GetAllAssetInfos();

// 验证定位地址有效性
bool CheckLocationValid(string location);

// 检查是否需要从远端下载
bool IsNeedDownloadFromRemote(string location);
bool IsNeedDownloadFromRemote(AssetInfo assetInfo);

下载器创建方法(4种模式)

// 下载全部需要下载的资源
ResourceDownloaderOperation CreateResourceDownloader(
    int downloadingMaxNumber, int failedTryAgain);

// 按标签下载
ResourceDownloaderOperation CreateResourceDownloader(
    string tag, int downloadingMaxNumber, int failedTryAgain);
ResourceDownloaderOperation CreateResourceDownloader(
    string[] tags, int downloadingMaxNumber, int failedTryAgain);

// 按资源路径下载
ResourceDownloaderOperation CreateBundleDownloader(
    string location, int downloadingMaxNumber, int failedTryAgain);
ResourceDownloaderOperation CreateBundleDownloader(
    string[] locations, int downloadingMaxNumber, int failedTryAgain);

// 按 AssetInfo 下载
ResourceDownloaderOperation CreateBundleDownloader(
    AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain);

解压器创建方法

// 解压全部需要解压的资源
ResourceUnpackerOperation CreateResourceUnpacker(
    int unpackingMaxNumber, int failedTryAgain);

// 按标签解压
ResourceUnpackerOperation CreateResourceUnpacker(
    string tag, int unpackingMaxNumber, int failedTryAgain);
ResourceUnpackerOperation CreateResourceUnpacker(
    string[] tags, int unpackingMaxNumber, int failedTryAgain);

导入器创建方法

// 按文件路径导入
ResourceImporterOperation CreateResourceImporter(
    string[] filePaths, int importerMaxNumber, int failedTryAgain);

// 按导入信息导入
ResourceImporterOperation CreateResourceImporter(
    ImportFileInfo[] fileInfos, int importerMaxNumber, int failedTryAgain);

缓存清理方法

// 清理缓存文件
ClearCacheFilesOperation ClearCacheFilesAsync(EFileClearMode clearMode);
ClearCacheFilesOperation ClearCacheFilesAsync(string clearMode, object clearParam);

资源卸载方法

// 强制卸载全部资源
UnloadAllAssetsOperation UnloadAllAssetsAsync();

// 卸载未使用的资源
UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync(int loopCount = 100);

// 尝试卸载指定资源
bool TryUnloadUnusedAsset(string location);
bool TryUnloadUnusedAsset(AssetInfo assetInfo);

清单系统

PackageManifest

资源清单文件,存储资源和资源包的元数据,是资源查询的数据库。

配置信息

属性 类型 说明
FileVersion string 清单文件格式版本
EnableAddressable bool 启用可寻址定位
SupportExtensionless bool 支持无扩展名寻址
LocationToLower bool 定位地址大小写不敏感
IncludeAssetGUID bool 包含资源 GUID
ReplaceAssetPathWithAddress bool 用 Address 替换 AssetPath
OutputNameStyle int 文件名样式
BuildBundleType int 构建资源包类型
BuildPipeline string 构建管线名称

包裹信息

属性 类型 说明
PackageName string 包裹名称
PackageVersion string 包裹版本
PackageNote string 包裹备注

核心数据

属性 类型 说明
AssetList List<PackageAsset> 主资源列表
BundleList List<PackageBundle> 资源包列表

运行时字典(初始化时构建)

字典 键 值 说明
AssetDic AssetPath PackageAsset 资源路径查询
AssetPathMapping1 Location AssetPath 定位地址→资源路径
AssetPathMapping2 AssetGUID AssetPath GUID→资源路径
BundleDic1 BundleName PackageBundle 按名称查询
BundleDic2 FileName PackageBundle 按文件名查询
BundleDic3 BundleGUID PackageBundle 按 GUID 查询

查询方法

// 定位地址转换
bool TryMappingToAssetPath(string location, out string assetPath);

// 资源查询
bool TryGetPackageAsset(string assetPath, out PackageAsset result);

// 资源包查询(3种方式)
bool TryGetPackageBundleByBundleName(string bundleName, out PackageBundle result);
bool TryGetPackageBundleByFileName(string fileName, out PackageBundle result);
bool TryGetPackageBundleByBundleGUID(string bundleGUID, out PackageBundle result);

// 获取资源主包
PackageBundle GetMainPackageBundle(AssetInfo assetInfo);

// 获取资源依赖包
PackageBundle[] GetAssetAllDependencies(PackageAsset asset);

// 获取资源包依赖
PackageBundle[] GetBundleAllDependencies(PackageBundle bundle);

// 定位地址转 AssetInfo
AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType);

// GUID 转 AssetInfo
AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType);

// 按标签获取资源
AssetInfo[] GetAssetInfosByTags(string[] tags);

// 检查资源包是否在清单中
bool IsIncludeBundleFile(string bundleGUID);

PackageAsset

单个资源的元数据(可序列化)。

public class PackageAsset
{
    public string Address;              // 可寻址地址
    public string AssetPath;            // 资源路径 (Assets/...)
    public string AssetGUID;            // 资源 GUID
    public string[] AssetTags;          // 分类标签
    public int BundleID;                // 所属资源包 ID(索引)
    public int[] DependBundleIDs;       // 依赖资源包 ID 数组

    // 检查是否包含指定标签
    public bool HasTag(string[] tags);
}

PackageBundle

资源包的元数据(可序列化)。

public class PackageBundle
{
    // 基础信息
    public string BundleName;           // 资源包名称
    public string BundleGUID { get; }   // GUID(= FileHash)
    public uint UnityCRC;               // Unity 生成的 CRC
    public string FileHash;             // 文件哈希值
    public uint FileCRC;                // 文件 CRC 校验码
    public long FileSize;               // 文件大小(字节)
    public bool Encrypted;              // 是否加密

    // 分类和依赖
    public string[] Tags;               // 资源包分类标签
    public int[] DependBundleIDs;       // 依赖资源包 ID(引擎层)

    // 运行时属性
    public int BundleType { get; }      // 资源包类型
    public string FileName { get; }     // 远端文件名
    public string FileExtension { get; } // 文件扩展名

    // 运行时列表
    public List<PackageAsset> IncludeMainAssets;   // 包含的主资源
    public List<int> ReferenceBundleIDs;           // 引用此包的 ID 列表

    // 检查是否包含标签
    public bool HasTag(string[] tags);
    public bool HasAnyTags();

    // 对比相等性(基于 FileHash)
    public bool Equals(PackageBundle otherBundle);
}

ManifestTools

清单序列化工具类。

// 验证清单数据完整性
static bool VerifyManifestData(byte[] fileData, string hashValue);

// 序列化
static string SerializeToJson(PackageManifest manifest);
static byte[] SerializeToBinary(PackageManifest manifest);

// 反序列化
static PackageManifest DeserializeFromJson(string jsonContent);
static PackageManifest DeserializeFromBinary(byte[] binaryData);

// 文件命名
static string GetRemoteBundleFileExtension(string bundleName);
static string GetRemoteBundleFileName(OutputNameStyle style, ...);

ManifestDefine

清单常量定义。

public class ManifestDefine
{
    public const int FileMaxSize = 104857600;           // 100MB
    public const uint FileSign = 0x594F4F;              // "YOO" 标记
    public const string FileVersion = "2025.9.30";      // 当前版本
    public const string VERSION_2025_8_28 = "2025.8.28";
    public const string VERSION_2025_9_30 = "2025.9.30";
    public const bool BackwardCompatible = true;        // 向后兼容
}

运行模式系统

IPlayMode 接口

定义不同运行模式的统一接口。

public interface IPlayMode
{
    // 当前活跃的清单
    PackageManifest ActiveManifest { set; get; }

    // 销毁文件系统
    void DestroyFileSystem();

    // 版本和清单操作
    RequestPackageVersionOperation RequestPackageVersionAsync(...);
    UpdatePackageManifestOperation UpdatePackageManifestAsync(...);
    PreDownloadContentOperation PreDownloadContentAsync(...);
    ClearCacheFilesOperation ClearCacheFilesAsync(...);

    // 下载器创建
    ResourceDownloaderOperation CreateResourceDownloaderByAll(...);
    ResourceDownloaderOperation CreateResourceDownloaderByTags(...);
    ResourceDownloaderOperation CreateResourceDownloaderByPaths(...);

    // 解压器创建
    ResourceUnpackerOperation CreateResourceUnpackerByAll(...);
    ResourceUnpackerOperation CreateResourceUnpackerByTags(...);

    // 导入器创建
    ResourceImporterOperation CreateResourceImporterByFilePaths(...);
    ResourceImporterOperation CreateResourceImporterByFileInfos(...);
}

PlayModeImpl

播放模式核心实现,同时实现 IPlayMode 和 IBundleQuery 接口。

核心属性

public class PlayModeImpl : IPlayMode, IBundleQuery
{
    public readonly string PackageName;
    public readonly EPlayMode PlayMode;
    public readonly List<IFileSystem> FileSystems = new List<IFileSystem>(10);
    public PackageManifest ActiveManifest { set; get; }
}

文件系统管理

// 获取主文件系统(列表最后一个)
public IFileSystem GetMainFileSystem();

// 获取资源包所属的文件系统
public IFileSystem GetBelongFileSystem(PackageBundle bundle);

IBundleQuery 实现

// 获取主资源包信息
BundleInfo GetMainBundleInfo(AssetInfo assetInfo);

// 获取依赖资源包信息
BundleInfo[] GetDependBundleInfos(AssetInfo assetInfo);

// 获取资源包名称
string GetMainBundleName(int bundleID);

下载/解压/导入列表生成

// 生成全部下载列表
List<BundleInfo> GetDownloadListByAll(PackageManifest manifest);

// 按标签筛选下载列表
List<BundleInfo> GetDownloadListByTags(PackageManifest manifest, string[] tags);

// 按资源路径筛选下载列表
List<BundleInfo> GetDownloadListByPaths(PackageManifest manifest, string[] locations);

// 解压列表
List<BundleInfo> GetUnpackListByAll(PackageManifest manifest);
List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags);

// 导入列表
List<BundleInfo> GetImporterListByFilePaths(...);
List<BundleInfo> GetImporterListByFileInfos(...);

五种运行模式

模式 说明 文件系统
EditorSimulateMode 编辑器模拟模式 DefaultEditorFileSystem
OfflinePlayMode 单机运行模式 DefaultBuildinFileSystem
HostPlayMode 联机运行模式 Buildin + Cache
WebPlayMode WebGL 运行模式 WebServer + WebRemote
CustomPlayMode 自定义模式 用户自定义

文件系统优先级

FileSystems[0] → FileSystems[1] → ... → FileSystems[N] (主文件系统)
              ↓                              ↓
         编辑器或内置资源          远端或缓存资源

操作类系统

InitializationOperation

初始化操作,管理包裹的初始化流程。

状态流程:
Prepare
    ↓
ClearOldFileSystem
    └── 清理旧的文件系统(如果存在)
            ↓
InitFileSystem
    └── 逐个初始化 FileSystems
            ├── FileSystem[0].InitializeFileSystemAsync()
            ├── FileSystem[1].InitializeFileSystemAsync()
            └── ...
                    ↓
CheckInitResult
    └── 检查所有文件系统初始化结果
            ├── 任一失败 → Status = Failed
            └── 全部成功 → Status = Succeed
                    ↓
Done

DestroyOperation

销毁操作,管理包裹的销毁流程。

状态流程:
CheckInitStatus
    ├── 初始化中 → Status = Failed(不允许销毁)
    └── 其他状态 → 继续
            ↓
UnloadAllAssets
    └── 如果初始化成功,卸载所有资源
            ↓
DestroyPackage
    ├── 销毁包裹
    └── OperationSystem.ClearPackageOperation()
            ↓
Done → Status = Succeed

RequestPackageVersionOperation

请求版本操作,获取远端最新版本号。

状态流程:
RequestPackageVersion
    └── 委托给主文件系统
            └── FileSystem.RequestPackageVersionAsync()
                    ├── 成功 → PackageVersion = 版本号
                    └── 失败 → Error
                            ↓
Done

UpdatePackageManifestOperation

更新清单操作,加载指定版本的清单。

状态流程:
CheckParams
    └── 验证参数有效性
            ↓
CheckActiveManifest
    └── 检查当前清单版本
            ├── 版本匹配 → 直接成功(复用)
            └── 版本不匹配 → 继续加载
                    ↓
LoadPackageManifest
    └── 主文件系统加载清单
            └── FileSystem.LoadPackageManifestAsync()
                    ├── 成功 → Manifest = 新清单
                    └── 失败 → Error
                            ↓
Done

PreDownloadContentOperation

预下载操作,预加载指定版本的清单并支持创建下载器。

状态流程:
CheckParams
    └── 验证参数有效性
            ↓
CheckActiveManifest
    └── 检查是否已有相同版本清单
            ├── 有 → 复用清单
            └── 无 → 继续加载
                    ↓
LoadPackageManifest
    └── 加载指定版本清单
            ├── 成功 → 可创建下载器
            └── 失败 → Error
                    ↓
Done

预下载后创建下载器

// 下载全部
CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain);

// 按标签下载
CreateResourceDownloader(string tag, ...);
CreateResourceDownloader(string[] tags, ...);

// 按资源路径下载
CreateResourceDownloader(string[] locations, ...);

ClearCacheFilesOperation

缓存清理操作,清理指定的缓存文件。

状态流程:
Prepare
    └── 准备清理任务
            ↓
ClearCacheFiles
    └── 逐个文件系统清理
            └── FileSystem.ClearCacheFilesAsync(options)
                    ↓
CheckClearResult
    └── 检查清理结果
            ├── 任一失败 → Status = Failed
            └── 全部成功 → Status = Succeed
                    ↓
Done

DownloaderOperation

下载操作基类,管理并发下载任务。

核心属性

public abstract class DownloaderOperation : AsyncOperationBase
{
    // 下载统计
    public int TotalDownloadCount { get; }      // 总下载数
    public long TotalDownloadBytes { get; }     // 总大小(字节)
    public int CurrentDownloadCount { get; }    // 已完成数
    public long CurrentDownloadBytes { get; }   // 已完成大小
    public float Progress { get; }              // 进度 0.0~1.0

    // 并发控制
    protected const int MAX_LOADER_COUNT = 64;  // 最大同时下载数
}

回调委托

// 下载完成回调
public DownloadFinishDelegate DownloadFinishCallback;

// 进度更新回调
public DownloadUpdateDelegate DownloadUpdateCallback;

// 下载错误回调
public DownloadErrorDelegate DownloadErrorCallback;

// 开始下载文件回调
public DownloadFileBeginDelegate DownloadFileBeginCallback;

状态流程

Check
    └── 检查下载列表是否为空
            ├── 为空 → 直接成功
            └── 不为空 → 开始下载
                    ↓
Loading
    ├── 检测已完成的下载器
    ├── 移除完成的下载器
    ├── 更新进度回调
    ├── 创建新下载器(≤ MAX_LOADER_COUNT)
    └── 处理失败重试
            ↓
Done

子类

类 说明
ResourceDownloaderOperation 资源下载器
ResourceUnpackerOperation 资源解压器
ResourceImporterOperation 资源导入器

DeserializeManifestOperation

清单反序列化操作,从二进制数据反序列化清单。

状态流程:
RestoreFileData
    └── 调用插件还原数据(如果有)
            ↓
DeserializeFileHeader
    └── 读取文件头
            ├── 验证 FileSign (0x594F4F)
            └── 检查 FileVersion 兼容性
                    ↓
PrepareAssetList
    └── 读取资源数量
            ↓
DeserializeAssetList(时间切片)
    └── 逐个反序列化资源
            ↓
PrepareBundleList
    └── 读取资源包数量
            ↓
DeserializeBundleList(时间切片)
    └── 逐个反序列化资源包
            ↓
InitManifest
    └── 初始化清单(构建字典)
            ↓
Done → Manifest

辅助类说明

AssetInfo

资源信息包装类(公开 API)。

public class AssetInfo
{
    // 公开属性
    public string PackageName { get; }      // 所属包裹
    public System.Type AssetType { get; }   // 资源类型
    public string Error { get; }            // 错误信息
    public bool IsInvalid { get; }          // 身份是否无效
    public string Address { get; }          // 可寻址地址
    public string AssetPath { get; }        // 资源路径

    // 内部属性
    internal ELoadMethod LoadMethod;        // 加载方法
    internal string GUID { get; }           // 唯一标识符
    internal PackageAsset Asset { get; }    // 内部对象
}

BundleInfo

资源包信息(内部使用)。

public class BundleInfo
{
    private readonly IFileSystem _fileSystem;
    public readonly PackageBundle Bundle;

    // 加载资源包
    public FSLoadBundleOperation LoadBundleFile();

    // 创建下载器
    public FSDownloadFileOperation CreateDownloader(int failedTryAgain);

    // 检查是否需要下载
    public bool IsNeedDownloadFromRemote();

    // 生成唯一标识(用于去重)
    public string GetDownloadCombineGUID();
}

PackageDetails

包裹详细信息(公开 API)。

public class PackageDetails
{
    public string FileVersion;
    public bool EnableAddressable;
    public bool SupportExtensionless;
    public bool LocationToLower;
    public bool IncludeAssetGUID;
    public bool ReplaceAssetPathWithAddress;
    public int OutputNameStyle;
    public int BuildBundleType;
    public string BuildPipeline;
    public string PackageName;
    public string PackageVersion;
    public string PackageNote;
    public int AssetTotalCount;     // 主资源总数
    public int BundleTotalCount;    // 资源包总数
}

枚举定义

EBuildBundleType

资源包类型枚举。

public enum EBuildBundleType
{
    Unknown = 0,        // 未知(默认)
    VirtualBundle = 1,  // 虚拟包(编辑器模拟)
    AssetBundle = 2,    // Unity AssetBundle
    RawBundle = 3,      // 原生文件(未压缩)
    InstantBundle = 4,  // Unity China InstantBundle
}

EFileNameStyle

文件名命名风格枚举。

public enum EFileNameStyle
{
    HashName = 0,               // "abc123def456.bundle"
    BundleName = 1,             // "assets_ui.bundle"
    BundleName_HashName = 2,    // "assets_ui_abc123def456.bundle"
}

ELoadMethod

资源加载方法枚举(内部)。

internal enum ELoadMethod
{
    None = 0,
    LoadAsset,        // 加载单个资源
    LoadSubAssets,    // 加载子资源
    LoadAllAssets,    // 加载资源包内全部
    LoadScene,        // 加载场景
    LoadRawFile,      // 加载原生文件
}

关键工作流

初始化流程

1. YooAssets.CreatePackage(packageName)
   └── new ResourcePackage(packageName)

2. package.InitializeAsync(parameters)
   ├── CheckInitializeParameters()
   ├── new ResourceManager()
   ├── new PlayModeImpl()
   ├── new InitializationOperation()
   └── OperationSystem.StartOperation()

3. InitializationOperation 逐个初始化 FileSystem
   ├── DefaultEditorFileSystem(编辑器模拟)
   ├── DefaultBuildinFileSystem(StreamingAssets)
   ├── DefaultCacheFileSystem(已缓存资源)
   └── DefaultWebServerFileSystem(WebGL)

4. PlayModeImpl.ActiveManifest = fileSystem.LoadPackageManifest()
   └── 清单反序列化并初始化

资源加载流程

package.LoadAssetAsync<T>(location)
    │
    ├── ConvertLocationToAssetInfo(location)
    │   └── PlayModeImpl.ActiveManifest.ConvertLocationToAssetInfo()
    │       └── AssetPathMapping1[location] → AssetPath
    │           └── AssetDic[assetPath] → PackageAsset
    │
    ├── ResourceManager.LoadAssetAsync(assetInfo)
    │   ├── ProviderDic 查询或创建 Provider
    │   ├── Provider.StartBundleLoader()
    │   │   ├── GetMainBundleInfo() → BundleInfo
    │   │   └── GetDependBundleInfos() → List<BundleInfo>
    │   │
    │   └── 并发加载 AssetBundle
    │       ├── PlayModeImpl.GetBelongFileSystem()
    │       └── IFileSystem.LoadBundleFile()
    │
    └── return AssetHandle

清单更新流程

package.RequestPackageVersionAsync()
    └── PlayModeImpl.GetMainFileSystem().RequestPackageVersionAsync()
            │
            ▼
package.UpdatePackageManifestAsync(version)
    ├── 检查 ActiveManifest 版本是否已匹配
    └── PlayModeImpl.GetMainFileSystem().LoadPackageManifestAsync(version)
        └── ManifestTools.DeserializeFromBinary()
            └── DeserializeManifestOperation(逐个反序列化资源包)

下载流程

downloader = package.CreateResourceDownloader(...)
    └── PlayModeImpl.GetDownloadListByXXX()
        ├── 遍历清单的 BundleList
        ├── GetBelongFileSystem(bundle)
        └── fileSystem.NeedDownload(bundle)
                │
                ▼
downloader.BeginDownload()
    └── DownloaderOperation.InternalUpdate()
        ├── 创建 ≤ MAX_LOADER_COUNT 个 FSDownloadFileOperation
        ├── fileSystem.DownloadFileAsync(bundle, options)
        ├── 更新进度和回调
        └── 失败文件进入重试列表

类继承关系

AsyncOperationBase
├── InitializationOperation
├── DestroyOperation
├── RequestPackageVersionOperation
│   └── RequestPackageVersionImplOperation
├── UpdatePackageManifestOperation
├── PreDownloadContentOperation
├── ClearCacheFilesOperation
├── DownloaderOperation (abstract)
│   ├── ResourceDownloaderOperation
│   ├── ResourceUnpackerOperation
│   └── ResourceImporterOperation
└── DeserializeManifestOperation

IPlayMode
└── PlayModeImpl (also implements IBundleQuery)

PackageManifest
├── List<PackageAsset> AssetList
└── List<PackageBundle> BundleList

使用示例

初始化包裹(联机模式)

// 创建包裹
var package = YooAssets.CreatePackage("DefaultPackage");

// 创建内置文件系统参数
var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();

// 创建缓存文件系统参数
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(
    remoteServices: new GameRemoteServices()
);

// 创建联机模式初始化参数
var initParams = new HostPlayModeParameters();
initParams.BuildinFileSystemParameters = buildinParams;
initParams.CacheFileSystemParameters = cacheParams;

// 异步初始化
var initOp = package.InitializeAsync(initParams);
await initOp.ToTask();

if (initOp.Status == EOperationStatus.Succeed)
{
    Debug.Log("包裹初始化成功!");
}

更新清单

// 请求最新版本
var versionOp = package.RequestPackageVersionAsync();
await versionOp.ToTask();

if (versionOp.Status != EOperationStatus.Succeed)
{
    Debug.LogError($"请求版本失败:{versionOp.Error}");
    return;
}

string packageVersion = versionOp.PackageVersion;
Debug.Log($"最新版本:{packageVersion}");

// 更新清单
var updateOp = package.UpdatePackageManifestAsync(packageVersion);
await updateOp.ToTask();

if (updateOp.Status == EOperationStatus.Succeed)
{
    Debug.Log("清单更新成功!");
}

下载资源

// 创建下载器(最多10个并发,失败重试3次)
var downloader = package.CreateResourceDownloader(10, 3);

if (downloader.TotalDownloadCount == 0)
{
    Debug.Log("没有需要下载的资源");
    return;
}

Debug.Log($"需要下载 {downloader.TotalDownloadCount} 个文件," +
          $"总大小 {downloader.TotalDownloadBytes / 1024 / 1024}MB");

// 注册回调
downloader.DownloadUpdateCallback = (info) =>
{
    Debug.Log($"下载进度:{info.Progress * 100:F1}%");
};

downloader.DownloadErrorCallback = (info) =>
{
    Debug.LogError($"下载错误:{info.FileName} - {info.Error}");
};

// 开始下载
downloader.BeginDownload();
await downloader.ToTask();

if (downloader.Status == EOperationStatus.Succeed)
{
    Debug.Log("下载完成!");
}

按标签下载

// 按单个标签下载
var downloader = package.CreateResourceDownloader("level1", 10, 3);

// 按多个标签下载
var downloader = package.CreateResourceDownloader(
    new string[] { "level1", "level2" }, 10, 3);

downloader.BeginDownload();
await downloader.ToTask();

加载资源

// 异步加载预制体
var handle = package.LoadAssetAsync<GameObject>("Assets/Prefabs/Player.prefab");
await handle.ToTask();

if (handle.Status == EOperationStatus.Succeed)
{
    var prefab = handle.AssetObject as GameObject;
    var player = GameObject.Instantiate(prefab);

    // 使用完毕后释放
    // handle.Release();
}
else
{
    Debug.LogError($"加载失败:{handle.LastError}");
}

加载场景

// 异步加载场景(叠加模式)
var handle = package.LoadSceneAsync("Assets/Scenes/GameScene.unity", LoadSceneMode.Additive);
await handle.ToTask();

if (handle.Status == EOperationStatus.Succeed)
{
    Debug.Log("场景加载成功!");
}

预下载指定版本

// 预下载特定版本
var predownloadOp = package.PreDownloadContentAsync("1.0.5");
await predownloadOp.ToTask();

if (predownloadOp.Status == EOperationStatus.Succeed)
{
    // 创建下载器
    var downloader = predownloadOp.CreateResourceDownloader(10, 3);
    downloader.BeginDownload();
    await downloader.ToTask();
}

清理缓存

// 清理所有缓存
var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearAllBundleFiles);
await clearOp.ToTask();

// 清理未使用的缓存
var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearUnusedBundleFiles);
await clearOp.ToTask();

// 按标签清理
var clearOp = package.ClearCacheFilesAsync(
    EFileClearMode.ClearBundleFilesByTags.ToString(), "dlc_old");
await clearOp.ToTask();

卸载资源

// 卸载未使用的资源
var unloadOp = package.UnloadUnusedAssetsAsync();
await unloadOp.ToTask();

// 强制卸载全部资源
var unloadOp = package.UnloadAllAssetsAsync();
await unloadOp.ToTask();

注意事项

  1. 初始化顺序:必须先初始化包裹才能进行其他操作
  2. 清单更新:建议在更新清单前调用 UnloadAllAssetsAsync() 释放已加载资源
  3. 资源释放:使用后必须调用 Handle.Release() 避免内存泄漏
  4. 并发限制:下载器最大并发数为 64,建议根据网络环境合理设置
  5. 版本兼容:清单文件版本需 >= 2025.8.28
  6. 异常处理:操作失败时检查 Status 和 Error 属性
  7. 线程安全:所有核心逻辑在 Unity 主线程执行,无需额外同步