)
源码-全局入口与资源包YooAssets ResourcePackage篇章05-源码深度-运行时核心模块阅读时间约 30 分钟前置知识了解运行时总览一、引言本章将深入解析 YooAsset 全局入口YooAssets与资源包ResourcePackage的源码实现。YooAssets 是 YooAsset 的全局静态入口ResourcePackage 是资源管理的核心抽象。深入理解这两个类的实现是掌握 YooAsset 资源管理的关键。YooAssets 和 ResourcePackage 的设计体现了 YooAsset 的核心理念清晰的职责划分、灵活的扩展能力、统一的 API 接口。本章将从源码层面深入解析这两个类的实现。二、YooAssets 全局入口2.1 YooAssets 的设计YooAssets 是 YooAsset 的全局静态入口类public static class YooAssets { private static GameObject _operationUpdaterGo; private static readonly Dictionarystring, ResourcePackage _packages new Dictionarystring, 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创建 PackageInitPackage初始化 PackageDestroyPackage销毁 PackageGetPackage获取 PackageSetDefaultPackage设置默认 PackageGetDefaultPackage获取默认 Package2.2 YooAssets.CreatePackageCreatePackage 方法创建 ResourcePackagepublic 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.InitPackageInitPackage 方法初始化 ResourcePackagepublic static bool InitPackage(ResourcePackage package) { // 1. 启动 OperationUpdater if (_operationUpdaterGo null) { _operationUpdaterGo new GameObject(YooAssetOperationUpdater); _operationUpdaterGo.AddComponentOperationUpdater(); 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.DestroyPackageDestroyPackage 方法销毁 ResourcePackagepublic 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 的辅助方法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 资源管理的核心抽象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 LoadAssetAsyncT(string location); public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode); public void UnloadAsset(AssetOperationHandle handle); public void Destroy(); }核心字段详解PackageNamePackage 名称ManifestPackage 清单BuildinFileSystem构建内文件系统CacheFileSystem缓存文件系统DeliveryFileSystem远程文件系统PlayModeImpl运行模式实现ResourceManager资源管理器DownloadManager下载管理器CacheSystem缓存系统3.2 ResourcePackage 初始化ResourcePackage 初始化是 YooAsset 的核心流程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 提供了多种资源加载方法public AssetOperationHandle LoadAssetAsyncT(string location) { return ResourceManager.LoadAssetAsync(location, typeof(T)); } public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode) { return ResourceManager.LoadSceneAsync(location, sceneMode); } public SubAssetsOperationHandle LoadSubAssetsAsyncT(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 提供了多种资源卸载方法public void UnloadAsset(AssetOperationHandle handle) { ResourceManager.UnloadAsset(handle); } public void UnloadScene(SceneOperationHandle handle) { ResourceManager.UnloadScene(handle); }UnloadAsset 详解卸载资源。卸载时会减少 Provider 的引用计数引用为 0 时销毁资源。UnloadScene 详解卸载场景。3.5 热更新ResourcePackage 提供了热更新方法public UpdatePackageVersionOperation UpdatePackageVersionAsync() { return PlayModeImpl.UpdatePackageVersionAsync(); } public UpdatePackageManifestOperation UpdatePackageManifestAsync() { return PlayModeImpl.UpdatePackageManifestAsync(); }UpdatePackageVersionAsync 详解更新 Package 版本。请求服务器的最新版本与本地版本比较。UpdatePackageManifestAsync 详解更新 Package Manifest。请求服务器的 Manifest与本地 Manifest 比较下载差异资源。3.6 ResourcePackage 销毁ResourcePackage 销毁时需要清理所有资源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 加载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 解析private PackageManifest ParseManifest(byte[] manifestData) { string json System.Text.Encoding.UTF8.GetString(manifestData); return PackageManifest.FromJson(json); }JSON 解析详解将 Manifest 的字节数据转换为字符串然后使用 JsonUtility 反序列化为 PackageManifest 对象。4.3 Manifest 验证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.Patchpublic string PackageVersion { get; set; } public string ResourceVersion { get; set; }PackageVersion 详解Package 的版本号。ResourceVersion 详解资源的版本号可以与 PackageVersion 不同。5.2 版本检查public UpdatePackageVersionOperation UpdatePackageVersionAsync() { // 1. 请求服务器版本 var request UnityWebRequest.Get(_versionURL); // 2. 解析服务器版本 // 3. 与本地版本比较 // 4. 返回最新版本 }版本检查流程详解向服务器请求最新版本解析后与本地版本比较。5.3 版本更新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