源码-全局入口与资源包(YooAssets & ResourcePackage)
篇章 :05-源码深度-运行时核心模块 阅读时间 :约 30 分钟 前置知识:了解运行时总览
一、引言
本章将深入解析 YooAsset 全局入口(YooAssets)与资源包(ResourcePackage)的源码实现。YooAssets 是 YooAsset 的全局静态入口,ResourcePackage 是资源管理的核心抽象。深入理解这两个类的实现,是掌握 YooAsset 资源管理的关键。
YooAssets 和 ResourcePackage 的设计体现了 YooAsset 的核心理念:清晰的职责划分、灵活的扩展能力、统一的 API 接口。本章将从源码层面深入解析这两个类的实现。
二、YooAssets 全局入口
2.1 YooAssets 的设计
YooAssets 是 YooAsset 的全局静态入口类:
csharp
public static class YooAssets
{
private static GameObject _operationUpdaterGo;
private static readonly Dictionary<string, ResourcePackage> _packages = new Dictionary<string, ResourcePackage>();
private static ResourcePackage _defaultPackage;
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();
}
核心字段详解:
- _operationUpdaterGo:异步操作更新器的 GameObject
- _packages:所有 Package 的字典
- _defaultPackage:默认 Package
核心方法详解:
- CreatePackage:创建 Package
- InitPackage:初始化 Package
- DestroyPackage:销毁 Package
- GetPackage:获取 Package
- SetDefaultPackage:设置默认 Package
- GetDefaultPackage:获取默认 Package
2.2 YooAssets.CreatePackage
CreatePackage 方法创建 ResourcePackage:
csharp
public static ResourcePackage CreatePackage(string packageName)
{
if (_packages.ContainsKey(packageName))
{
Debug.LogError($"Package {packageName} already exists!");
return _packages[packageName];
}
ResourcePackage package = new ResourcePackage(packageName);
_packages.Add(packageName, package);
return package;
}
重复创建保护详解:
CreatePackage 会检查是否已存在同名 Package,避免重复创建。
返回值详解:
CreatePackage 返回创建的 ResourcePackage 对象,开发者可以继续初始化。
2.3 YooAssets.InitPackage
InitPackage 方法初始化 ResourcePackage:
csharp
public static bool InitPackage(ResourcePackage package)
{
// 1. 启动 OperationUpdater
if (_operationUpdaterGo == null)
{
_operationUpdaterGo = new GameObject("YooAssetOperationUpdater");
_operationUpdaterGo.AddComponent<OperationUpdater>();
UnityEngine.Object.DontDestroyOnLoad(_operationUpdaterGo);
}
// 2. 异步初始化 Package
var operation = package.InitializeAsync();
operation.Completed += (op) => {
if (op.Status == EOperationStatus.Succeed)
{
Debug.Log($"Package {package.PackageName} initialized successfully");
}
};
return true;
}
OperationUpdater 启动详解:
InitPackage 会确保 OperationUpdater GameObject 存在。OperationUpdater 负责在每帧更新异步操作。
异步初始化详解:
InitPackage 调用 package.InitializeAsync() 进行异步初始化。
完成回调详解:
初始化完成时,会触发回调通知,开发者可以监听此回调。
2.4 YooAssets.DestroyPackage
DestroyPackage 方法销毁 ResourcePackage:
csharp
public static void DestroyPackage(ResourcePackage package)
{
if (package == null) return;
// 1. 销毁 Package
package.Destroy();
// 2. 从字典中移除
_packages.Remove(package.PackageName);
// 3. 如果是默认 Package,清空默认 Package
if (_defaultPackage == package)
{
_defaultPackage = null;
}
}
销毁顺序详解:
DestroyPackage 先销毁 Package,然后从字典中移除,最后清理默认 Package 引用。
注意事项详解:
DestroyPackage 是同步操作,会立即销毁 Package。开发者需要确保在销毁前没有正在进行的资源加载。
2.5 YooAssets 的辅助方法
csharp
public static ResourcePackage GetPackage(string packageName)
{
if (_packages.TryGetValue(packageName, out var package))
return package;
return null;
}
public static void SetDefaultPackage(ResourcePackage package)
{
_defaultPackage = package;
}
public static ResourcePackage GetDefaultPackage()
{
return _defaultPackage;
}
GetPackage 详解:
通过 packageName 获取 Package。
SetDefaultPackage 详解:
设置默认 Package。设置后,可以通过 ResourcePackage.DefaultPackage 加载资源。
三、ResourcePackage 资源包
3.1 ResourcePackage 的设计
ResourcePackage 是 YooAsset 资源管理的核心抽象:
csharp
public class ResourcePackage
{
public string PackageName { get; private set; }
public PackageManifest Manifest { get; private set; }
public IFileSystem BuildinFileSystem { get; private set; }
public IFileSystem CacheFileSystem { get; private set; }
public IFileSystem DeliveryFileSystem { get; private set; }
public IPlayModeImpl PlayModeImpl { get; private set; }
public ResourceManager ResourceManager { get; private set; }
public DownloadManager DownloadManager { get; private set; }
public CacheSystem CacheSystem { get; private set; }
public InitializationOperation InitializeAsync(IBuildinQueryServices buildinQueryServices, IDeliveryQueryServices deliveryQueryServices);
public UpdatePackageVersionOperation UpdatePackageVersionAsync();
public UpdatePackageManifestOperation UpdatePackageManifestAsync();
public AssetOperationHandle LoadAssetAsync<T>(string location);
public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode);
public void UnloadAsset(AssetOperationHandle handle);
public void Destroy();
}
核心字段详解:
- PackageName:Package 名称
- Manifest:Package 清单
- BuildinFileSystem:构建内文件系统
- CacheFileSystem:缓存文件系统
- DeliveryFileSystem:远程文件系统
- PlayModeImpl:运行模式实现
- ResourceManager:资源管理器
- DownloadManager:下载管理器
- CacheSystem:缓存系统
3.2 ResourcePackage 初始化
ResourcePackage 初始化是 YooAsset 的核心流程:
csharp
public InitializationOperation InitializeAsync(
IBuildinQueryServices buildinQueryServices = null,
IDeliveryQueryServices deliveryQueryServices = null)
{
// 1. 加载 Manifest
var loadManifestOp = LoadManifest();
loadManifestOp.Completed += (op) => {
if (op.Status == EOperationStatus.Succeed)
{
// 2. 初始化 FileSystem
InitFileSystems(buildinQueryServices, deliveryQueryServices);
// 3. 初始化 PlayMode
InitPlayMode();
// 4. 初始化 Manager
InitManagers();
}
};
return initializationOp;
}
加载 Manifest 详解:
首先加载 PackageManifest 文件,PackageManifest 包含了所有 Bundle 的信息。
初始化 FileSystem 详解:
根据运行模式初始化 FileSystem。Host 模式会同时初始化 BuildinFileSystem、CacheFileSystem、DeliveryFileSystem。
初始化 PlayMode 详解:
根据配置的运行模式创建对应的 PlayModeImpl。
初始化 Manager 详解:
初始化 ResourceManager、DownloadManager、CacheSystem 等管理器。
3.3 资源加载
ResourcePackage 提供了多种资源加载方法:
csharp
public AssetOperationHandle LoadAssetAsync<T>(string location)
{
return ResourceManager.LoadAssetAsync(location, typeof(T));
}
public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode)
{
return ResourceManager.LoadSceneAsync(location, sceneMode);
}
public SubAssetsOperationHandle LoadSubAssetsAsync<T>(string location)
{
return ResourceManager.LoadSubAssetsAsync(location, typeof(T));
}
public RawFileOperationHandle LoadRawFileAsync(string location)
{
return ResourceManager.LoadRawFileAsync(location);
}
LoadAssetAsync 详解:
异步加载指定类型的资源,返回 AssetOperationHandle。
LoadSceneAsync 详解:
异步加载场景,返回 SceneOperationHandle。
LoadSubAssetsAsync 详解:
异步加载子资源,返回 SubAssetsOperationHandle。
LoadRawFileAsync 详解:
异步加载原生文件,返回 RawFileOperationHandle。
3.4 资源卸载
ResourcePackage 提供了多种资源卸载方法:
csharp
public void UnloadAsset(AssetOperationHandle handle)
{
ResourceManager.UnloadAsset(handle);
}
public void UnloadScene(SceneOperationHandle handle)
{
ResourceManager.UnloadScene(handle);
}
UnloadAsset 详解:
卸载资源。卸载时会减少 Provider 的引用计数,引用为 0 时销毁资源。
UnloadScene 详解:
卸载场景。
3.5 热更新
ResourcePackage 提供了热更新方法:
csharp
public UpdatePackageVersionOperation UpdatePackageVersionAsync()
{
return PlayModeImpl.UpdatePackageVersionAsync();
}
public UpdatePackageManifestOperation UpdatePackageManifestAsync()
{
return PlayModeImpl.UpdatePackageManifestAsync();
}
UpdatePackageVersionAsync 详解:
更新 Package 版本。请求服务器的最新版本,与本地版本比较。
UpdatePackageManifestAsync 详解:
更新 Package Manifest。请求服务器的 Manifest,与本地 Manifest 比较,下载差异资源。
3.6 ResourcePackage 销毁
ResourcePackage 销毁时需要清理所有资源:
csharp
public void Destroy()
{
// 1. 销毁 Manager
ResourceManager.Destroy();
DownloadManager.Destroy();
CacheSystem.Destroy();
// 2. 销毁 FileSystem
BuildinFileSystem?.OnDestroy();
CacheFileSystem?.OnDestroy();
DeliveryFileSystem?.OnDestroy();
// 3. 销毁 PlayMode
PlayModeImpl?.OnDestroy();
// 4. 清空 Manifest
Manifest = null;
}
销毁顺序详解:
销毁时按照 Manager → FileSystem → PlayMode → Manifest 的顺序进行销毁。
注意事项详解:
销毁 Package 前需要确保没有正在进行的资源加载,否则可能造成资源泄漏。
四、Manifest 处理
4.1 Manifest 加载
csharp
private LoadManifestOperation LoadManifest()
{
// 1. 获取 Manifest 文件路径
string manifestFilePath = GetManifestFilePath();
// 2. 异步加载 Manifest
var loadOp = new LoadManifestOperation(manifestFilePath);
loadOp.Start();
return loadOp;
}
Manifest 文件路径详解:
Manifest 文件路径通常为 {BuildinPath}/{PackageName}/PackageManifest_{PackageVersion}.bytes。
异步加载详解:
使用 LoadManifestOperation 异步加载 Manifest 文件。
4.2 Manifest 解析
csharp
private PackageManifest ParseManifest(byte[] manifestData)
{
string json = System.Text.Encoding.UTF8.GetString(manifestData);
return PackageManifest.FromJson(json);
}
JSON 解析详解:
将 Manifest 的字节数据转换为字符串,然后使用 JsonUtility 反序列化为 PackageManifest 对象。
4.3 Manifest 验证
csharp
private bool ValidateManifest(PackageManifest manifest)
{
if (manifest == null) return false;
if (string.IsNullOrEmpty(manifest.PackageName)) return false;
if (string.IsNullOrEmpty(manifest.PackageVersion)) return false;
if (manifest.AssetList == null || manifest.AssetList.Assets == null) return false;
if (manifest.BundleList == null || manifest.BundleList.Bundles == null) return false;
return true;
}
验证项详解:
- Manifest 不为空
- PackageName 不为空
- PackageVersion 不为空
- AssetList 不为空
- BundleList 不为空
五、版本管理
5.1 版本号
YooAsset 使用语义化版本号(Major.Minor.Patch):
csharp
public string PackageVersion { get; set; }
public string ResourceVersion { get; set; }
PackageVersion 详解:
Package 的版本号。
ResourceVersion 详解:
资源的版本号,可以与 PackageVersion 不同。
5.2 版本检查
csharp
public UpdatePackageVersionOperation UpdatePackageVersionAsync()
{
// 1. 请求服务器版本
var request = UnityWebRequest.Get(_versionURL);
// 2. 解析服务器版本
// 3. 与本地版本比较
// 4. 返回最新版本
}
版本检查流程详解:
向服务器请求最新版本,解析后与本地版本比较。
5.3 版本更新
csharp
public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion)
{
// 1. 加载服务器 Manifest
// 2. 与本地 Manifest 对比
// 3. 计算差异 Bundle
// 4. 返回下载操作
}
版本更新流程详解:
根据 packageVersion 加载服务器的 Manifest,与本地 Manifest 对比,计算差异 Bundle,返回下载操作。
六、总结
本章深入解析了 YooAsset 全局入口(YooAssets)与资源包(ResourcePackage)的源码实现,包括:
- YooAssets 全局入口:全局静态类的设计、CreatePackage、InitPackage、DestroyPackage 等方法
- ResourcePackage 资源包:核心抽象、初始化、资源加载、卸载、热更新
- Manifest 处理:加载、解析、验证
- 版本管理:版本号、版本检查、版本更新
通过深入理解 YooAssets 和 ResourcePackage 的源码实现,开发者可以更好地使用 YooAsset 的资源管理功能,并根据自己的需求进行扩展。
上一篇 :运行时总览 下一篇 :运行模式体系(PlayMode)