diff --git a/Assets/YooAsset/CHANGELOG.md b/Assets/YooAsset/CHANGELOG.md index b985db8..8e37c30 100644 --- a/Assets/YooAsset/CHANGELOG.md +++ b/Assets/YooAsset/CHANGELOG.md @@ -2,6 +2,271 @@ All notable changes to this package will be documented in this file. +## [1.4.11] - 2023-04-14 + +### Fixed + +- (#97)修复了着色器变种收集配置无法保存的问题。 +- (#83)修复了资源收集界面Package列表没有实时刷新的问题。 +- (#48)优化了场景卸载机制,在切换场景的时候不在主动卸载资源。 + +### Changed + +- 增加了扩展属性 + + ```c# + [assembly: InternalsVisibleTo("YooAsset.EditorExtension")] + [assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")] + ``` + +## [1.4.10] - 2023-04-08 + +### Fixed + +- 修复了资源文件路径无效导致异常的问题。 +- 修复了原生文件不支持ini格式文件的问题。 +- 修复了通过代码途径导入XML配置的报错问题。 + +## [1.4.9] - 2023-03-29 + +### Fixed + +- 修复了资源配置界面的GroupActiveRule保存无效的问题。 + +### Changed + +- 优化了资源配置导入逻辑,增加了对XML配置文件的合法性检测。 + +- 优化了UniTask的说明文档。 + +- 调整构建的输出目录结构。 + +- 调试窗口增加分屏功能。(Unity2020.3+起效) + +- 报告窗口增加分屏功能。(Unity2020.3+起效) + +- 编辑器模拟模式支持了虚拟资源包。 + +- 扩展了Instantiate方法。 + + ```c# + public sealed class AssetOperationHandle + { + public GameObject InstantiateSync(); + public GameObject InstantiateSync(Transform parent); + public GameObject InstantiateSync(Transform parent, bool worldPositionStays); + public GameObject InstantiateSync(Vector3 position, Quaternion rotation); + public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent); + } + ``` + +### Added + +- 优化了报告文件内容,增加了资源包内嵌的资源列表。 + +- 可寻址规则增加了AddressByFilePath类。 + +- 新增了新方法。 + + ```c# + /// + /// 向远端请求并更新清单 + /// + public class UpdatePackageManifestOperation : AsyncOperationBase + { + /// + /// 保存当前清单的版本,用于下次启动时自动加载的版本。 + /// + public void SavePackageVersion(); + } + ``` + +- 新增了初始化参数。 + + ```c# + /// + /// 下载失败尝试次数 + /// 注意:默认值为MaxValue + /// + public int DownloadFailedTryAgain = int.MaxValue; + ``` + +- 新增了初始化参数。 + + ```c# + /// + /// 资源加载每帧处理的最大时间片段 + /// 注意:默认值为MaxValue + /// + public long LoadingMaxTimeSlice = long.MaxValue; + ``` + +### Removed + +- 移除了代码里的Patch敏感字。 + + ```c# + //PatchManifest.cs重命名为PackageManifest.cs + //AssetsPackage.cs重命名为ResourcePackage.cs + //YooAssets.CreateAssetsPackage()重命名为YooAssets.CreatePackage() + //YooAssets.GetAssetsPackage()重命名为YooAssets.GetPackage() + //YooAssets.TryGetAssetsPackage()重命名为YooAssets.TryGetPackage() + //YooAssets.HasAssetsPackage()重命名为YooAssets.HasPackage() + ``` + +- 移除了初始化参数:AssetLoadingMaxNumber + +## [1.4.8] - 2023-03-10 + +### Fixed + +- 修复了同步加载原生文件,程序卡死的问题。 +- 修复了可编程构建管线,当项目里没有着色器,如果有引用内置着色器会导致打包失败的问题。 +- 修复了在Unity2021.3版本下着色器收集界面错乱的问题。 + +### Changed + +- 优化了打包逻辑,提高构建速度。 + +- 支持自定义日志处理,方便收集线上问题。 + + ```c# + public class YooAssets + { + /// + /// 初始化资源系统 + /// + /// 自定义日志处理 + public static void Initialize(ILogger logger = null) + } + ``` + +## [1.4.7] - 2023-03-03 + +### Fixed + +- 修复了在运行时资源引用链无效的问题。 +- 修复了在构建过程中发生异常后进度条未消失的问题。 +- 修复了使用SBP构建管线,如果有原生文件会导致打包失败的问题。 + +### Changed + +- 支持自定义下载请求 + + ```c# + /// + /// 设置下载系统参数,自定义下载请求 + /// + public static void SetDownloadSystemUnityWebRequest(DownloadRequestDelegate requestDelegate) + ``` + +- 优化了打包时资源包引用关系计算的逻辑。 + +- 优化了缓存系统初始化逻辑,支持分帧获取所有缓存文件。 + +- 优化了缓存系统的存储目录结构,提高了文件夹查询速度。 + +- 优化了在资源收集界面,点击查看Collector主资源列表卡顿问题。 + +- 优化了资源对象加载耗时统计的逻辑,现在更加准确了。 + +- 优化了资源加载器查询逻辑。 + +- 优化了资源下载系统,下载文件的验证支持了多线程。 + +- 着色器变种收集界面增加单次照射数量的控制。 + +## [1.4.6-preview] - 2023-02-22 + +### Changed + +- EVerifyLevel新增Middle级别。 + + ```c# + public enum EVerifyLevel + { + /// + /// 验证文件存在 + /// + Low, + + /// + /// 验证文件大小 + /// + Middle, + + /// + /// 验证文件大小和CRC + /// + High, + } + ``` + +- 补丁清单的资源包列表新增引用链。 + + (解决复杂依赖关系下,错误卸载资源包的问题) + +- 缓存系统支持后缀格式存储。 + + (解决原生文件没有后缀格式的问题) + +- 收集界面增加用户自定义数据栏。 + +## [1.4.5-preview] - 2023-02-17 + +### Fixed + +- (#67)修复了报告查看界面在Unity2021.3上的兼容性问题。 +- (#66)修复了在Unity2021.3上编辑器模拟模式运行报错的问题。 + +### Changed + +- 接口变更:IPackRule + + ````c# + /// + /// 资源打包规则接口 + /// + public interface IPackRule + { + /// + /// 获取打包规则结果 + /// + PackRuleResult GetPackRuleResult(PackRuleData data); + + /// + /// 是否为原生文件打包规则 + /// + bool IsRawFilePackRule(); + } + ```` + +## [1.4.4-preview] - 2023-02-14 + +### Fixed + +- (#65)修复了AssetBundle构建宏逻辑错误。 +- 修复了AssetBundle加载宏逻辑错误。 + +## [1.4.3-preview] - 2023-02-10 + +全新的缓存系统! + +### Fixed + +- 修复了WebGL平台本地文件验证报错。 +- 修复了WEBGL平台加载原生文件失败的问题。 +- 修复了通过Handle句柄查询资源包下载进度为零的问题。 + +### Changed + +- 着色器变种收集增加分批次处理功能。 +- Unity2021版本开始不再支持内置构建管线。 + +### Removed + +- 太空战机DEMO移除了BetterStreamingAssets插件。 + ## [1.4.2-preview] - 2023-01-03 ### Fixed diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilder.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilder.cs index ca3b3e0..88b82e0 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilder.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilder.cs @@ -39,12 +39,6 @@ namespace YooAsset.Editor var buildParametersContext = new BuildParametersContext(buildParameters); _buildContext.SetContextObject(buildParametersContext); - // 是否显示LOG - if (buildParameters.BuildMode == EBuildMode.SimulateBuild) - BuildRunner.EnableLog = false; - else - BuildRunner.EnableLog = true; - // 创建构建节点 List pipeline; if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline) @@ -54,12 +48,13 @@ namespace YooAsset.Editor new TaskPrepare(), //前期准备工作 new TaskGetBuildMap(), //获取构建列表 new TaskBuilding(), //开始执行构建 + new TaskCopyRawFile(), //拷贝原生文件 new TaskVerifyBuildResult(), //验证构建结果 new TaskEncryption(), //加密资源文件 - new TaskUpdateBuildInfo(), //更新构建信息 - new TaskCreatePatchManifest(), //创建清单文件 + new TaskUpdateBundleInfo(), //更新资源包信息 + new TaskCreateManifest(), //创建清单文件 new TaskCreateReport(), //创建报告文件 - new TaskCreatePatchPackage(), //制作补丁包 + new TaskCreatePackage(), //制作包裹 new TaskCopyBuildinFiles(), //拷贝内置文件 }; } @@ -70,12 +65,13 @@ namespace YooAsset.Editor new TaskPrepare(), //前期准备工作 new TaskGetBuildMap(), //获取构建列表 new TaskBuilding_SBP(), //开始执行构建 + new TaskCopyRawFile(), //拷贝原生文件 new TaskVerifyBuildResult_SBP(), //验证构建结果 new TaskEncryption(), //加密资源文件 - new TaskUpdateBuildInfo(), //更新构建信息 - new TaskCreatePatchManifest(), //创建清单文件 + new TaskUpdateBundleInfo(), //更新补丁信息 + new TaskCreateManifest(), //创建清单文件 new TaskCreateReport(), //创建报告文件 - new TaskCreatePatchPackage(), //制作补丁包 + new TaskCreatePackage(), //制作补丁包 new TaskCopyBuildinFiles(), //拷贝内置文件 }; } @@ -84,19 +80,23 @@ namespace YooAsset.Editor throw new NotImplementedException(); } + // 初始化日志 + BuildLogger.InitLogger(buildParameters.EnableLog); + // 执行构建流程 var buildResult = BuildRunner.Run(pipeline, _buildContext); if (buildResult.Success) { buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory(); - Debug.Log($"{buildParameters.BuildMode} pipeline build succeed !"); + BuildLogger.Log($"{buildParameters.BuildMode} pipeline build succeed !"); } else { - Debug.LogWarning($"{buildParameters.BuildMode} pipeline build failed !"); - Debug.LogError($"Build task failed : {buildResult.FailedTask}"); - Debug.LogError($"Build task error : {buildResult.FailedInfo}"); + BuildLogger.Warning($"{buildParameters.BuildMode} pipeline build failed !"); + BuildLogger.Error($"Build task failed : {buildResult.FailedTask}"); + BuildLogger.Error($"Build task error : {buildResult.FailedInfo}"); } + return buildResult; } } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderHelper.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderHelper.cs index 963b771..ab0f933 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderHelper.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderHelper.cs @@ -58,14 +58,5 @@ namespace YooAsset.Editor } } } - - /// - /// 获取构建管线的输出目录 - /// - public static string MakePipelineOutputDirectory(string outputRoot, string buildPackage, BuildTarget buildTarget, EBuildMode buildMode) - { - string outputDirectory = $"{outputRoot}/{buildPackage}/{buildTarget}/{YooAssetSettings.OutputFolderName}"; - return outputDirectory; - } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderSettingData.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderSettingData.cs index 9412292..353931b 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderSettingData.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderSettingData.cs @@ -29,7 +29,7 @@ namespace YooAsset.Editor /// private static void LoadSettingData() { - _setting = EditorHelper.LoadSettingData(); + _setting = SettingLoader.LoadSettingData(); } /// diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderWindow.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderWindow.cs index 2d854ac..9e4b8ea 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderWindow.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderWindow.cs @@ -14,7 +14,7 @@ namespace YooAsset.Editor [MenuItem("YooAsset/AssetBundle Builder", false, 102)] public static void ShowExample() { - AssetBundleBuilderWindow window = GetWindow("资源包构建工具", true, EditorDefine.DockedWindowTypes); + AssetBundleBuilderWindow window = GetWindow("资源包构建工具", true, WindowsDefine.DockedWindowTypes); window.minSize = new Vector2(800, 600); } @@ -42,7 +42,7 @@ namespace YooAsset.Editor VisualElement root = this.rootVisualElement; // 加载布局文件 - var visualAsset = EditorHelper.LoadWindowUXML(); + var visualAsset = UxmlLoader.LoadWindowUXML(); if (visualAsset == null) return; @@ -60,7 +60,7 @@ namespace YooAsset.Editor // 加密服务类 _encryptionServicesClassTypes = GetEncryptionServicesClassTypes(); - _encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.FullName).ToList(); + _encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.Name).ToList(); // 输出目录 string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot(); @@ -220,15 +220,27 @@ namespace YooAsset.Editor private void RefreshWindow() { + var buildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline; var buildMode = AssetBundleBuilderSettingData.Setting.BuildMode; var copyOption = AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption; bool enableElement = buildMode == EBuildMode.ForceRebuild; bool tagsFiledVisible = copyOption == ECopyBuildinFileOption.ClearAndCopyByTags || copyOption == ECopyBuildinFileOption.OnlyCopyByTags; - _encryptionField.SetEnabled(enableElement); - _compressionField.SetEnabled(enableElement); - _outputNameStyleField.SetEnabled(enableElement); - _copyBuildinFileOptionField.SetEnabled(enableElement); - _copyBuildinFileTagsField.SetEnabled(enableElement); + + if (buildPipeline == EBuildPipeline.BuiltinBuildPipeline) + { + _compressionField.SetEnabled(enableElement); + _outputNameStyleField.SetEnabled(enableElement); + _copyBuildinFileOptionField.SetEnabled(enableElement); + _copyBuildinFileTagsField.SetEnabled(enableElement); + } + else + { + _compressionField.SetEnabled(true); + _outputNameStyleField.SetEnabled(true); + _copyBuildinFileOptionField.SetEnabled(true); + _copyBuildinFileTagsField.SetEnabled(true); + } + _copyBuildinFileTagsField.visible = tagsFiledVisible; } private void SaveBtn_clicked() diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleSimulateBuilder.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleSimulateBuilder.cs index e9d4df7..9a89843 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleSimulateBuilder.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleSimulateBuilder.cs @@ -18,6 +18,7 @@ namespace YooAsset.Editor buildParameters.BuildMode = EBuildMode.SimulateBuild; buildParameters.PackageName = packageName; buildParameters.PackageVersion = "Simulate"; + buildParameters.EnableLog = false; AssetBundleBuilder builder = new AssetBundleBuilder(); var buildResult = builder.Run(buildParameters); diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs index dd21a6e..7999f92 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs @@ -7,8 +7,6 @@ namespace YooAsset.Editor { public class BuildAssetInfo { - private string _mainBundleName; - private string _shareBundleName; private bool _isAddAssetTags = false; private readonly HashSet _referenceBundleNames = new HashSet(); @@ -17,6 +15,11 @@ namespace YooAsset.Editor /// public ECollectorType CollectorType { private set; get; } + /// + /// 资源包完整名称 + /// + public string BundleName { private set; get; } + /// /// 可寻址地址 /// @@ -54,10 +57,10 @@ namespace YooAsset.Editor public List AllDependAssetInfos { private set; get; } - public BuildAssetInfo(ECollectorType collectorType, string mainBundleName, string address, string assetPath, bool isRawAsset) + public BuildAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, bool isRawAsset) { - _mainBundleName = mainBundleName; CollectorType = collectorType; + BundleName = bundleName; Address = address; AssetPath = assetPath; IsRawAsset = isRawAsset; @@ -133,24 +136,12 @@ namespace YooAsset.Editor /// public bool HasBundleName() { - string bundleName = GetBundleName(); - if (string.IsNullOrEmpty(bundleName)) + if (string.IsNullOrEmpty(BundleName)) return false; else return true; } - /// - /// 获取资源包名称 - /// - public string GetBundleName() - { - if (CollectorType == ECollectorType.None) - return _shareBundleName; - else - return _mainBundleName; - } - /// /// 添加关联的资源包名称 /// @@ -164,53 +155,32 @@ namespace YooAsset.Editor } /// - /// 计算主资源或共享资源的完整包名 + /// 计算共享资源包的完整包名 /// - public void CalculateFullBundleName(bool uniqueBundleName, string packageName) + public void CalculateShareBundleName(bool uniqueBundleName, string packageName, string shadersBundleName) { - if (CollectorType == ECollectorType.None) + if (CollectorType != ECollectorType.None) + return; + + if (IsRawAsset) + throw new Exception("Should never get here !"); + + if (IsShaderAsset) { - if (IsRawAsset) - throw new Exception("Should never get here !"); - - if (IsShaderAsset) - { - _shareBundleName = YooAssetSettingsData.GetUnityShadersBundleFullName(uniqueBundleName, packageName); - } - else - { - if (_referenceBundleNames.Count > 1) - { - IPackRule packRule = PackDirectory.StaticPackRule; - var bundleName = packRule.GetBundleName(new PackRuleData(AssetPath)); - if (YooAssetSettingsData.Setting.RegularBundleName) - bundleName = EditorTools.GetRegularPath(bundleName).Replace('/', '_').Replace('.', '_').ToLower(); - else - bundleName = EditorTools.GetRegularPath(bundleName).ToLower(); - - if (uniqueBundleName) - _shareBundleName = $"{packageName.ToLower()}_share_{bundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}"; - else - _shareBundleName = $"share_{bundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}"; - } - } + BundleName = shadersBundleName; } else { - if (IsRawAsset) + if (_referenceBundleNames.Count > 1) { - string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.RawFileVariant}"; - _mainBundleName = mainBundleName.ToLower(); + IPackRule packRule = PackDirectory.StaticPackRule; + PackRuleResult packRuleResult = packRule.GetPackRuleResult(new PackRuleData(AssetPath)); + BundleName = packRuleResult.GetShareBundleName(packageName, uniqueBundleName); } else { - string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}"; - _mainBundleName = mainBundleName.ToLower(); ; - } - - if (uniqueBundleName) - { - _mainBundleName = $"{packageName.ToLower()}_{_mainBundleName}"; + // 注意:被引用次数小于1的资源不需要设置资源包名称 + BundleName = string.Empty; } } } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildBundleInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildBundleInfo.cs index 9663de4..4063069 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildBundleInfo.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildBundleInfo.cs @@ -8,7 +8,7 @@ namespace YooAsset.Editor { public class BuildBundleInfo { - public class BuildPatchInfo + public class InfoWrapper { /// /// 构建内容的哈希值 @@ -18,17 +18,17 @@ namespace YooAsset.Editor /// /// 文件哈希值 /// - public string PatchFileHash { set; get; } + public string FileHash { set; get; } /// /// 文件哈希值 /// - public string PatchFileCRC { set; get; } + public string FileCRC { set; get; } /// /// 文件哈希值 /// - public long PatchFileSize { set; get; } + public long FileSize { set; get; } /// @@ -39,7 +39,7 @@ namespace YooAsset.Editor /// /// 补丁包输出文件路径 /// - public string PatchOutputFilePath { set; get; } + public string PackageOutputFilePath { set; get; } } /// @@ -51,12 +51,12 @@ namespace YooAsset.Editor /// 参与构建的资源列表 /// 注意:不包含零依赖资源 /// - public readonly List BuildinAssets = new List(); + public readonly List AllMainAssets = new List(); /// /// 补丁文件信息 /// - public readonly BuildPatchInfo PatchInfo = new BuildPatchInfo(); + public readonly InfoWrapper BundleInfo = new InfoWrapper(); /// /// Bundle文件的加载方法 @@ -76,9 +76,9 @@ namespace YooAsset.Editor { get { - foreach (var asset in BuildinAssets) + foreach (var assetInfo in AllMainAssets) { - if (asset.IsRawAsset) + if (assetInfo.IsRawAsset) return true; } return false; @@ -113,7 +113,7 @@ namespace YooAsset.Editor if (IsContainsAsset(assetInfo.AssetPath)) throw new System.Exception($"Asset is existed : {assetInfo.AssetPath}"); - BuildinAssets.Add(assetInfo); + AllMainAssets.Add(assetInfo); } /// @@ -121,7 +121,7 @@ namespace YooAsset.Editor /// public bool IsContainsAsset(string assetPath) { - foreach (var assetInfo in BuildinAssets) + foreach (var assetInfo in AllMainAssets) { if (assetInfo.AssetPath == assetPath) { @@ -136,8 +136,8 @@ namespace YooAsset.Editor /// public string[] GetBundleTags() { - List result = new List(BuildinAssets.Count); - foreach (var assetInfo in BuildinAssets) + List result = new List(AllMainAssets.Count); + foreach (var assetInfo in AllMainAssets) { foreach (var assetTag in assetInfo.BundleTags) { @@ -148,20 +148,43 @@ namespace YooAsset.Editor return result.ToArray(); } + /// + /// 获取该资源包内的所有资源(包括零依赖资源) + /// + public List GetAllBuiltinAssetPaths() + { + var packAssets = GetAllMainAssetPaths(); + List result = new List(packAssets); + foreach (var assetInfo in AllMainAssets) + { + if (assetInfo.AllDependAssetInfos == null) + continue; + foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos) + { + if (dependAssetInfo.HasBundleName() == false) + { + if (result.Contains(dependAssetInfo.AssetPath) == false) + result.Add(dependAssetInfo.AssetPath); + } + } + } + return result; + } + /// /// 获取构建的资源路径列表 /// - public string[] GetBuildinAssetPaths() + public string[] GetAllMainAssetPaths() { - return BuildinAssets.Select(t => t.AssetPath).ToArray(); + return AllMainAssets.Select(t => t.AssetPath).ToArray(); } /// /// 获取所有写入补丁清单的资源 /// - public BuildAssetInfo[] GetAllPatchAssetInfos() + public BuildAssetInfo[] GetAllMainAssetInfos() { - return BuildinAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray(); + return AllMainAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray(); } /// @@ -173,24 +196,24 @@ namespace YooAsset.Editor AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = BundleName; build.assetBundleVariant = string.Empty; - build.assetNames = GetBuildinAssetPaths(); + build.assetNames = GetAllMainAssetPaths(); return build; } /// - /// 创建PatchBundle类 + /// 创建PackageBundle类 /// - internal PatchBundle CreatePatchBundle() + internal PackageBundle CreatePackageBundle() { - PatchBundle patchBundle = new PatchBundle(); - patchBundle.BundleName = BundleName; - patchBundle.FileHash = PatchInfo.PatchFileHash; - patchBundle.FileCRC = PatchInfo.PatchFileCRC; - patchBundle.FileSize = PatchInfo.PatchFileSize; - patchBundle.IsRawFile = IsRawFile; - patchBundle.LoadMethod = (byte)LoadMethod; - patchBundle.Tags = GetBundleTags(); - return patchBundle; + PackageBundle packageBundle = new PackageBundle(); + packageBundle.BundleName = BundleName; + packageBundle.FileHash = BundleInfo.FileHash; + packageBundle.FileCRC = BundleInfo.FileCRC; + packageBundle.FileSize = BundleInfo.FileSize; + packageBundle.IsRawFile = IsRawFile; + packageBundle.LoadMethod = (byte)LoadMethod; + packageBundle.Tags = GetBundleTags(); + return packageBundle; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapContext.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapContext.cs index effc561..e28666f 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapContext.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapContext.cs @@ -8,6 +8,8 @@ namespace YooAsset.Editor { public class BuildMapContext : IContextObject { + private readonly Dictionary _bundleInfoDic = new Dictionary(10000); + /// /// 参与构建的资源总数 /// 说明:包括主动收集的资源以及其依赖的所有资源 @@ -25,9 +27,20 @@ namespace YooAsset.Editor public bool UniqueBundleName; /// - /// 资源包列表 + /// 着色器统一的全名称 /// - public readonly List BundleInfos = new List(1000); + public string ShadersBundleName; + + /// + /// 资源包信息列表 + /// + public Dictionary.ValueCollection Collection + { + get + { + return _bundleInfoDic.Values; + } + } /// @@ -35,11 +48,11 @@ namespace YooAsset.Editor /// public void PackAsset(BuildAssetInfo assetInfo) { - string bundleName = assetInfo.GetBundleName(); + string bundleName = assetInfo.BundleName; if (string.IsNullOrEmpty(bundleName)) throw new Exception("Should never get here !"); - if (TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo)) + if (_bundleInfoDic.TryGetValue(bundleName, out BuildBundleInfo bundleInfo)) { bundleInfo.PackAsset(assetInfo); } @@ -47,33 +60,28 @@ namespace YooAsset.Editor { BuildBundleInfo newBundleInfo = new BuildBundleInfo(bundleName); newBundleInfo.PackAsset(assetInfo); - BundleInfos.Add(newBundleInfo); + _bundleInfoDic.Add(bundleName, newBundleInfo); } } /// - /// 获取所有的打包资源 + /// 是否包含资源包 /// - public List GetAllAssets() + public bool IsContainsBundle(string bundleName) { - List result = new List(BundleInfos.Count); - foreach (var bundleInfo in BundleInfos) - { - result.AddRange(bundleInfo.BuildinAssets); - } - return result; + return _bundleInfoDic.ContainsKey(bundleName); } /// - /// 获取AssetBundle内构建的资源路径列表 + /// 获取资源包信息,如果没找到返回NULL /// - public string[] GetBuildinAssetPaths(string bundleName) + public BuildBundleInfo GetBundleInfo(string bundleName) { - if (TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo)) + if (_bundleInfoDic.TryGetValue(bundleName, out BuildBundleInfo result)) { - return bundleInfo.GetBuildinAssetPaths(); + return result; } - throw new Exception($"Not found {nameof(BuildBundleInfo)} : {bundleName}"); + throw new Exception($"Not found bundle : {bundleName}"); } /// @@ -81,8 +89,8 @@ namespace YooAsset.Editor /// public UnityEditor.AssetBundleBuild[] GetPipelineBuilds() { - List builds = new List(BundleInfos.Count); - foreach (var bundleInfo in BundleInfos) + List builds = new List(_bundleInfoDic.Count); + foreach (var bundleInfo in _bundleInfoDic.Values) { if (bundleInfo.IsRawFile == false) builds.Add(bundleInfo.CreatePipelineBuild()); @@ -91,25 +99,15 @@ namespace YooAsset.Editor } /// - /// 是否包含资源包 + /// 创建着色器信息类 /// - public bool IsContainsBundle(string bundleName) + public void CreateShadersBundleInfo(string shadersBundleName) { - return TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo); - } - - public bool TryGetBundleInfo(string bundleName, out BuildBundleInfo result) - { - foreach (var bundleInfo in BundleInfos) + if (IsContainsBundle(shadersBundleName) == false) { - if (bundleInfo.BundleName == bundleName) - { - result = bundleInfo; - return true; - } + var shaderBundleInfo = new BuildBundleInfo(shadersBundleName); + _bundleInfoDic.Add(shadersBundleName, shaderBundleInfo); } - result = null; - return false; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapCreater.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapCreater.cs deleted file mode 100644 index bf783d3..0000000 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapCreater.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Linq; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset.Editor -{ - public static class BuildMapCreater - { - /// - /// 执行资源构建上下文 - /// - public static BuildMapContext CreateBuildMap(EBuildMode buildMode, string packageName) - { - BuildMapContext context = new BuildMapContext(); - Dictionary buildAssetDic = new Dictionary(1000); - - // 1. 检测配置合法性 - AssetBundleCollectorSettingData.Setting.CheckConfigError(); - - // 2. 获取所有收集器收集的资源 - var buildResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName); - List allCollectAssets = buildResult.CollectAssets; - - // 3. 剔除未被引用的依赖资源 - List removeDependList = new List(); - foreach (var collectAssetInfo in allCollectAssets) - { - if (collectAssetInfo.CollectorType == ECollectorType.DependAssetCollector) - { - if (IsRemoveDependAsset(allCollectAssets, collectAssetInfo.AssetPath)) - removeDependList.Add(collectAssetInfo); - } - } - foreach (var removeValue in removeDependList) - { - allCollectAssets.Remove(removeValue); - } - - // 4. 录入所有收集器收集的资源 - foreach (var collectAssetInfo in allCollectAssets) - { - if (buildAssetDic.ContainsKey(collectAssetInfo.AssetPath) == false) - { - var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.CollectorType, collectAssetInfo.BundleName, - collectAssetInfo.Address, collectAssetInfo.AssetPath, collectAssetInfo.IsRawAsset); - buildAssetInfo.AddAssetTags(collectAssetInfo.AssetTags); - buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags); - buildAssetDic.Add(collectAssetInfo.AssetPath, buildAssetInfo); - } - else - { - throw new Exception($"Should never get here !"); - } - } - - // 5. 录入相关依赖的资源 - foreach (var collectAssetInfo in allCollectAssets) - { - foreach (var dependAssetPath in collectAssetInfo.DependAssets) - { - if (buildAssetDic.ContainsKey(dependAssetPath)) - { - buildAssetDic[dependAssetPath].AddBundleTags(collectAssetInfo.AssetTags); - buildAssetDic[dependAssetPath].AddReferenceBundleName(collectAssetInfo.BundleName); - } - else - { - var buildAssetInfo = new BuildAssetInfo(dependAssetPath); - buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags); - buildAssetInfo.AddReferenceBundleName(collectAssetInfo.BundleName); - buildAssetDic.Add(dependAssetPath, buildAssetInfo); - } - } - } - - // 6. 记录关键信息 - context.AssetFileCount = buildAssetDic.Count; - context.EnableAddressable = buildResult.EnableAddressable; - context.UniqueBundleName = buildResult.UniqueBundleName; - - // 7. 填充主动收集资源的依赖列表 - foreach (var collectAssetInfo in allCollectAssets) - { - var dependAssetInfos = new List(collectAssetInfo.DependAssets.Count); - foreach (var dependAssetPath in collectAssetInfo.DependAssets) - { - if (buildAssetDic.TryGetValue(dependAssetPath, out BuildAssetInfo value)) - dependAssetInfos.Add(value); - else - throw new Exception("Should never get here !"); - } - buildAssetDic[collectAssetInfo.AssetPath].SetAllDependAssetInfos(dependAssetInfos); - } - - // 8. 计算完整的资源包名 - foreach (KeyValuePair pair in buildAssetDic) - { - pair.Value.CalculateFullBundleName(buildResult.UniqueBundleName, buildResult.PackageName); - } - - // 9. 移除不参与构建的资源 - List removeBuildList = new List(); - foreach (KeyValuePair pair in buildAssetDic) - { - var buildAssetInfo = pair.Value; - if (buildAssetInfo.HasBundleName() == false) - removeBuildList.Add(buildAssetInfo); - } - foreach (var removeValue in removeBuildList) - { - buildAssetDic.Remove(removeValue.AssetPath); - } - - // 10. 构建资源包 - var allBuildinAssets = buildAssetDic.Values.ToList(); - if (allBuildinAssets.Count == 0) - throw new Exception("构建的资源列表不能为空"); - foreach (var assetInfo in allBuildinAssets) - { - context.PackAsset(assetInfo); - } - return context; - } - private static bool IsRemoveDependAsset(List allCollectAssets, string dependAssetPath) - { - foreach (var collectAssetInfo in allCollectAssets) - { - var collectorType = collectAssetInfo.CollectorType; - if (collectorType == ECollectorType.MainAssetCollector || collectorType == ECollectorType.StaticAssetCollector) - { - if (collectAssetInfo.DependAssets.Contains(dependAssetPath)) - return false; - } - } - - BuildRunner.Log($"发现未被依赖的资源并自动移除 : {dependAssetPath}"); - return true; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs index d1ab9d6..3c324c7 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs @@ -67,6 +67,11 @@ namespace YooAsset.Editor public string PackageVersion; + /// + /// 是否显示普通日志 + /// + public bool EnableLog = true; + /// /// 验证构建结果 /// diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParametersContext.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParametersContext.cs index d751f33..5774c93 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParametersContext.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParametersContext.cs @@ -7,8 +7,6 @@ namespace YooAsset.Editor { public class BuildParametersContext : IContextObject { - private readonly System.Diagnostics.Stopwatch _buildWatch = new System.Diagnostics.Stopwatch(); - private string _pipelineOutputDirectory = string.Empty; private string _packageOutputDirectory = string.Empty; @@ -31,7 +29,7 @@ namespace YooAsset.Editor { if (string.IsNullOrEmpty(_pipelineOutputDirectory)) { - _pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(Parameters.OutputRoot, Parameters.PackageName, Parameters.BuildTarget, Parameters.BuildMode); + _pipelineOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{YooAssetSettings.OutputFolderName}"; } return _pipelineOutputDirectory; } @@ -43,7 +41,7 @@ namespace YooAsset.Editor { if (string.IsNullOrEmpty(_packageOutputDirectory)) { - _packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.PackageName}/{Parameters.BuildTarget}/{Parameters.PackageVersion}"; + _packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{Parameters.PackageVersion}"; } return _packageOutputDirectory; } @@ -117,22 +115,5 @@ namespace YooAsset.Editor return buildParams; } - - /// - /// 获取构建的耗时(单位:秒) - /// - public float GetBuildingSeconds() - { - float seconds = _buildWatch.ElapsedMilliseconds / 1000f; - return seconds; - } - public void BeginWatch() - { - _buildWatch.Start(); - } - public void StopWatch() - { - _buildWatch.Stop(); - } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportBundleInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportBundleInfo.cs index c34828a..a4339ee 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportBundleInfo.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportBundleInfo.cs @@ -48,6 +48,16 @@ namespace YooAsset.Editor /// public string[] Tags; + /// + /// 引用该资源包的ID列表 + /// + public int[] ReferenceIDs; + + /// + /// 该资源包内包含的所有资源 + /// + public List AllBuiltinAssets = new List(); + /// /// 获取资源分类标签的字符串 /// diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs new file mode 100644 index 0000000..2d6026c --- /dev/null +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs @@ -0,0 +1,33 @@ +using System; +using System.IO; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset.Editor +{ + public static class BuildLogger + { + private static bool _enableLog = true; + + public static void InitLogger(bool enableLog) + { + _enableLog = enableLog; + } + + public static void Log(string message) + { + if (_enableLog) + { + Debug.Log(message); + } + } + public static void Warning(string message) + { + Debug.LogWarning(message); + } + public static void Error(string message) + { + Debug.LogError(message); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs.meta b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs.meta rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs.meta index 1fd4db3..8fad97d 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs.meta +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4eacb00a7e3873740b599112dfcf0123 +guid: 2bc82466a51f50141975e4424095aa09 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildRunner.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildRunner.cs index 9fb013c..9cc3e67 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildRunner.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildRunner.cs @@ -2,13 +2,19 @@ using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Diagnostics; using UnityEngine; namespace YooAsset.Editor { public class BuildRunner { - public static bool EnableLog = true; + private static Stopwatch _buildWatch; + + /// + /// 总耗时 + /// + public static int TotalSeconds = 0; /// /// 执行构建流程 @@ -23,17 +29,28 @@ namespace YooAsset.Editor BuildResult buildResult = new BuildResult(); buildResult.Success = true; + TotalSeconds = 0; for (int i = 0; i < pipeline.Count; i++) { IBuildTask task = pipeline[i]; try { + _buildWatch = Stopwatch.StartNew(); var taskAttribute = task.GetType().GetCustomAttribute(); - Log($"---------------------------------------->{taskAttribute.Desc}<---------------------------------------"); + if (taskAttribute != null) + BuildLogger.Log($"---------------------------------------->{taskAttribute.Desc}<---------------------------------------"); task.Run(context); + _buildWatch.Stop(); + + // 统计耗时 + int seconds = GetBuildSeconds(); + TotalSeconds += seconds; + if (taskAttribute != null) + BuildLogger.Log($"{taskAttribute.Desc}耗时:{seconds}秒"); } catch (Exception e) { + EditorTools.ClearProgressBar(); buildResult.FailedTask = task.GetType().Name; buildResult.FailedInfo = e.ToString(); buildResult.Success = false; @@ -42,26 +59,14 @@ namespace YooAsset.Editor } // 返回运行结果 + BuildLogger.Log($"构建过程总计耗时:{TotalSeconds}秒"); return buildResult; } - /// - /// 日志输出 - /// - public static void Log(string info) + private static int GetBuildSeconds() { - if (EnableLog) - { - UnityEngine.Debug.Log(info); - } - } - - /// - /// 日志输出 - /// - public static void Info(string info) - { - UnityEngine.Debug.Log(info); + float seconds = _buildWatch.ElapsedMilliseconds / 1000f; + return (int)seconds; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskBuilding.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskBuilding.cs index 87ed746..da267bd 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskBuilding.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskBuilding.cs @@ -41,36 +41,10 @@ namespace YooAsset.Editor throw new Exception("构建过程中发生严重错误!请查阅上下文日志!"); } - BuildRunner.Log("Unity引擎打包成功!"); + BuildLogger.Log("Unity引擎打包成功!"); BuildResultContext buildResultContext = new BuildResultContext(); buildResultContext.UnityManifest = buildResults; context.SetContextObject(buildResultContext); - - // 拷贝原生文件 - if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) - { - CopyRawBundle(buildMapContext, buildParametersContext); - } - } - - /// - /// 拷贝原生文件 - /// - private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext) - { - string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); - foreach (var bundleInfo in buildMapContext.BundleInfos) - { - if (bundleInfo.IsRawFile) - { - string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; - foreach (var buildAsset in bundleInfo.BuildinAssets) - { - if (buildAsset.IsRawAsset) - EditorTools.CopyFile(buildAsset.AssetPath, dest, true); - } - } - } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskBuilding_SBP.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskBuilding_SBP.cs index d17ee14..bb69ae2 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskBuilding_SBP.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskBuilding_SBP.cs @@ -33,44 +33,26 @@ namespace YooAsset.Editor // 开始构建 IBundleBuildResults buildResults; var buildParameters = buildParametersContext.GetSBPBuildParameters(); - var shadersBunldeName = YooAssetSettingsData.GetUnityShadersBundleFullName(buildMapContext.UniqueBundleName, buildParametersContext.Parameters.PackageName); - var taskList = SBPBuildTasks.Create(shadersBunldeName); + var taskList = SBPBuildTasks.Create(buildMapContext.ShadersBundleName); ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList); if (exitCode < 0) { throw new Exception($"构建过程中发生错误 : {exitCode}"); } - BuildRunner.Log("Unity引擎打包成功!"); + // 创建着色器信息 + // 说明:解决因为着色器资源包导致验证失败。 + // 例如:当项目里没有着色器,如果有依赖内置着色器就会验证失败。 + string shadersBundleName = buildMapContext.ShadersBundleName; + if (buildResults.BundleInfos.ContainsKey(shadersBundleName)) + { + buildMapContext.CreateShadersBundleInfo(shadersBundleName); + } + + BuildLogger.Log("Unity引擎打包成功!"); BuildResultContext buildResultContext = new BuildResultContext(); buildResultContext.Results = buildResults; context.SetContextObject(buildResultContext); - - // 拷贝原生文件 - if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) - { - CopyRawBundle(buildMapContext, buildParametersContext); - } - } - - /// - /// 拷贝原生文件 - /// - private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext) - { - string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); - foreach (var bundleInfo in buildMapContext.BundleInfos) - { - if (bundleInfo.IsRawFile) - { - string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; - foreach (var buildAsset in bundleInfo.BuildinAssets) - { - if (buildAsset.IsRawAsset) - EditorTools.CopyFile(buildAsset.AssetPath, dest, true); - } - } - } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyBuildinFiles.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyBuildinFiles.cs index 20b883d..fcb8a38 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyBuildinFiles.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyBuildinFiles.cs @@ -12,13 +12,13 @@ namespace YooAsset.Editor void IBuildTask.Run(BuildContext context) { var buildParametersContext = context.GetContextObject(); - var patchManifestContext = context.GetContextObject(); + var manifestContext = context.GetContextObject(); var buildMode = buildParametersContext.Parameters.BuildMode; if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) { if (buildParametersContext.Parameters.CopyBuildinFileOption != ECopyBuildinFileOption.None) { - CopyBuildinFilesToStreaming(buildParametersContext, patchManifestContext); + CopyBuildinFilesToStreaming(buildParametersContext, manifestContext); } } } @@ -26,7 +26,7 @@ namespace YooAsset.Editor /// /// 拷贝首包资源文件 /// - private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext, PatchManifestContext patchManifestContext) + private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext, ManifestContext manifestContext) { ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption; string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); @@ -35,7 +35,7 @@ namespace YooAsset.Editor string buildPackageVersion = buildParametersContext.Parameters.PackageVersion; // 加载补丁清单 - PatchManifest patchManifest = patchManifestContext.Manifest; + PackageManifest manifest = manifestContext.Manifest; // 清空流目录 if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags) @@ -70,10 +70,10 @@ namespace YooAsset.Editor // 拷贝文件列表(所有文件) if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.OnlyCopyAll) { - foreach (var patchBundle in patchManifest.BundleList) + foreach (var packageBundle in manifest.BundleList) { - string sourcePath = $"{packageOutputDirectory}/{patchBundle.FileName}"; - string destPath = $"{streamingAssetsDirectory}/{patchBundle.FileName}"; + string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}"; + string destPath = $"{streamingAssetsDirectory}/{packageBundle.FileName}"; EditorTools.CopyFile(sourcePath, destPath, true); } } @@ -82,19 +82,19 @@ namespace YooAsset.Editor if (option == ECopyBuildinFileOption.ClearAndCopyByTags || option == ECopyBuildinFileOption.OnlyCopyByTags) { string[] tags = buildParametersContext.Parameters.CopyBuildinFileTags.Split(';'); - foreach (var patchBundle in patchManifest.BundleList) + foreach (var packageBundle in manifest.BundleList) { - if (patchBundle.HasTag(tags) == false) + if (packageBundle.HasTag(tags) == false) continue; - string sourcePath = $"{packageOutputDirectory}/{patchBundle.FileName}"; - string destPath = $"{streamingAssetsDirectory}/{patchBundle.FileName}"; + string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}"; + string destPath = $"{streamingAssetsDirectory}/{packageBundle.FileName}"; EditorTools.CopyFile(sourcePath, destPath, true); } } // 刷新目录 AssetDatabase.Refresh(); - BuildRunner.Log($"内置文件拷贝完成:{streamingAssetsDirectory}"); + BuildLogger.Log($"内置文件拷贝完成:{streamingAssetsDirectory}"); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyRawFile.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyRawFile.cs new file mode 100644 index 0000000..661af52 --- /dev/null +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyRawFile.cs @@ -0,0 +1,44 @@ +using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset.Editor +{ + [TaskAttribute("拷贝原生文件")] + public class TaskCopyRawFile : IBuildTask + { + void IBuildTask.Run(BuildContext context) + { + var buildParametersContext = context.GetContextObject(); + var buildParameters = context.GetContextObject(); + var buildMapContext = context.GetContextObject(); + + var buildMode = buildParameters.Parameters.BuildMode; + if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) + { + CopyRawBundle(buildMapContext, buildParametersContext); + } + } + + /// + /// 拷贝原生文件 + /// + private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext) + { + string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); + foreach (var bundleInfo in buildMapContext.Collection) + { + if (bundleInfo.IsRawFile) + { + string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; + foreach (var assetInfo in bundleInfo.AllMainAssets) + { + if (assetInfo.IsRawAsset) + EditorTools.CopyFile(assetInfo.AssetPath, dest, true); + } + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapCreater.cs.meta b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyRawFile.cs.meta similarity index 83% rename from Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapCreater.cs.meta rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyRawFile.cs.meta index 8827383..a803fb3 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapCreater.cs.meta +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCopyRawFile.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e9274735f1f14af4b893c21a4240b816 +guid: 3625d4b8b5b79324ebf7ec19a87677e7 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateManifest.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateManifest.cs new file mode 100644 index 0000000..310e36f --- /dev/null +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateManifest.cs @@ -0,0 +1,368 @@ +using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; + +using UnityEditor.Build.Pipeline; +using UnityEditor.Build.Pipeline.Interfaces; + +namespace YooAsset.Editor +{ + public class ManifestContext : IContextObject + { + internal PackageManifest Manifest; + } + + [TaskAttribute("创建清单文件")] + public class TaskCreateManifest : IBuildTask + { + void IBuildTask.Run(BuildContext context) + { + CreateManifestFile(context); + } + + /// + /// 创建补丁清单文件到输出目录 + /// + private void CreateManifestFile(BuildContext context) + { + var buildMapContext = context.GetContextObject(); + var buildParametersContext = context.GetContextObject(); + var buildParameters = buildParametersContext.Parameters; + string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); + + // 创建新补丁清单 + PackageManifest manifest = new PackageManifest(); + manifest.FileVersion = YooAssetSettings.ManifestFileVersion; + manifest.EnableAddressable = buildMapContext.EnableAddressable; + manifest.OutputNameStyle = (int)buildParameters.OutputNameStyle; + manifest.PackageName = buildParameters.PackageName; + manifest.PackageVersion = buildParameters.PackageVersion; + manifest.BundleList = GetAllPackageBundle(context); + manifest.AssetList = GetAllPackageAsset(context, manifest); + + // 更新Unity内置资源包的引用关系 + if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline) + { + if (buildParameters.BuildMode == EBuildMode.IncrementalBuild) + { + var buildResultContext = context.GetContextObject(); + UpdateBuiltInBundleReference(manifest, buildResultContext, buildMapContext.ShadersBundleName); + } + } + + // 更新资源包之间的引用关系 + if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline) + { + if (buildParameters.BuildMode == EBuildMode.IncrementalBuild) + { + var buildResultContext = context.GetContextObject(); + UpdateScriptPipelineReference(manifest, buildResultContext); + } + } + + // 更新资源包之间的引用关系 + if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline) + { + if (buildParameters.BuildMode != EBuildMode.SimulateBuild) + { + var buildResultContext = context.GetContextObject(); + UpdateBuiltinPipelineReference(manifest, buildResultContext); + } + } + + // 创建补丁清单文本文件 + { + string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion); + string filePath = $"{packageOutputDirectory}/{fileName}"; + ManifestTools.SerializeToJson(filePath, manifest); + BuildLogger.Log($"创建补丁清单文件:{filePath}"); + } + + // 创建补丁清单二进制文件 + string packageHash; + { + string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion); + string filePath = $"{packageOutputDirectory}/{fileName}"; + ManifestTools.SerializeToBinary(filePath, manifest); + packageHash = HashUtility.FileMD5(filePath); + BuildLogger.Log($"创建补丁清单文件:{filePath}"); + + ManifestContext manifestContext = new ManifestContext(); + byte[] bytesData = FileUtility.ReadAllBytes(filePath); + manifestContext.Manifest = ManifestTools.DeserializeFromBinary(bytesData); + context.SetContextObject(manifestContext); + } + + // 创建补丁清单哈希文件 + { + string fileName = YooAssetSettingsData.GetPackageHashFileName(buildParameters.PackageName, buildParameters.PackageVersion); + string filePath = $"{packageOutputDirectory}/{fileName}"; + FileUtility.CreateFile(filePath, packageHash); + BuildLogger.Log($"创建补丁清单哈希文件:{filePath}"); + } + + // 创建补丁清单版本文件 + { + string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildParameters.PackageName); + string filePath = $"{packageOutputDirectory}/{fileName}"; + FileUtility.CreateFile(filePath, buildParameters.PackageVersion); + BuildLogger.Log($"创建补丁清单版本文件:{filePath}"); + } + } + + /// + /// 获取资源包列表 + /// + private List GetAllPackageBundle(BuildContext context) + { + var buildMapContext = context.GetContextObject(); + + List result = new List(1000); + foreach (var bundleInfo in buildMapContext.Collection) + { + var packageBundle = bundleInfo.CreatePackageBundle(); + result.Add(packageBundle); + } + return result; + } + + /// + /// 获取资源列表 + /// + private List GetAllPackageAsset(BuildContext context, PackageManifest manifest) + { + var buildMapContext = context.GetContextObject(); + + List result = new List(1000); + foreach (var bundleInfo in buildMapContext.Collection) + { + var assetInfos = bundleInfo.GetAllMainAssetInfos(); + foreach (var assetInfo in assetInfos) + { + PackageAsset packageAsset = new PackageAsset(); + if (buildMapContext.EnableAddressable) + packageAsset.Address = assetInfo.Address; + else + packageAsset.Address = string.Empty; + packageAsset.AssetPath = assetInfo.AssetPath; + packageAsset.AssetTags = assetInfo.AssetTags.ToArray(); + packageAsset.BundleID = GetAssetBundleID(assetInfo.BundleName, manifest); + packageAsset.DependIDs = GetAssetBundleDependIDs(packageAsset.BundleID, assetInfo, manifest); + result.Add(packageAsset); + } + } + return result; + } + private int[] GetAssetBundleDependIDs(int mainBundleID, BuildAssetInfo assetInfo, PackageManifest manifest) + { + List result = new List(); + foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos) + { + if (dependAssetInfo.HasBundleName()) + { + int bundleID = GetAssetBundleID(dependAssetInfo.BundleName, manifest); + if (mainBundleID != bundleID) + { + if (result.Contains(bundleID) == false) + result.Add(bundleID); + } + } + } + return result.ToArray(); + } + private int GetAssetBundleID(string bundleName, PackageManifest manifest) + { + for (int index = 0; index < manifest.BundleList.Count; index++) + { + if (manifest.BundleList[index].BundleName == bundleName) + return index; + } + throw new Exception($"Not found bundle name : {bundleName}"); + } + + /// + /// 更新Unity内置资源包的引用关系 + /// + private void UpdateBuiltInBundleReference(PackageManifest manifest, TaskBuilding_SBP.BuildResultContext buildResultContext, string shadersBunldeName) + { + // 获取所有依赖着色器资源包的资源包列表 + List shaderBundleReferenceList = new List(); + foreach (var valuePair in buildResultContext.Results.BundleInfos) + { + if (valuePair.Value.Dependencies.Any(t => t == shadersBunldeName)) + shaderBundleReferenceList.Add(valuePair.Key); + } + + // 注意:没有任何资源依赖着色器 + if (shaderBundleReferenceList.Count == 0) + return; + + // 获取着色器资源包索引 + Predicate predicate = new Predicate(s => s.BundleName == shadersBunldeName); + int shaderBundleId = manifest.BundleList.FindIndex(predicate); + if (shaderBundleId == -1) + throw new Exception("没有发现着色器资源包!"); + + // 检测依赖交集并更新依赖ID + foreach (var packageAsset in manifest.AssetList) + { + List dependBundles = GetPackageAssetAllDependBundles(manifest, packageAsset); + List conflictAssetPathList = dependBundles.Intersect(shaderBundleReferenceList).ToList(); + if (conflictAssetPathList.Count > 0) + { + List newDependIDs = new List(packageAsset.DependIDs); + if (newDependIDs.Contains(shaderBundleId) == false) + newDependIDs.Add(shaderBundleId); + packageAsset.DependIDs = newDependIDs.ToArray(); + } + } + } + private List GetPackageAssetAllDependBundles(PackageManifest manifest, PackageAsset packageAsset) + { + List result = new List(); + string mainBundle = manifest.BundleList[packageAsset.BundleID].BundleName; + result.Add(mainBundle); + foreach (var dependID in packageAsset.DependIDs) + { + string dependBundle = manifest.BundleList[dependID].BundleName; + result.Add(dependBundle); + } + return result; + } + + #region 资源包引用关系相关 + private readonly Dictionary _cachedBundleID = new Dictionary(10000); + private readonly Dictionary _cachedBundleDepends = new Dictionary(10000); + + private void UpdateScriptPipelineReference(PackageManifest manifest, TaskBuilding_SBP.BuildResultContext buildResultContext) + { + int progressValue; + int totalCount = manifest.BundleList.Count; + + // 缓存资源包ID + _cachedBundleID.Clear(); + progressValue = 0; + foreach (var packageBundle in manifest.BundleList) + { + int bundleID = GetAssetBundleID(packageBundle.BundleName, manifest); + _cachedBundleID.Add(packageBundle.BundleName, bundleID); + EditorTools.DisplayProgressBar("缓存资源包索引", ++progressValue, totalCount); + } + EditorTools.ClearProgressBar(); + + // 缓存资源包依赖 + _cachedBundleDepends.Clear(); + progressValue = 0; + foreach (var packageBundle in manifest.BundleList) + { + if (packageBundle.IsRawFile) + { + _cachedBundleDepends.Add(packageBundle.BundleName, new string[] { }); + continue; + } + + if (buildResultContext.Results.BundleInfos.ContainsKey(packageBundle.BundleName) == false) + throw new Exception($"Not found bundle in SBP build results : {packageBundle.BundleName}"); + + var depends = buildResultContext.Results.BundleInfos[packageBundle.BundleName].Dependencies; + _cachedBundleDepends.Add(packageBundle.BundleName, depends); + EditorTools.DisplayProgressBar("缓存资源包依赖列表", ++progressValue, totalCount); + } + EditorTools.ClearProgressBar(); + + // 计算资源包引用列表 + foreach (var packageBundle in manifest.BundleList) + { + packageBundle.ReferenceIDs = GetBundleRefrenceIDs(manifest, packageBundle); + EditorTools.DisplayProgressBar("计算资源包引用关系", ++progressValue, totalCount); + } + EditorTools.ClearProgressBar(); + } + private void UpdateBuiltinPipelineReference(PackageManifest manifest, TaskBuilding.BuildResultContext buildResultContext) + { + int progressValue; + int totalCount = manifest.BundleList.Count; + + // 缓存资源包ID + _cachedBundleID.Clear(); + progressValue = 0; + foreach (var packageBundle in manifest.BundleList) + { + int bundleID = GetAssetBundleID(packageBundle.BundleName, manifest); + _cachedBundleID.Add(packageBundle.BundleName, bundleID); + EditorTools.DisplayProgressBar("缓存资源包索引", ++progressValue, totalCount); + } + EditorTools.ClearProgressBar(); + + // 缓存资源包依赖 + _cachedBundleDepends.Clear(); + progressValue = 0; + foreach (var packageBundle in manifest.BundleList) + { + if (packageBundle.IsRawFile) + { + _cachedBundleDepends.Add(packageBundle.BundleName, new string[] { } ); + continue; + } + + var depends = buildResultContext.UnityManifest.GetDirectDependencies(packageBundle.BundleName); + _cachedBundleDepends.Add(packageBundle.BundleName, depends); + EditorTools.DisplayProgressBar("缓存资源包依赖列表", ++progressValue, totalCount); + } + EditorTools.ClearProgressBar(); + + // 计算资源包引用列表 + progressValue = 0; + foreach (var packageBundle in manifest.BundleList) + { + packageBundle.ReferenceIDs = GetBundleRefrenceIDs(manifest, packageBundle); + EditorTools.DisplayProgressBar("计算资源包引用关系", ++progressValue, totalCount); + } + EditorTools.ClearProgressBar(); + } + + private int[] GetBundleRefrenceIDs(PackageManifest manifest, PackageBundle targetBundle) + { + List referenceList = new List(); + foreach (var packageBundle in manifest.BundleList) + { + string bundleName = packageBundle.BundleName; + if (bundleName == targetBundle.BundleName) + continue; + + string[] dependencies = GetCachedBundleDepends(bundleName); + if (dependencies.Contains(targetBundle.BundleName)) + { + referenceList.Add(bundleName); + } + } + + List result = new List(); + foreach (var bundleName in referenceList) + { + int bundleID = GetCachedBundleID(bundleName); + if (result.Contains(bundleID) == false) + result.Add(bundleID); + } + return result.ToArray(); + } + private int GetCachedBundleID(string bundleName) + { + if (_cachedBundleID.TryGetValue(bundleName, out int value) == false) + { + throw new Exception($"Not found cached bundle ID : {bundleName}"); + } + return value; + } + private string[] GetCachedBundleDepends(string bundleName) + { + if (_cachedBundleDepends.TryGetValue(bundleName, out string[] value) == false) + { + throw new Exception($"Not found cached bundle depends : {bundleName}"); + } + return value; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchManifest.cs.meta b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateManifest.cs.meta similarity index 100% rename from Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchManifest.cs.meta rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateManifest.cs.meta diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchPackage.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePackage.cs similarity index 79% rename from Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchPackage.cs rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePackage.cs index 954c73f..4f891bb 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchPackage.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePackage.cs @@ -3,8 +3,8 @@ using System.Collections.Generic; namespace YooAsset.Editor { - [TaskAttribute("制作补丁包")] - public class TaskCreatePatchPackage : IBuildTask + [TaskAttribute("制作包裹")] + public class TaskCreatePackage : IBuildTask { void IBuildTask.Run(BuildContext context) { @@ -13,19 +13,19 @@ namespace YooAsset.Editor var buildMode = buildParameters.Parameters.BuildMode; if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) { - CopyPatchFiles(buildParameters, buildMapContext); + CopyPackageFiles(buildParameters, buildMapContext); } } /// /// 拷贝补丁文件到补丁包目录 /// - private void CopyPatchFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext) + private void CopyPackageFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext) { var buildParameters = buildParametersContext.Parameters; string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); - BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}"); + BuildLogger.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}"); if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline) { @@ -67,11 +67,11 @@ namespace YooAsset.Editor // 拷贝所有补丁文件 int progressValue = 0; - int patchFileTotalCount = buildMapContext.BundleInfos.Count; - foreach (var bundleInfo in buildMapContext.BundleInfos) + int fileTotalCount = buildMapContext.Collection.Count; + foreach (var bundleInfo in buildMapContext.Collection) { - EditorTools.CopyFile(bundleInfo.PatchInfo.BuildOutputFilePath, bundleInfo.PatchInfo.PatchOutputFilePath, true); - EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount); + EditorTools.CopyFile(bundleInfo.BundleInfo.BuildOutputFilePath, bundleInfo.BundleInfo.PackageOutputFilePath, true); + EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, fileTotalCount); } EditorTools.ClearProgressBar(); } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchPackage.cs.meta b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePackage.cs.meta similarity index 100% rename from Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchPackage.cs.meta rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePackage.cs.meta diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchManifest.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchManifest.cs deleted file mode 100644 index 2982c84..0000000 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreatePatchManifest.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System; -using System.Linq; -using System.Collections; -using System.Collections.Generic; - -using UnityEditor.Build.Pipeline; -using UnityEditor.Build.Pipeline.Interfaces; - -namespace YooAsset.Editor -{ - public class PatchManifestContext : IContextObject - { - internal PatchManifest Manifest; - } - - [TaskAttribute("创建补丁清单文件")] - public class TaskCreatePatchManifest : IBuildTask - { - void IBuildTask.Run(BuildContext context) - { - CreatePatchManifestFile(context); - } - - /// - /// 创建补丁清单文件到输出目录 - /// - private void CreatePatchManifestFile(BuildContext context) - { - var buildMapContext = context.GetContextObject(); - var buildParametersContext = context.GetContextObject(); - var buildParameters = buildParametersContext.Parameters; - string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); - - // 创建新补丁清单 - PatchManifest patchManifest = new PatchManifest(); - patchManifest.FileVersion = YooAssetSettings.PatchManifestFileVersion; - patchManifest.EnableAddressable = buildMapContext.EnableAddressable; - patchManifest.OutputNameStyle = (int)buildParameters.OutputNameStyle; - patchManifest.PackageName = buildParameters.PackageName; - patchManifest.PackageVersion = buildParameters.PackageVersion; - patchManifest.BundleList = GetAllPatchBundle(context); - patchManifest.AssetList = GetAllPatchAsset(context, patchManifest); - - // 更新Unity内置资源包的引用关系 - string shadersBunldeName = YooAssetSettingsData.GetUnityShadersBundleFullName(buildMapContext.UniqueBundleName, buildParameters.PackageName); - if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline) - { - if (buildParameters.BuildMode == EBuildMode.IncrementalBuild) - { - var buildResultContext = context.GetContextObject(); - UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results, shadersBunldeName); - } - } - - // 创建补丁清单文本文件 - { - string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion); - string filePath = $"{packageOutputDirectory}/{fileName}"; - PatchManifestTools.SerializeToJson(filePath, patchManifest); - BuildRunner.Log($"创建补丁清单文件:{filePath}"); - } - - // 创建补丁清单二进制文件 - string packageHash; - { - string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion); - string filePath = $"{packageOutputDirectory}/{fileName}"; - PatchManifestTools.SerializeToBinary(filePath, patchManifest); - packageHash = HashUtility.FileMD5(filePath); - BuildRunner.Log($"创建补丁清单文件:{filePath}"); - - PatchManifestContext patchManifestContext = new PatchManifestContext(); - byte[] bytesData = FileUtility.ReadAllBytes(filePath); - patchManifestContext.Manifest = PatchManifestTools.DeserializeFromBinary(bytesData); - context.SetContextObject(patchManifestContext); - } - - // 创建补丁清单哈希文件 - { - string fileName = YooAssetSettingsData.GetPackageHashFileName(buildParameters.PackageName, buildParameters.PackageVersion); - string filePath = $"{packageOutputDirectory}/{fileName}"; - FileUtility.CreateFile(filePath, packageHash); - BuildRunner.Log($"创建补丁清单哈希文件:{filePath}"); - } - - // 创建补丁清单版本文件 - { - string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildParameters.PackageName); - string filePath = $"{packageOutputDirectory}/{fileName}"; - FileUtility.CreateFile(filePath, buildParameters.PackageVersion); - BuildRunner.Log($"创建补丁清单版本文件:{filePath}"); - } - } - - /// - /// 获取资源包列表 - /// - private List GetAllPatchBundle(BuildContext context) - { - var buildMapContext = context.GetContextObject(); - var buildParametersContext = context.GetContextObject(); - - List result = new List(1000); - foreach (var bundleInfo in buildMapContext.BundleInfos) - { - var patchBundle = bundleInfo.CreatePatchBundle(); - result.Add(patchBundle); - } - return result; - } - - /// - /// 获取资源列表 - /// - private List GetAllPatchAsset(BuildContext context, PatchManifest patchManifest) - { - var buildMapContext = context.GetContextObject(); - - List result = new List(1000); - foreach (var bundleInfo in buildMapContext.BundleInfos) - { - var assetInfos = bundleInfo.GetAllPatchAssetInfos(); - foreach (var assetInfo in assetInfos) - { - PatchAsset patchAsset = new PatchAsset(); - if (buildMapContext.EnableAddressable) - patchAsset.Address = assetInfo.Address; - else - patchAsset.Address = string.Empty; - patchAsset.AssetPath = assetInfo.AssetPath; - patchAsset.AssetTags = assetInfo.AssetTags.ToArray(); - patchAsset.BundleID = GetAssetBundleID(assetInfo.GetBundleName(), patchManifest); - patchAsset.DependIDs = GetAssetBundleDependIDs(patchAsset.BundleID, assetInfo, patchManifest); - result.Add(patchAsset); - } - } - return result; - } - private int[] GetAssetBundleDependIDs(int mainBundleID, BuildAssetInfo assetInfo, PatchManifest patchManifest) - { - List result = new List(); - foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos) - { - if (dependAssetInfo.HasBundleName()) - { - int bundleID = GetAssetBundleID(dependAssetInfo.GetBundleName(), patchManifest); - if (mainBundleID != bundleID) - { - if (result.Contains(bundleID) == false) - result.Add(bundleID); - } - } - } - return result.ToArray(); - } - private int GetAssetBundleID(string bundleName, PatchManifest patchManifest) - { - for (int index = 0; index < patchManifest.BundleList.Count; index++) - { - if (patchManifest.BundleList[index].BundleName == bundleName) - return index; - } - throw new Exception($"Not found bundle name : {bundleName}"); - } - - /// - /// 更新Unity内置资源包的引用关系 - /// - private void UpdateBuiltInBundleReference(PatchManifest patchManifest, IBundleBuildResults buildResults, string shadersBunldeName) - { - // 获取所有依赖着色器资源包的资源包列表 - List shaderBundleReferenceList = new List(); - foreach (var valuePair in buildResults.BundleInfos) - { - if (valuePair.Value.Dependencies.Any(t => t == shadersBunldeName)) - shaderBundleReferenceList.Add(valuePair.Key); - } - - // 注意:没有任何资源依赖着色器 - if (shaderBundleReferenceList.Count == 0) - return; - - // 获取着色器资源包索引 - Predicate predicate = new Predicate(s => s.BundleName == shadersBunldeName); - int shaderBundleId = patchManifest.BundleList.FindIndex(predicate); - if (shaderBundleId == -1) - throw new Exception("没有发现着色器资源包!"); - - // 检测依赖交集并更新依赖ID - foreach (var patchAsset in patchManifest.AssetList) - { - List dependBundles = GetPatchAssetAllDependBundles(patchManifest, patchAsset); - List conflictAssetPathList = dependBundles.Intersect(shaderBundleReferenceList).ToList(); - if (conflictAssetPathList.Count > 0) - { - List newDependIDs = new List(patchAsset.DependIDs); - if (newDependIDs.Contains(shaderBundleId) == false) - newDependIDs.Add(shaderBundleId); - patchAsset.DependIDs = newDependIDs.ToArray(); - } - } - } - private List GetPatchAssetAllDependBundles(PatchManifest patchManifest, PatchAsset patchAsset) - { - List result = new List(); - string mainBundle = patchManifest.BundleList[patchAsset.BundleID].BundleName; - result.Add(mainBundle); - foreach (var dependID in patchAsset.DependIDs) - { - string dependBundle = patchManifest.BundleList[dependID].BundleName; - result.Add(dependBundle); - } - return result; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateReport.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateReport.cs index 4969c22..3b65c33 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateReport.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateReport.cs @@ -12,25 +12,21 @@ namespace YooAsset.Editor { var buildParameters = context.GetContextObject(); var buildMapContext = context.GetContextObject(); - var patchManifestContext = context.GetContextObject(); - buildParameters.StopWatch(); + var manifestContext = context.GetContextObject(); var buildMode = buildParameters.Parameters.BuildMode; if (buildMode != EBuildMode.SimulateBuild) { - CreateReportFile(buildParameters, buildMapContext, patchManifestContext); + CreateReportFile(buildParameters, buildMapContext, manifestContext); } - - float buildSeconds = buildParameters.GetBuildingSeconds(); - BuildRunner.Info($"Build time consuming {buildSeconds} seconds."); } - private void CreateReportFile(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext, PatchManifestContext patchManifestContext) + private void CreateReportFile(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext, ManifestContext manifestContext) { var buildParameters = buildParametersContext.Parameters; string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); - PatchManifest patchManifest = patchManifestContext.Manifest; + PackageManifest manifest = manifestContext.Manifest; BuildReport buildReport = new BuildReport(); // 概述信息 @@ -42,7 +38,7 @@ namespace YooAsset.Editor #endif buildReport.Summary.UnityVersion = UnityEngine.Application.unityVersion; buildReport.Summary.BuildDate = DateTime.Now.ToString(); - buildReport.Summary.BuildSeconds = (int)buildParametersContext.GetBuildingSeconds(); + buildReport.Summary.BuildSeconds = BuildRunner.TotalSeconds; buildReport.Summary.BuildTarget = buildParameters.BuildTarget; buildReport.Summary.BuildPipeline = buildParameters.BuildPipeline; buildReport.Summary.BuildMode = buildParameters.BuildMode; @@ -61,45 +57,47 @@ namespace YooAsset.Editor // 构建结果 buildReport.Summary.AssetFileTotalCount = buildMapContext.AssetFileCount; - buildReport.Summary.MainAssetTotalCount = GetMainAssetCount(patchManifest); - buildReport.Summary.AllBundleTotalCount = GetAllBundleCount(patchManifest); - buildReport.Summary.AllBundleTotalSize = GetAllBundleSize(patchManifest); - buildReport.Summary.EncryptedBundleTotalCount = GetEncryptedBundleCount(patchManifest); - buildReport.Summary.EncryptedBundleTotalSize = GetEncryptedBundleSize(patchManifest); - buildReport.Summary.RawBundleTotalCount = GetRawBundleCount(patchManifest); - buildReport.Summary.RawBundleTotalSize = GetRawBundleSize(patchManifest); + buildReport.Summary.MainAssetTotalCount = GetMainAssetCount(manifest); + buildReport.Summary.AllBundleTotalCount = GetAllBundleCount(manifest); + buildReport.Summary.AllBundleTotalSize = GetAllBundleSize(manifest); + buildReport.Summary.EncryptedBundleTotalCount = GetEncryptedBundleCount(manifest); + buildReport.Summary.EncryptedBundleTotalSize = GetEncryptedBundleSize(manifest); + buildReport.Summary.RawBundleTotalCount = GetRawBundleCount(manifest); + buildReport.Summary.RawBundleTotalSize = GetRawBundleSize(manifest); } // 资源对象列表 - buildReport.AssetInfos = new List(patchManifest.AssetList.Count); - foreach (var patchAsset in patchManifest.AssetList) + buildReport.AssetInfos = new List(manifest.AssetList.Count); + foreach (var packageAsset in manifest.AssetList) { - var mainBundle = patchManifest.BundleList[patchAsset.BundleID]; + var mainBundle = manifest.BundleList[packageAsset.BundleID]; ReportAssetInfo reportAssetInfo = new ReportAssetInfo(); - reportAssetInfo.Address = patchAsset.Address; - reportAssetInfo.AssetPath = patchAsset.AssetPath; - reportAssetInfo.AssetTags = patchAsset.AssetTags; - reportAssetInfo.AssetGUID = AssetDatabase.AssetPathToGUID(patchAsset.AssetPath); + reportAssetInfo.Address = packageAsset.Address; + reportAssetInfo.AssetPath = packageAsset.AssetPath; + reportAssetInfo.AssetTags = packageAsset.AssetTags; + reportAssetInfo.AssetGUID = AssetDatabase.AssetPathToGUID(packageAsset.AssetPath); reportAssetInfo.MainBundleName = mainBundle.BundleName; reportAssetInfo.MainBundleSize = mainBundle.FileSize; - reportAssetInfo.DependBundles = GetDependBundles(patchManifest, patchAsset); - reportAssetInfo.DependAssets = GetDependAssets(buildMapContext, mainBundle.BundleName, patchAsset.AssetPath); + reportAssetInfo.DependBundles = GetDependBundles(manifest, packageAsset); + reportAssetInfo.DependAssets = GetDependAssets(buildMapContext, mainBundle.BundleName, packageAsset.AssetPath); buildReport.AssetInfos.Add(reportAssetInfo); } // 资源包列表 - buildReport.BundleInfos = new List(patchManifest.BundleList.Count); - foreach (var patchBundle in patchManifest.BundleList) + buildReport.BundleInfos = new List(manifest.BundleList.Count); + foreach (var packageBundle in manifest.BundleList) { ReportBundleInfo reportBundleInfo = new ReportBundleInfo(); - reportBundleInfo.BundleName = patchBundle.BundleName; - reportBundleInfo.FileName = patchBundle.FileName; - reportBundleInfo.FileHash = patchBundle.FileHash; - reportBundleInfo.FileCRC = patchBundle.FileCRC; - reportBundleInfo.FileSize = patchBundle.FileSize; - reportBundleInfo.Tags = patchBundle.Tags; - reportBundleInfo.IsRawFile = patchBundle.IsRawFile; - reportBundleInfo.LoadMethod = (EBundleLoadMethod)patchBundle.LoadMethod; + reportBundleInfo.BundleName = packageBundle.BundleName; + reportBundleInfo.FileName = packageBundle.FileName; + reportBundleInfo.FileHash = packageBundle.FileHash; + reportBundleInfo.FileCRC = packageBundle.FileCRC; + reportBundleInfo.FileSize = packageBundle.FileSize; + reportBundleInfo.IsRawFile = packageBundle.IsRawFile; + reportBundleInfo.LoadMethod = (EBundleLoadMethod)packageBundle.LoadMethod; + reportBundleInfo.Tags = packageBundle.Tags; + reportBundleInfo.ReferenceIDs = packageBundle.ReferenceIDs; + reportBundleInfo.AllBuiltinAssets = GetAllBuiltinAssets(buildMapContext, packageBundle.BundleName); buildReport.BundleInfos.Add(reportBundleInfo); } @@ -107,18 +105,18 @@ namespace YooAsset.Editor string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion); string filePath = $"{packageOutputDirectory}/{fileName}"; BuildReport.Serialize(filePath, buildReport); - BuildRunner.Log($"资源构建报告文件创建完成:{filePath}"); + BuildLogger.Log($"资源构建报告文件创建完成:{filePath}"); } /// /// 获取资源对象依赖的所有资源包 /// - private List GetDependBundles(PatchManifest patchManifest, PatchAsset patchAsset) + private List GetDependBundles(PackageManifest manifest, PackageAsset packageAsset) { - List dependBundles = new List(patchAsset.DependIDs.Length); - foreach (int index in patchAsset.DependIDs) + List dependBundles = new List(packageAsset.DependIDs.Length); + foreach (int index in packageAsset.DependIDs) { - string dependBundleName = patchManifest.BundleList[index].BundleName; + string dependBundleName = manifest.BundleList[index].BundleName; dependBundles.Add(dependBundleName); } return dependBundles; @@ -130,14 +128,14 @@ namespace YooAsset.Editor private List GetDependAssets(BuildMapContext buildMapContext, string bundleName, string assetPath) { List result = new List(); - if (buildMapContext.TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo)) + var bundleInfo = buildMapContext.GetBundleInfo(bundleName); { BuildAssetInfo findAssetInfo = null; - foreach (var buildinAsset in bundleInfo.BuildinAssets) + foreach (var assetInfo in bundleInfo.AllMainAssets) { - if (buildinAsset.AssetPath == assetPath) + if (assetInfo.AssetPath == assetPath) { - findAssetInfo = buildinAsset; + findAssetInfo = assetInfo; break; } } @@ -150,67 +148,72 @@ namespace YooAsset.Editor result.Add(dependAssetInfo.AssetPath); } } - else - { - throw new Exception($"Not found bundle : {bundleName}"); - } return result; } - private int GetMainAssetCount(PatchManifest patchManifest) + /// + /// 获取该资源包内的所有资源(包括零依赖资源) + /// + private List GetAllBuiltinAssets(BuildMapContext buildMapContext, string bundleName) { - return patchManifest.AssetList.Count; + var bundleInfo = buildMapContext.GetBundleInfo(bundleName); + return bundleInfo.GetAllBuiltinAssetPaths(); } - private int GetAllBundleCount(PatchManifest patchManifest) + + private int GetMainAssetCount(PackageManifest manifest) { - return patchManifest.BundleList.Count; + return manifest.AssetList.Count; } - private long GetAllBundleSize(PatchManifest patchManifest) + private int GetAllBundleCount(PackageManifest manifest) + { + return manifest.BundleList.Count; + } + private long GetAllBundleSize(PackageManifest manifest) { long fileBytes = 0; - foreach (var patchBundle in patchManifest.BundleList) + foreach (var packageBundle in manifest.BundleList) { - fileBytes += patchBundle.FileSize; + fileBytes += packageBundle.FileSize; } return fileBytes; } - private int GetEncryptedBundleCount(PatchManifest patchManifest) + private int GetEncryptedBundleCount(PackageManifest manifest) { int fileCount = 0; - foreach (var patchBundle in patchManifest.BundleList) + foreach (var packageBundle in manifest.BundleList) { - if (patchBundle.LoadMethod != (byte)EBundleLoadMethod.Normal) + if (packageBundle.LoadMethod != (byte)EBundleLoadMethod.Normal) fileCount++; } return fileCount; } - private long GetEncryptedBundleSize(PatchManifest patchManifest) + private long GetEncryptedBundleSize(PackageManifest manifest) { long fileBytes = 0; - foreach (var patchBundle in patchManifest.BundleList) + foreach (var packageBundle in manifest.BundleList) { - if (patchBundle.LoadMethod != (byte)EBundleLoadMethod.Normal) - fileBytes += patchBundle.FileSize; + if (packageBundle.LoadMethod != (byte)EBundleLoadMethod.Normal) + fileBytes += packageBundle.FileSize; } return fileBytes; } - private int GetRawBundleCount(PatchManifest patchManifest) + private int GetRawBundleCount(PackageManifest manifest) { int fileCount = 0; - foreach (var patchBundle in patchManifest.BundleList) + foreach (var packageBundle in manifest.BundleList) { - if (patchBundle.IsRawFile) + if (packageBundle.IsRawFile) fileCount++; } return fileCount; } - private long GetRawBundleSize(PatchManifest patchManifest) + private long GetRawBundleSize(PackageManifest manifest) { long fileBytes = 0; - foreach (var patchBundle in patchManifest.BundleList) + foreach (var packageBundle in manifest.BundleList) { - if (patchBundle.IsRawFile) - fileBytes += patchBundle.FileSize; + if (packageBundle.IsRawFile) + fileBytes += packageBundle.FileSize; } return fileBytes; } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskEncryption.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskEncryption.cs index 96ffe6a..ab4e64b 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskEncryption.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskEncryption.cs @@ -27,17 +27,16 @@ namespace YooAsset.Editor private void EncryptingBundleFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext) { var encryptionServices = buildParametersContext.Parameters.EncryptionServices; - - // 如果没有设置加密类 if (encryptionServices == null) return; + if (encryptionServices.GetType() == typeof(EncryptionNone)) + return; + int progressValue = 0; string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); - foreach (var bundleInfo in buildMapContext.BundleInfos) + foreach (var bundleInfo in buildMapContext.Collection) { - bundleInfo.LoadMethod = EBundleLoadMethod.Normal; - EncryptFileInfo fileInfo = new EncryptFileInfo(); fileInfo.BundleName = bundleInfo.BundleName; fileInfo.FilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; @@ -48,7 +47,7 @@ namespace YooAsset.Editor // 注意:原生文件不支持加密 if (bundleInfo.IsRawFile) { - UnityEngine.Debug.LogWarning($"Encryption not support raw file : {bundleInfo.BundleName}"); + BuildLogger.Warning($"Encryption not support raw file : {bundleInfo.BundleName}"); continue; } @@ -56,11 +55,11 @@ namespace YooAsset.Editor FileUtility.CreateFile(filePath, encryptResult.EncryptedData); bundleInfo.EncryptedFilePath = filePath; bundleInfo.LoadMethod = encryptResult.LoadMethod; - BuildRunner.Log($"Bundle文件加密完成:{filePath}"); + BuildLogger.Log($"Bundle文件加密完成:{filePath}"); } // 进度条 - EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.BundleInfos.Count); + EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.Collection.Count); } EditorTools.ClearProgressBar(); } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskGetBuildMap.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskGetBuildMap.cs index 2cc5396..f3cd9a8 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskGetBuildMap.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskGetBuildMap.cs @@ -13,32 +13,188 @@ namespace YooAsset.Editor void IBuildTask.Run(BuildContext context) { var buildParametersContext = context.GetContextObject(); - var buildMapContext = BuildMapCreater.CreateBuildMap(buildParametersContext.Parameters.BuildMode, buildParametersContext.Parameters.PackageName); + var buildMapContext = CreateBuildMap(buildParametersContext.Parameters.BuildMode, buildParametersContext.Parameters.PackageName); context.SetContextObject(buildMapContext); - BuildRunner.Log("构建内容准备完毕!"); + BuildLogger.Log("构建内容准备完毕!"); // 检测构建结果 CheckBuildMapContent(buildMapContext); } + /// + /// 资源构建上下文 + /// + public BuildMapContext CreateBuildMap(EBuildMode buildMode, string packageName) + { + Dictionary allBuildAssetInfoDic = new Dictionary(1000); + + // 1. 检测配置合法性 + AssetBundleCollectorSettingData.Setting.CheckConfigError(); + + // 2. 获取所有收集器收集的资源 + var collectResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName); + List allCollectAssetInfos = collectResult.CollectAssets; + + // 3. 剔除未被引用的依赖项资源 + RemoveZeroReferenceAssets(allCollectAssetInfos); + + // 4. 录入所有收集器收集的资源 + foreach (var collectAssetInfo in allCollectAssetInfos) + { + if (allBuildAssetInfoDic.ContainsKey(collectAssetInfo.AssetPath) == false) + { + var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.CollectorType, collectAssetInfo.BundleName, + collectAssetInfo.Address, collectAssetInfo.AssetPath, collectAssetInfo.IsRawAsset); + buildAssetInfo.AddAssetTags(collectAssetInfo.AssetTags); + buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags); + allBuildAssetInfoDic.Add(collectAssetInfo.AssetPath, buildAssetInfo); + } + else + { + throw new Exception($"Should never get here !"); + } + } + + // 5. 录入所有收集资源的依赖资源 + foreach (var collectAssetInfo in allCollectAssetInfos) + { + string collectAssetBundleName = collectAssetInfo.BundleName; + foreach (var dependAssetPath in collectAssetInfo.DependAssets) + { + if (allBuildAssetInfoDic.ContainsKey(dependAssetPath)) + { + allBuildAssetInfoDic[dependAssetPath].AddBundleTags(collectAssetInfo.AssetTags); + allBuildAssetInfoDic[dependAssetPath].AddReferenceBundleName(collectAssetBundleName); + } + else + { + var buildAssetInfo = new BuildAssetInfo(dependAssetPath); + buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags); + buildAssetInfo.AddReferenceBundleName(collectAssetBundleName); + allBuildAssetInfoDic.Add(dependAssetPath, buildAssetInfo); + } + } + } + + // 6. 填充所有收集资源的依赖列表 + foreach (var collectAssetInfo in allCollectAssetInfos) + { + var dependAssetInfos = new List(collectAssetInfo.DependAssets.Count); + foreach (var dependAssetPath in collectAssetInfo.DependAssets) + { + if (allBuildAssetInfoDic.TryGetValue(dependAssetPath, out BuildAssetInfo value)) + dependAssetInfos.Add(value); + else + throw new Exception("Should never get here !"); + } + allBuildAssetInfoDic[collectAssetInfo.AssetPath].SetAllDependAssetInfos(dependAssetInfos); + } + + // 7. 记录关键信息 + BuildMapContext context = new BuildMapContext(); + context.AssetFileCount = allBuildAssetInfoDic.Count; + context.EnableAddressable = collectResult.Command.EnableAddressable; + context.UniqueBundleName = collectResult.Command.UniqueBundleName; + context.ShadersBundleName = collectResult.Command.ShadersBundleName; + + // 8. 计算共享的资源包名 + var command = collectResult.Command; + foreach (var buildAssetInfo in allBuildAssetInfoDic.Values) + { + buildAssetInfo.CalculateShareBundleName(command.UniqueBundleName, command.PackageName, command.ShadersBundleName); + } + + // 9. 移除不参与构建的资源 + List removeBuildList = new List(); + foreach (var buildAssetInfo in allBuildAssetInfoDic.Values) + { + if (buildAssetInfo.HasBundleName() == false) + removeBuildList.Add(buildAssetInfo); + } + foreach (var removeValue in removeBuildList) + { + allBuildAssetInfoDic.Remove(removeValue.AssetPath); + } + + // 10. 构建资源包 + var allPackAssets = allBuildAssetInfoDic.Values.ToList(); + if (allPackAssets.Count == 0) + throw new Exception("构建的资源列表不能为空"); + foreach (var assetInfo in allPackAssets) + { + context.PackAsset(assetInfo); + } + return context; + } + private void RemoveZeroReferenceAssets(List allCollectAssetInfos) + { + // 1. 检测是否任何存在依赖资源 + bool hasAnyDependAsset = false; + foreach (var collectAssetInfo in allCollectAssetInfos) + { + var collectorType = collectAssetInfo.CollectorType; + if (collectorType == ECollectorType.DependAssetCollector) + { + hasAnyDependAsset = true; + break; + } + } + if (hasAnyDependAsset == false) + return; + + // 2. 获取所有主资源的依赖资源集合 + HashSet allDependAsset = new HashSet(); + foreach (var collectAssetInfo in allCollectAssetInfos) + { + var collectorType = collectAssetInfo.CollectorType; + if (collectorType == ECollectorType.MainAssetCollector || collectorType == ECollectorType.StaticAssetCollector) + { + foreach (var dependAsset in collectAssetInfo.DependAssets) + { + if (allDependAsset.Contains(dependAsset) == false) + allDependAsset.Add(dependAsset); + } + } + } + + // 3. 找出所有零引用的依赖资源集合 + List removeList = new List(); + foreach (var collectAssetInfo in allCollectAssetInfos) + { + var collectorType = collectAssetInfo.CollectorType; + if (collectorType == ECollectorType.DependAssetCollector) + { + if (allDependAsset.Contains(collectAssetInfo.AssetPath) == false) + removeList.Add(collectAssetInfo); + } + } + + // 4. 移除所有零引用的依赖资源 + foreach (var removeValue in removeList) + { + BuildLogger.Log($"发现未被依赖的资源并自动移除 : {removeValue.AssetPath}"); + allCollectAssetInfos.Remove(removeValue); + } + } + /// /// 检测构建结果 /// private void CheckBuildMapContent(BuildMapContext buildMapContext) { - foreach (var bundleInfo in buildMapContext.BundleInfos) + foreach (var bundleInfo in buildMapContext.Collection) { // 注意:原生文件资源包只能包含一个原生文件 bool isRawFile = bundleInfo.IsRawFile; if (isRawFile) { - if (bundleInfo.BuildinAssets.Count != 1) + if (bundleInfo.AllMainAssets.Count != 1) throw new Exception($"The bundle does not support multiple raw asset : {bundleInfo.BundleName}"); continue; } // 注意:原生文件不能被其它资源文件依赖 - foreach (var assetInfo in bundleInfo.BuildinAssets) + foreach (var assetInfo in bundleInfo.AllMainAssets) { if (assetInfo.AllDependAssetInfos != null) { diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskPrepare.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskPrepare.cs index 718cfbb..5c32428 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskPrepare.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskPrepare.cs @@ -12,8 +12,6 @@ namespace YooAsset.Editor void IBuildTask.Run(BuildContext context) { var buildParametersContext = context.GetContextObject(); - buildParametersContext.BeginWatch(); - var buildParameters = buildParametersContext.Parameters; // 检测构建参数合法性 @@ -21,7 +19,7 @@ namespace YooAsset.Editor throw new Exception("请选择目标平台"); if (string.IsNullOrEmpty(buildParameters.PackageName)) throw new Exception("包裹名称不能为空"); - if(string.IsNullOrEmpty(buildParameters.PackageVersion)) + if (string.IsNullOrEmpty(buildParameters.PackageVersion)) throw new Exception("包裹版本不能为空"); if (buildParameters.BuildMode != EBuildMode.SimulateBuild) @@ -53,11 +51,11 @@ namespace YooAsset.Editor if (buildParameters.BuildMode == EBuildMode.ForceRebuild) { - // 删除平台总目录 - string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.PackageName}/{buildParameters.BuildTarget}"; + // 删除总目录 + string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.BuildTarget}/{buildParameters.PackageName}"; if (EditorTools.DeleteDirectory(platformDirectory)) { - BuildRunner.Log($"删除平台总目录:{platformDirectory}"); + BuildLogger.Log($"删除平台总目录:{platformDirectory}"); } } @@ -65,7 +63,7 @@ namespace YooAsset.Editor string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); if (EditorTools.CreateDirectory(pipelineOutputDirectory)) { - BuildRunner.Log($"创建输出目录:{pipelineOutputDirectory}"); + BuildLogger.Log($"创建输出目录:{pipelineOutputDirectory}"); } } } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBuildInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBundleInfo.cs similarity index 68% rename from Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBuildInfo.cs rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBundleInfo.cs index 8c6f6fd..4881a51 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBuildInfo.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBundleInfo.cs @@ -6,8 +6,8 @@ using UnityEditor; namespace YooAsset.Editor { - [TaskAttribute("更新构建信息")] - public class TaskUpdateBuildInfo : IBuildTask + [TaskAttribute("更新资源包信息")] + public class TaskUpdateBundleInfo : IBuildTask { void IBuildTask.Run(BuildContext context) { @@ -17,39 +17,40 @@ namespace YooAsset.Editor string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); int outputNameStyle = (int)buildParametersContext.Parameters.OutputNameStyle; - // 1.检测路径长度 - foreach (var bundleInfo in buildMapContext.BundleInfos) + // 1.检测文件名长度 + foreach (var bundleInfo in buildMapContext.Collection) { - // NOTE:检测路径长度不要超过260字符。 - string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; - if (filePath.Length >= 260) - throw new Exception($"The output bundle name is too long {filePath.Length} chars : {filePath}"); + // NOTE:检测文件名长度不要超过260字符。 + string fileName = bundleInfo.BundleName; + if (fileName.Length >= 260) + throw new Exception($"The output bundle name is too long {fileName.Length} chars : {fileName}"); } // 2.更新构建输出的文件路径 - foreach (var bundleInfo in buildMapContext.BundleInfos) + foreach (var bundleInfo in buildMapContext.Collection) { if (bundleInfo.IsEncryptedFile) - bundleInfo.PatchInfo.BuildOutputFilePath = bundleInfo.EncryptedFilePath; + bundleInfo.BundleInfo.BuildOutputFilePath = bundleInfo.EncryptedFilePath; else - bundleInfo.PatchInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; + bundleInfo.BundleInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; } // 3.更新文件其它信息 - foreach (var bundleInfo in buildMapContext.BundleInfos) + foreach (var bundleInfo in buildMapContext.Collection) { - string buildOutputFilePath = bundleInfo.PatchInfo.BuildOutputFilePath; - bundleInfo.PatchInfo.ContentHash = GetBundleContentHash(bundleInfo, context); - bundleInfo.PatchInfo.PatchFileHash = GetBundleFileHash(buildOutputFilePath, buildParametersContext); - bundleInfo.PatchInfo.PatchFileCRC = GetBundleFileCRC(buildOutputFilePath, buildParametersContext); - bundleInfo.PatchInfo.PatchFileSize = GetBundleFileSize(buildOutputFilePath, buildParametersContext); + string buildOutputFilePath = bundleInfo.BundleInfo.BuildOutputFilePath; + bundleInfo.BundleInfo.ContentHash = GetBundleContentHash(bundleInfo, context); + bundleInfo.BundleInfo.FileHash = GetBundleFileHash(buildOutputFilePath, buildParametersContext); + bundleInfo.BundleInfo.FileCRC = GetBundleFileCRC(buildOutputFilePath, buildParametersContext); + bundleInfo.BundleInfo.FileSize = GetBundleFileSize(buildOutputFilePath, buildParametersContext); } // 4.更新补丁包输出的文件路径 - foreach (var bundleInfo in buildMapContext.BundleInfos) + foreach (var bundleInfo in buildMapContext.Collection) { - string patchFileName = PatchManifestTools.CreateBundleFileName(outputNameStyle, bundleInfo.BundleName, bundleInfo.PatchInfo.PatchFileHash, bundleInfo.IsRawFile); - bundleInfo.PatchInfo.PatchOutputFilePath = $"{packageOutputDirectory}/{patchFileName}"; + string fileExtension = ManifestTools.GetRemoteBundleFileExtension(bundleInfo.BundleName); + string fileName = ManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleInfo.BundleName, fileExtension, bundleInfo.BundleInfo.FileHash); + bundleInfo.BundleInfo.PackageOutputFilePath = $"{packageOutputDirectory}/{fileName}"; } } @@ -63,7 +64,7 @@ namespace YooAsset.Editor if (bundleInfo.IsRawFile) { - string filePath = bundleInfo.PatchInfo.BuildOutputFilePath; + string filePath = bundleInfo.BundleInfo.BuildOutputFilePath; return HashUtility.FileMD5(filePath); } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBuildInfo.cs.meta b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBundleInfo.cs.meta similarity index 100% rename from Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBuildInfo.cs.meta rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskUpdateBundleInfo.cs.meta diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskVerifyBuildResult.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskVerifyBuildResult.cs index 52dd554..e3ffbbf 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskVerifyBuildResult.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskVerifyBuildResult.cs @@ -34,29 +34,29 @@ namespace YooAsset.Editor { var buildParametersContext = context.GetContextObject(); var buildMapContext = context.GetContextObject(); - string[] buildedBundles = unityManifest.GetAllAssetBundles(); + string[] unityCreateBundles = unityManifest.GetAllAssetBundles(); // 1. 过滤掉原生Bundle - string[] mapBundles = buildMapContext.BundleInfos.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToArray(); + string[] mapBundles = buildMapContext.Collection.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToArray(); // 2. 验证Bundle - List exceptBundleList1 = buildedBundles.Except(mapBundles).ToList(); + List exceptBundleList1 = unityCreateBundles.Except(mapBundles).ToList(); if (exceptBundleList1.Count > 0) { foreach (var exceptBundle in exceptBundleList1) { - Debug.LogWarning($"差异资源包: {exceptBundle}"); + BuildLogger.Warning($"差异资源包: {exceptBundle}"); } throw new System.Exception("存在差异资源包!请查看警告信息!"); } // 3. 验证Bundle - List exceptBundleList2 = mapBundles.Except(buildedBundles).ToList(); + List exceptBundleList2 = mapBundles.Except(unityCreateBundles).ToList(); if (exceptBundleList2.Count > 0) { foreach (var exceptBundle in exceptBundleList2) { - Debug.LogWarning($"差异资源包: {exceptBundle}"); + BuildLogger.Warning($"差异资源包: {exceptBundle}"); } throw new System.Exception("存在差异资源包!请查看警告信息!"); } @@ -76,16 +76,16 @@ namespace YooAsset.Editor string[] mapAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle); if (mapAssetPaths.Length != buildedAssetPaths.Length) { - Debug.LogWarning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}"); + BuildLogger.Warning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}"); var exceptAssetList1 = mapAssetPaths.Except(buildedAssetPaths).ToList(); foreach (var excpetAsset in exceptAssetList1) { - Debug.LogWarning($"构建失败的资源对象路径为 : {excpetAsset}"); + BuildLogger.Warning($"构建失败的资源对象路径为 : {excpetAsset}"); } var exceptAssetList2 = buildedAssetPaths.Except(mapAssetPaths).ToList(); foreach (var excpetAsset in exceptAssetList2) { - Debug.LogWarning($"构建失败的资源对象路径为 : {excpetAsset}"); + BuildLogger.Warning($"构建失败的资源对象路径为 : {excpetAsset}"); } isPass = false; continue; @@ -101,7 +101,7 @@ namespace YooAsset.Editor } */ - BuildRunner.Log("构建结果验证成功!"); + BuildLogger.Log("构建结果验证成功!"); } /// diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskVerifyBuildResult_SBP.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskVerifyBuildResult_SBP.cs index 9b52d8e..b4ec42a 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskVerifyBuildResult_SBP.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskVerifyBuildResult_SBP.cs @@ -35,34 +35,34 @@ namespace YooAsset.Editor { var buildParameters = context.GetContextObject(); var buildMapContext = context.GetContextObject(); - List buildedBundles = buildResults.BundleInfos.Keys.ToList(); + List unityCreateBundles = buildResults.BundleInfos.Keys.ToList(); // 1. 过滤掉原生Bundle - List expectBundles = buildMapContext.BundleInfos.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToList(); + List expectBundles = buildMapContext.Collection.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToList(); // 2. 验证Bundle - List exceptBundleList1 = buildedBundles.Except(expectBundles).ToList(); + List exceptBundleList1 = unityCreateBundles.Except(expectBundles).ToList(); if (exceptBundleList1.Count > 0) { foreach (var exceptBundle in exceptBundleList1) { - Debug.LogWarning($"差异资源包: {exceptBundle}"); + BuildLogger.Warning($"差异资源包: {exceptBundle}"); } throw new System.Exception("存在差异资源包!请查看警告信息!"); } // 3. 验证Bundle - List exceptBundleList2 = expectBundles.Except(buildedBundles).ToList(); + List exceptBundleList2 = expectBundles.Except(unityCreateBundles).ToList(); if (exceptBundleList2.Count > 0) { foreach (var exceptBundle in exceptBundleList2) { - Debug.LogWarning($"差异资源包: {exceptBundle}"); + BuildLogger.Warning($"差异资源包: {exceptBundle}"); } throw new System.Exception("存在差异资源包!请查看警告信息!"); } - BuildRunner.Log("构建结果验证成功!"); + BuildLogger.Log("构建结果验证成功!"); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryption.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryption.cs new file mode 100644 index 0000000..44f5053 --- /dev/null +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryption.cs @@ -0,0 +1,11 @@ + +namespace YooAsset.Editor +{ + public class EncryptionNone : IEncryptionServices + { + public EncryptResult Encrypt(EncryptFileInfo fileInfo) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs.meta b/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryption.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs.meta rename to Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryption.cs.meta index 4b66326..3c666d3 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs.meta +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryption.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a6296859f09655c4191594304ddf378f +guid: 46b8b200b841799498896403d9d427c2 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollector.cs b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollector.cs index 8449b7c..b344a42 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollector.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollector.cs @@ -45,6 +45,11 @@ namespace YooAsset.Editor /// public string AssetTags = string.Empty; + /// + /// 用户自定义数据 + /// + public string UserData = string.Empty; + /// /// 收集器是否有效 @@ -142,11 +147,14 @@ namespace YooAsset.Editor } Dictionary result = new Dictionary(1000); - bool isRawAsset = PackRuleName == nameof(PackRawFile); + + // 检测是否为原生资源打包规则 + IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName); + bool isRawFilePackRule = packRuleInstance.IsRawFilePackRule(); // 检测原生资源包的收集器类型 - if (isRawAsset && CollectorType != ECollectorType.MainAssetCollector) - throw new Exception($"The raw file must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}"); + if (isRawFilePackRule && CollectorType != ECollectorType.MainAssetCollector) + throw new Exception($"The raw file pack rule must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}"); if (string.IsNullOrEmpty(CollectPath)) throw new Exception($"The collect path is null or empty in group : {group.GroupName}"); @@ -158,11 +166,11 @@ namespace YooAsset.Editor string[] findAssets = EditorTools.FindAssets(EAssetSearchType.All, collectDirectory); foreach (string assetPath in findAssets) { - if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath)) + if (IsValidateAsset(assetPath, isRawFilePackRule) && IsCollectAsset(assetPath)) { if (result.ContainsKey(assetPath) == false) { - var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset); + var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawFilePackRule); result.Add(assetPath, collectAssetInfo); } else @@ -175,9 +183,9 @@ namespace YooAsset.Editor else { string assetPath = CollectPath; - if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath)) + if (IsValidateAsset(assetPath, isRawFilePackRule) && IsCollectAsset(assetPath)) { - var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset); + var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawFilePackRule); result.Add(assetPath, collectAssetInfo); } else @@ -207,12 +215,12 @@ namespace YooAsset.Editor return result.Values.ToList(); } - private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawAsset) + private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawFilePackRule) { - string address = GetAddress(group, assetPath); - string bundleName = GetBundleName(group, assetPath); + string address = GetAddress(command, group, assetPath); + string bundleName = GetBundleName(command, group, assetPath); List assetTags = GetAssetTags(group); - CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, assetTags, isRawAsset); + CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, isRawFilePackRule, assetTags); // 注意:模拟构建模式下不需要收集依赖资源 if (command.BuildMode == EBuildMode.SimulateBuild) @@ -222,7 +230,7 @@ namespace YooAsset.Editor return collectAssetInfo; } - private bool IsValidateAsset(string assetPath) + private bool IsValidateAsset(string assetPath, bool isRawFilePackRule) { if (assetPath.StartsWith("Assets/") == false && assetPath.StartsWith("Packages/") == false) { @@ -235,15 +243,38 @@ namespace YooAsset.Editor return false; // 忽略编辑器下的类型资源 - Type type = AssetDatabase.GetMainAssetTypeAtPath(assetPath); - if (type == typeof(LightingDataAsset)) + Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); + if (assetType == typeof(LightingDataAsset)) return false; - // 忽略Unity无法识别的无效文件 - // 注意:只对非原生文件收集器处理 - if(PackRuleName != nameof(PackRawFile)) + // 检测原生文件是否合规 + if (isRawFilePackRule) { - if (type == typeof(UnityEditor.DefaultAsset)) + string extension = StringUtility.RemoveFirstChar(System.IO.Path.GetExtension(assetPath)); + if (extension == EAssetFileExtension.unity.ToString() || extension == EAssetFileExtension.prefab.ToString() || + extension == EAssetFileExtension.fbx.ToString() || extension == EAssetFileExtension.mat.ToString() || + extension == EAssetFileExtension.controller.ToString() || extension == EAssetFileExtension.anim.ToString() || + extension == EAssetFileExtension.ttf.ToString() || extension == EAssetFileExtension.shader.ToString()) + { + UnityEngine.Debug.LogWarning($"Raw file pack rule can not support file estension : {extension}"); + return false; + } + + // 注意:原生文件只支持无依赖关系的资源 + /* + string[] depends = AssetDatabase.GetDependencies(assetPath, true); + if (depends.Length != 1) + { + UnityEngine.Debug.LogWarning($"Raw file pack rule can not support estension : {extension}"); + return false; + } + */ + } + else + { + // 忽略Unity无法识别的无效文件 + // 注意:只对非原生文件收集器处理 + if (assetType == typeof(UnityEditor.DefaultAsset)) { UnityEngine.Debug.LogWarning($"Cannot pack default asset : {assetPath}"); return false; @@ -251,20 +282,11 @@ namespace YooAsset.Editor } string fileExtension = System.IO.Path.GetExtension(assetPath); - if (IsIgnoreFile(fileExtension)) + if (DefaultFilterRule.IsIgnoreFile(fileExtension)) return false; return true; } - private bool IsIgnoreFile(string fileExtension) - { - foreach (var extension in YooAssetSettings.IgnoreFileExtensions) - { - if (extension == fileExtension) - return true; - } - return false; - } private bool IsCollectAsset(string assetPath) { Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); @@ -275,28 +297,34 @@ namespace YooAsset.Editor IFilterRule filterRuleInstance = AssetBundleCollectorSettingData.GetFilterRuleInstance(FilterRuleName); return filterRuleInstance.IsCollectAsset(new FilterRuleData(assetPath)); } - private string GetAddress(AssetBundleCollectorGroup group, string assetPath) + private string GetAddress(CollectCommand command, AssetBundleCollectorGroup group, string assetPath) { + if (command.EnableAddressable == false) + return string.Empty; + if (CollectorType != ECollectorType.MainAssetCollector) return string.Empty; IAddressRule addressRuleInstance = AssetBundleCollectorSettingData.GetAddressRuleInstance(AddressRuleName); - string adressValue = addressRuleInstance.GetAssetAddress(new AddressRuleData(assetPath, CollectPath, group.GroupName)); + string adressValue = addressRuleInstance.GetAssetAddress(new AddressRuleData(assetPath, CollectPath, group.GroupName, UserData)); return adressValue; } - private string GetBundleName(AssetBundleCollectorGroup group, string assetPath) + private string GetBundleName(CollectCommand command, AssetBundleCollectorGroup group, string assetPath) { System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection)) - return EditorTools.GetRegularPath(YooAssetSettings.UnityShadersBundleName).ToLower(); - - // 根据规则设置获取资源包名称 - IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName); - string bundleName = packRuleInstance.GetBundleName(new PackRuleData(assetPath, CollectPath, group.GroupName)); - if(YooAssetSettingsData.Setting.RegularBundleName) - return EditorTools.GetRegularPath(bundleName).Replace('/', '_').Replace('.', '_').ToLower(); + { + // 获取着色器打包规则结果 + PackRuleResult packRuleResult = DefaultPackRule.CreateShadersPackRuleResult(); + return packRuleResult.GetMainBundleName(command.PackageName, command.UniqueBundleName); + } else - return EditorTools.GetRegularPath(bundleName).ToLower(); + { + // 获取其它资源打包规则结果 + IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName); + PackRuleResult packRuleResult = packRuleInstance.GetPackRuleResult(new PackRuleData(assetPath, CollectPath, group.GroupName, UserData)); + return packRuleResult.GetMainBundleName(command.PackageName, command.UniqueBundleName); + } } private List GetAssetTags(AssetBundleCollectorGroup group) { @@ -307,11 +335,11 @@ namespace YooAsset.Editor } private List GetAllDependencies(string mainAssetPath) { - List result = new List(); string[] depends = AssetDatabase.GetDependencies(mainAssetPath, true); + List result = new List(depends.Length); foreach (string assetPath in depends) { - if (IsValidateAsset(assetPath)) + if (IsValidateAsset(assetPath, false)) { // 注意:排除主资源对象 if (assetPath != mainAssetPath) diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorConfig.cs b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorConfig.cs index 1996b0a..7db138a 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorConfig.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorConfig.cs @@ -10,7 +10,7 @@ namespace YooAsset.Editor { public class AssetBundleCollectorConfig { - public const string ConfigVersion = "2.2"; + public const string ConfigVersion = "2.4"; public const string XmlVersion = "Version"; public const string XmlCommon = "Common"; @@ -24,6 +24,7 @@ namespace YooAsset.Editor public const string XmlPackageDesc = "PackageDesc"; public const string XmlGroup = "Group"; + public const string XmlGroupActiveRule = "GroupActiveRule"; public const string XmlGroupName = "GroupName"; public const string XmlGroupDesc = "GroupDesc"; @@ -34,6 +35,7 @@ namespace YooAsset.Editor public const string XmlAddressRule = "AddressRule"; public const string XmlPackRule = "PackRule"; public const string XmlFilterRule = "FilterRule"; + public const string XmlUserData = "UserData"; public const string XmlAssetTags = "AssetTags"; /// @@ -107,6 +109,8 @@ namespace YooAsset.Editor foreach (var groupNode in groupNodeList) { XmlElement groupElement = groupNode as XmlElement; + if (groupElement.HasAttribute(XmlGroupActiveRule) == false) + throw new Exception($"Not found attribute {XmlGroupActiveRule} in {XmlGroup}"); if (groupElement.HasAttribute(XmlGroupName) == false) throw new Exception($"Not found attribute {XmlGroupName} in {XmlGroup}"); if (groupElement.HasAttribute(XmlGroupDesc) == false) @@ -115,6 +119,7 @@ namespace YooAsset.Editor throw new Exception($"Not found attribute {XmlAssetTags} in {XmlGroup}"); AssetBundleCollectorGroup group = new AssetBundleCollectorGroup(); + group.ActiveRuleName = groupElement.GetAttribute(XmlGroupActiveRule); group.GroupName = groupElement.GetAttribute(XmlGroupName); group.GroupDesc = groupElement.GetAttribute(XmlGroupDesc); group.AssetTags = groupElement.GetAttribute(XmlAssetTags); @@ -137,6 +142,8 @@ namespace YooAsset.Editor throw new Exception($"Not found attribute {XmlPackRule} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlFilterRule) == false) throw new Exception($"Not found attribute {XmlFilterRule} in {XmlCollector}"); + if (collectorElement.HasAttribute(XmlUserData) == false) + throw new Exception($"Not found attribute {XmlUserData} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlAssetTags) == false) throw new Exception($"Not found attribute {XmlAssetTags} in {XmlCollector}"); @@ -147,12 +154,19 @@ namespace YooAsset.Editor collector.AddressRuleName = collectorElement.GetAttribute(XmlAddressRule); collector.PackRuleName = collectorElement.GetAttribute(XmlPackRule); collector.FilterRuleName = collectorElement.GetAttribute(XmlFilterRule); + collector.UserData = collectorElement.GetAttribute(XmlUserData); collector.AssetTags = collectorElement.GetAttribute(XmlAssetTags); group.Collectors.Add(collector); } } } + // 检测配置错误 + foreach(var package in packages) + { + package.CheckConfigError(); + } + // 保存配置数据 AssetBundleCollectorSettingData.ClearAll(); AssetBundleCollectorSettingData.Setting.EnableAddressable = enableAddressable; @@ -204,6 +218,7 @@ namespace YooAsset.Editor foreach (var group in package.Groups) { var groupElement = xmlDoc.CreateElement(XmlGroup); + groupElement.SetAttribute(XmlGroupActiveRule, group.ActiveRuleName); groupElement.SetAttribute(XmlGroupName, group.GroupName); groupElement.SetAttribute(XmlGroupDesc, group.GroupDesc); groupElement.SetAttribute(XmlAssetTags, group.AssetTags); @@ -219,6 +234,7 @@ namespace YooAsset.Editor collectorElement.SetAttribute(XmlAddressRule, collector.AddressRuleName); collectorElement.SetAttribute(XmlPackRule, collector.PackRuleName); collectorElement.SetAttribute(XmlFilterRule, collector.FilterRuleName); + collectorElement.SetAttribute(XmlUserData, collector.UserData); collectorElement.SetAttribute(XmlAssetTags, collector.AssetTags); groupElement.AppendChild(collectorElement); } @@ -320,6 +336,45 @@ namespace YooAsset.Editor return UpdateXmlConfig(xmlDoc); } + // 2.2 -> 2.3 + if (configVersion == "2.2") + { + // 获取所有分组元素 + var groupNodeList = root.GetElementsByTagName(XmlGroup); + foreach (var groupNode in groupNodeList) + { + XmlElement groupElement = groupNode as XmlElement; + var collectorNodeList = groupElement.GetElementsByTagName(XmlCollector); + foreach (var collectorNode in collectorNodeList) + { + XmlElement collectorElement = collectorNode as XmlElement; + if (collectorElement.HasAttribute(XmlUserData) == false) + collectorElement.SetAttribute(XmlUserData, string.Empty); + } + } + + // 更新版本 + root.SetAttribute(XmlVersion, "2.3"); + return UpdateXmlConfig(xmlDoc); + } + + // 2.3 -> 2.4 + if(configVersion == "2.3") + { + // 获取所有分组元素 + var groupNodeList = root.GetElementsByTagName(XmlGroup); + foreach (var groupNode in groupNodeList) + { + XmlElement groupElement = groupNode as XmlElement; + if(groupElement.HasAttribute(XmlGroupActiveRule) == false) + groupElement.SetAttribute(XmlGroupActiveRule, $"{nameof(EnableGroup)}"); + } + + // 更新版本 + root.SetAttribute(XmlVersion, "2.4"); + return UpdateXmlConfig(xmlDoc); + } + return false; } } diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorSetting.cs b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorSetting.cs index bfcc7d8..1563147 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorSetting.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorSetting.cs @@ -100,8 +100,8 @@ namespace YooAsset.Editor { if (package.PackageName == packageName) { - CollectCommand command = new CollectCommand(buildMode, EnableAddressable); - CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName); + CollectCommand command = new CollectCommand(buildMode, packageName, EnableAddressable, UniqueBundleName); + CollectResult collectResult = new CollectResult(command); collectResult.SetCollectAssets(package.GetAllCollectAssets(command)); return collectResult; } @@ -109,21 +109,5 @@ namespace YooAsset.Editor throw new Exception($"Not found collector pacakge : {packageName}"); } - - /// - /// 获取所有包裹收集的资源文件 - /// - public List GetAllPackageAssets(EBuildMode buildMode) - { - List collectResultList = new List(1000); - foreach (var package in Packages) - { - CollectCommand command = new CollectCommand(buildMode, EnableAddressable); - CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName); - collectResult.SetCollectAssets(package.GetAllCollectAssets(command)); - collectResultList.Add(collectResult); - } - return collectResultList; - } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorSettingData.cs b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorSettingData.cs index 55600c4..5fd5aee 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorSettingData.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorSettingData.cs @@ -27,24 +27,8 @@ namespace YooAsset.Editor public static bool IsDirty { private set; get; } = false; - private static AssetBundleCollectorSetting _setting = null; - public static AssetBundleCollectorSetting Setting + static AssetBundleCollectorSettingData() { - get - { - if (_setting == null) - LoadSettingData(); - return _setting; - } - } - - /// - /// 加载配置文件 - /// - private static void LoadSettingData() - { - _setting = EditorHelper.LoadSettingData(); - // IPackRule { // 清空缓存集合 @@ -108,7 +92,8 @@ namespace YooAsset.Editor List types = new List(100) { typeof(AddressByFileName), - typeof(AddressByCollectorAndFileName), + typeof(AddressByFilePath), + typeof(AddressByFolderAndFileName), typeof(AddressByGroupAndFileName) }; @@ -146,6 +131,17 @@ namespace YooAsset.Editor } } + private static AssetBundleCollectorSetting _setting = null; + public static AssetBundleCollectorSetting Setting + { + get + { + if (_setting == null) + _setting = SettingLoader.LoadSettingData(); + return _setting; + } + } + /// /// 存储配置文件 /// @@ -183,9 +179,6 @@ namespace YooAsset.Editor public static List GetActiveRuleNames() { - if (_setting == null) - LoadSettingData(); - List names = new List(); foreach (var pair in _cacheActiveRuleTypes) { @@ -198,9 +191,6 @@ namespace YooAsset.Editor } public static List GetAddressRuleNames() { - if (_setting == null) - LoadSettingData(); - List names = new List(); foreach (var pair in _cacheAddressRuleTypes) { @@ -213,9 +203,6 @@ namespace YooAsset.Editor } public static List GetPackRuleNames() { - if (_setting == null) - LoadSettingData(); - List names = new List(); foreach (var pair in _cachePackRuleTypes) { @@ -228,9 +215,6 @@ namespace YooAsset.Editor } public static List GetFilterRuleNames() { - if (_setting == null) - LoadSettingData(); - List names = new List(); foreach (var pair in _cacheFilterRuleTypes) { @@ -243,7 +227,7 @@ namespace YooAsset.Editor } private static string GetRuleDisplayName(string name, Type type) { - var attribute = EditorAttribute.GetAttribute(type); + var attribute = DisplayNameAttributeHelper.GetAttribute(type); if (attribute != null && string.IsNullOrEmpty(attribute.DisplayName) == false) return attribute.DisplayName; else diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorWindow.cs b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorWindow.cs index 486ce7e..7d9b049 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorWindow.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorWindow.cs @@ -14,7 +14,7 @@ namespace YooAsset.Editor [MenuItem("YooAsset/AssetBundle Collector", false, 101)] public static void ShowExample() { - AssetBundleCollectorWindow window = GetWindow("资源包收集工具", true, EditorDefine.DockedWindowTypes); + AssetBundleCollectorWindow window = GetWindow("资源包收集工具", true, WindowsDefine.DockedWindowTypes); window.minSize = new Vector2(800, 600); } @@ -70,7 +70,7 @@ namespace YooAsset.Editor VisualElement root = this.rootVisualElement; // 加载布局文件 - var visualAsset = EditorHelper.LoadWindowUXML(); + var visualAsset = UxmlLoader.LoadWindowUXML(); if (visualAsset == null) return; @@ -148,6 +148,7 @@ namespace YooAsset.Editor { selectPackage.PackageName = evt.newValue; AssetBundleCollectorSettingData.ModifyPackage(selectPackage); + FillPackageViewData(); } }); @@ -160,6 +161,7 @@ namespace YooAsset.Editor { selectPackage.PackageDesc = evt.newValue; AssetBundleCollectorSettingData.ModifyPackage(selectPackage); + FillPackageViewData(); } }); @@ -594,14 +596,14 @@ namespace YooAsset.Editor var popupField = new PopupField(_addressRuleList, 0); popupField.name = "PopupField1"; popupField.style.unityTextAlign = TextAnchor.MiddleLeft; - popupField.style.width = 200; + popupField.style.width = 220; elementBottom.Add(popupField); } { var popupField = new PopupField(_packRuleList, 0); popupField.name = "PopupField2"; popupField.style.unityTextAlign = TextAnchor.MiddleLeft; - popupField.style.width = 230; + popupField.style.width = 220; elementBottom.Add(popupField); } { @@ -611,6 +613,15 @@ namespace YooAsset.Editor popupField.style.width = 150; elementBottom.Add(popupField); } + { + var textField = new TextField(); + textField.name = "TextField0"; + textField.label = "UserData"; + textField.style.width = 200; + elementBottom.Add(textField); + var label = textField.Q public string BundleName { private set; get; } - + /// /// 可寻址地址 /// @@ -25,30 +25,30 @@ namespace YooAsset.Editor /// public string AssetPath { private set; get; } - /// - /// 资源分类标签 - /// - public List AssetTags { private set; get; } - /// /// 是否为原生资源 /// public bool IsRawAsset { private set; get; } + /// + /// 资源分类标签 + /// + public List AssetTags { private set; get; } + /// /// 依赖的资源列表 /// public List DependAssets = new List(); - public CollectAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, List assetTags, bool isRawAsset) + public CollectAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, bool isRawAsset, List assetTags) { CollectorType = collectorType; BundleName = bundleName; Address = address; AssetPath = assetPath; - AssetTags = assetTags; IsRawAsset = isRawAsset; + AssetTags = assetTags; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/CollectCommand.cs b/Assets/YooAsset/Editor/AssetBundleCollector/CollectCommand.cs index 0501a37..c244e1e 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/CollectCommand.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/CollectCommand.cs @@ -8,15 +8,37 @@ namespace YooAsset.Editor /// public EBuildMode BuildMode { private set; get; } + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + /// /// 是否启用可寻址资源定位 /// public bool EnableAddressable { private set; get; } - public CollectCommand(EBuildMode buildMode, bool enableAddressable) + /// + /// 资源包名唯一化 + /// + public bool UniqueBundleName { private set; get; } + + /// + /// 着色器统一全名称 + /// + public string ShadersBundleName { private set; get; } + + + public CollectCommand(EBuildMode buildMode, string packageName, bool enableAddressable, bool uniqueBundleName) { BuildMode = buildMode; + PackageName = packageName; EnableAddressable = enableAddressable; + UniqueBundleName = uniqueBundleName; + + // 着色器统一全名称 + var packRuleResult = DefaultPackRule.CreateShadersPackRuleResult(); + ShadersBundleName = packRuleResult.GetMainBundleName(packageName, uniqueBundleName); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/CollectResult.cs b/Assets/YooAsset/Editor/AssetBundleCollector/CollectResult.cs index 5eca265..1a24cdc 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/CollectResult.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/CollectResult.cs @@ -6,33 +6,19 @@ namespace YooAsset.Editor public class CollectResult { /// - /// 包裹名称 + /// 收集命令 /// - public string PackageName { private set; get; } - - /// - /// 是否启用可寻址资源定位 - /// - public bool EnableAddressable { private set; get; } - - /// - /// 资源包名唯一化 - /// - public bool UniqueBundleName { private set; get; } + public CollectCommand Command { private set; get; } /// /// 收集的资源信息列表 /// public List CollectAssets { private set; get; } - - public CollectResult(string packageName, bool enableAddressable, bool uniqueBundleName) + public CollectResult(CollectCommand command) { - PackageName = packageName; - EnableAddressable = enableAddressable; - UniqueBundleName = uniqueBundleName; + Command = command; } - public void SetCollectAssets(List collectAssets) { CollectAssets = collectAssets; diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/DefaultAddressRule.cs b/Assets/YooAsset/Editor/AssetBundleCollector/DefaultAddressRule.cs index a2f1936..d23c78b 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/DefaultAddressRule.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/DefaultAddressRule.cs @@ -2,7 +2,7 @@ namespace YooAsset.Editor { - [DisplayName("以文件名称为定位地址")] + [DisplayName("定位地址: 文件名")] public class AddressByFileName : IAddressRule { string IAddressRule.GetAssetAddress(AddressRuleData data) @@ -11,7 +11,16 @@ namespace YooAsset.Editor } } - [DisplayName("以分组名称+文件名称为定位地址")] + [DisplayName("定位地址: 文件路径")] + public class AddressByFilePath : IAddressRule + { + string IAddressRule.GetAssetAddress(AddressRuleData data) + { + return data.AssetPath; + } + } + + [DisplayName("定位地址: 分组名+文件名")] public class AddressByGroupAndFileName : IAddressRule { string IAddressRule.GetAssetAddress(AddressRuleData data) @@ -21,14 +30,14 @@ namespace YooAsset.Editor } } - [DisplayName("以收集器名称+文件名称为定位地址")] - public class AddressByCollectorAndFileName : IAddressRule + [DisplayName("定位地址: 文件夹名+文件名")] + public class AddressByFolderAndFileName : IAddressRule { string IAddressRule.GetAssetAddress(AddressRuleData data) { string fileName = Path.GetFileNameWithoutExtension(data.AssetPath); - string collectorName = Path.GetFileNameWithoutExtension(data.CollectPath); - return $"{collectorName}_{fileName}"; + FileInfo fileInfo = new FileInfo(data.AssetPath); + return $"{fileInfo.Directory.Name}_{fileName}"; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/DefaultFilterRule.cs b/Assets/YooAsset/Editor/AssetBundleCollector/DefaultFilterRule.cs index eba9b87..931e00a 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/DefaultFilterRule.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/DefaultFilterRule.cs @@ -1,9 +1,27 @@ -using UnityEngine; -using UnityEditor; +using System.Collections; +using System.Collections.Generic; using System.IO; +using UnityEngine; +using UnityEditor; namespace YooAsset.Editor { + public class DefaultFilterRule + { + /// + /// 忽略的文件类型 + /// + private readonly static HashSet _ignoreFileExtensions = new HashSet() { "", ".so", ".dll", ".cs", ".js", ".boo", ".meta", ".cginc", ".hlsl" }; + + /// + /// 查询是否为忽略文件 + /// + public static bool IsIgnoreFile(string fileExtension) + { + return _ignoreFileExtensions.Contains(fileExtension); + } + } + [DisplayName("收集所有资源")] public class CollectAll : IFilterRule { diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/DefaultPackRule.cs b/Assets/YooAsset/Editor/AssetBundleCollector/DefaultPackRule.cs index 3dbc7c9..563d1e9 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/DefaultPackRule.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/DefaultPackRule.cs @@ -4,18 +4,50 @@ using UnityEditor; namespace YooAsset.Editor { + public class DefaultPackRule + { + /// + /// AssetBundle文件的后缀名 + /// + public const string AssetBundleFileExtension = "bundle"; + + /// + /// 原生文件的后缀名 + /// + public const string RawFileExtension = "rawfile"; + + /// + /// Unity着色器资源包名称 + /// + public const string ShadersBundleName = "unityshaders"; + + + public static PackRuleResult CreateShadersPackRuleResult() + { + PackRuleResult result = new PackRuleResult(ShadersBundleName, AssetBundleFileExtension); + return result; + } + } + /// /// 以文件路径作为资源包名 /// 注意:每个文件独自打资源包 /// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image_backgroud.bundle" /// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view_main.bundle" /// - [DisplayName("以文件路径作为资源包名")] + [DisplayName("资源包名: 文件路径")] public class PackSeparately : IPackRule { - string IPackRule.GetBundleName(PackRuleData data) + PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data) { - return StringUtility.RemoveExtension(data.AssetPath); + string bundleName = StringUtility.RemoveExtension(data.AssetPath); + PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension); + return result; + } + + bool IPackRule.IsRawFilePackRule() + { + return false; } } @@ -25,14 +57,21 @@ namespace YooAsset.Editor /// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image.bundle" /// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view.bundle" /// - [DisplayName("以父类文件夹路径作为资源包名")] + [DisplayName("资源包名: 父类文件夹路径")] public class PackDirectory : IPackRule { public static PackDirectory StaticPackRule = new PackDirectory(); - string IPackRule.GetBundleName(PackRuleData data) + PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data) { - return Path.GetDirectoryName(data.AssetPath); + string bundleName = Path.GetDirectoryName(data.AssetPath); + PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension); + return result; + } + + bool IPackRule.IsRawFilePackRule() + { + return false; } } @@ -43,10 +82,10 @@ namespace YooAsset.Editor /// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop.bundle" /// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop.bundle" /// - [DisplayName("以收集器路径下顶级文件夹为资源包名")] + [DisplayName("资源包名: 收集器下顶级文件夹路径")] public class PackTopDirectory : IPackRule { - string IPackRule.GetBundleName(PackRuleData data) + PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data) { string assetPath = data.AssetPath.Replace(data.CollectPath, string.Empty); assetPath = assetPath.TrimStart('/'); @@ -56,33 +95,48 @@ namespace YooAsset.Editor if (Path.HasExtension(splits[0])) throw new Exception($"Not found root directory : {assetPath}"); string bundleName = $"{data.CollectPath}/{splits[0]}"; - return bundleName; + PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension); + return result; } else { throw new Exception($"Not found root directory : {assetPath}"); } } + + bool IPackRule.IsRawFilePackRule() + { + return false; + } } /// /// 以收集器路径作为资源包名 /// 注意:收集的所有文件打进一个资源包 /// - [DisplayName("以收集器路径作为资源包名")] + [DisplayName("资源包名: 收集器路径")] public class PackCollector : IPackRule { - string IPackRule.GetBundleName(PackRuleData data) + PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data) { + string bundleName; string collectPath = data.CollectPath; if (AssetDatabase.IsValidFolder(collectPath)) { - return collectPath; + bundleName = collectPath; } else { - return StringUtility.RemoveExtension(collectPath); + bundleName = StringUtility.RemoveExtension(collectPath); } + + PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension); + return result; + } + + bool IPackRule.IsRawFilePackRule() + { + return false; } } @@ -90,51 +144,55 @@ namespace YooAsset.Editor /// 以分组名称作为资源包名 /// 注意:收集的所有文件打进一个资源包 /// - [DisplayName("以分组名称作为资源包名")] + [DisplayName("资源包名: 分组名称")] public class PackGroup : IPackRule { - string IPackRule.GetBundleName(PackRuleData data) + PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data) { - return data.GroupName; + string bundleName = data.GroupName; + PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension); + return result; + } + + bool IPackRule.IsRawFilePackRule() + { + return false; } } /// /// 打包原生文件 - /// 注意:原生文件打包支持:图片,音频,视频,文本 /// [DisplayName("打包原生文件")] public class PackRawFile : IPackRule { - string IPackRule.GetBundleName(PackRuleData data) + PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data) { - string extension = StringUtility.RemoveFirstChar(Path.GetExtension(data.AssetPath)); - if (extension == EAssetFileExtension.unity.ToString() || extension == EAssetFileExtension.prefab.ToString() || - extension == EAssetFileExtension.mat.ToString() || extension == EAssetFileExtension.controller.ToString() || - extension == EAssetFileExtension.fbx.ToString() || extension == EAssetFileExtension.anim.ToString() || - extension == EAssetFileExtension.shader.ToString()) - { - throw new Exception($"{nameof(PackRawFile)} is not support file estension : {extension}"); - } + string bundleName = data.AssetPath; + PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.RawFileExtension); + return result; + } - // 注意:原生文件只支持无依赖关系的资源 - string[] depends = AssetDatabase.GetDependencies(data.AssetPath, true); - if (depends.Length != 1) - throw new Exception($"{nameof(PackRawFile)} is not support estension : {extension}"); - - return data.AssetPath; + bool IPackRule.IsRawFilePackRule() + { + return true; } } /// /// 打包着色器变种集合 /// - [DisplayName("打包着色器变种集合")] + [DisplayName("打包着色器变种集合文件")] public class PackShaderVariants : IPackRule { - public string GetBundleName(PackRuleData data) + public PackRuleResult GetPackRuleResult(PackRuleData data) { - return YooAssetSettings.UnityShadersBundleName; + return DefaultPackRule.CreateShadersPackRuleResult(); + } + + bool IPackRule.IsRawFilePackRule() + { + return false; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/EditorAttribute.cs b/Assets/YooAsset/Editor/AssetBundleCollector/DisplayNameAttribute.cs similarity index 93% rename from Assets/YooAsset/Editor/EditorAttribute.cs rename to Assets/YooAsset/Editor/AssetBundleCollector/DisplayNameAttribute.cs index beecd80..8e001ed 100644 --- a/Assets/YooAsset/Editor/EditorAttribute.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/DisplayNameAttribute.cs @@ -16,7 +16,7 @@ namespace YooAsset.Editor } } - public static class EditorAttribute + public static class DisplayNameAttributeHelper { internal static T GetAttribute(Type type) where T : Attribute { diff --git a/Assets/YooAsset/Editor/EditorAttribute.cs.meta b/Assets/YooAsset/Editor/AssetBundleCollector/DisplayNameAttribute.cs.meta similarity index 100% rename from Assets/YooAsset/Editor/EditorAttribute.cs.meta rename to Assets/YooAsset/Editor/AssetBundleCollector/DisplayNameAttribute.cs.meta diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/IAddressRule.cs b/Assets/YooAsset/Editor/AssetBundleCollector/IAddressRule.cs index 061f03d..7b4f609 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/IAddressRule.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/IAddressRule.cs @@ -6,12 +6,14 @@ namespace YooAsset.Editor public string AssetPath; public string CollectPath; public string GroupName; + public string UserData; - public AddressRuleData(string assetPath, string collectPath, string groupName) + public AddressRuleData(string assetPath, string collectPath, string groupName, string userData) { AssetPath = assetPath; CollectPath = collectPath; GroupName = groupName; + UserData = userData; } } diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/IPackRule.cs b/Assets/YooAsset/Editor/AssetBundleCollector/IPackRule.cs index c719002..3e45713 100644 --- a/Assets/YooAsset/Editor/AssetBundleCollector/IPackRule.cs +++ b/Assets/YooAsset/Editor/AssetBundleCollector/IPackRule.cs @@ -3,21 +3,64 @@ namespace YooAsset.Editor { public struct PackRuleData { - public string AssetPath; + public string AssetPath; public string CollectPath; public string GroupName; + public string UserData; public PackRuleData(string assetPath) { AssetPath = assetPath; CollectPath = string.Empty; GroupName = string.Empty; + UserData = string.Empty; } - public PackRuleData(string assetPath, string collectPath, string groupName) + public PackRuleData(string assetPath, string collectPath, string groupName, string userData) { AssetPath = assetPath; CollectPath = collectPath; GroupName = groupName; + UserData = userData; + } + } + + public struct PackRuleResult + { + private readonly string _bundleName; + private readonly string _bundleExtension; + + public PackRuleResult(string bundleName, string bundleExtension) + { + _bundleName = bundleName; + _bundleExtension = bundleExtension; + } + + /// + /// 获取主资源包全名称 + /// + public string GetMainBundleName(string packageName, bool uniqueBundleName) + { + string fullName; + string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').ToLower(); + if (uniqueBundleName) + fullName = $"{packageName}_{bundleName}.{_bundleExtension}"; + else + fullName = $"{bundleName}.{_bundleExtension}"; + return fullName.ToLower(); + } + + /// + /// 获取共享资源包全名称 + /// + public string GetShareBundleName(string packageName, bool uniqueBundleName) + { + string fullName; + string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').ToLower(); + if (uniqueBundleName) + fullName = $"{packageName}_share_{bundleName}.{_bundleExtension}"; + else + fullName = $"share_{bundleName}.{_bundleExtension}"; + return fullName.ToLower(); } } @@ -27,8 +70,13 @@ namespace YooAsset.Editor public interface IPackRule { /// - /// 获取资源打包所属的资源包名称 + /// 获取打包规则结果 /// - string GetBundleName(PackRuleData data); + PackRuleResult GetPackRuleResult(PackRuleData data); + + /// + /// 是否为原生文件打包规则 + /// + bool IsRawFilePackRule(); } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs index adda79d..19a3012 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs @@ -15,7 +15,7 @@ namespace YooAsset.Editor [MenuItem("YooAsset/AssetBundle Debugger", false, 104)] public static void ShowExample() { - AssetBundleDebuggerWindow wnd = GetWindow("资源包调试工具", true, EditorDefine.DockedWindowTypes); + AssetBundleDebuggerWindow wnd = GetWindow("资源包调试工具", true, WindowsDefine.DockedWindowTypes); wnd.minSize = new Vector2(800, 600); } @@ -63,7 +63,7 @@ namespace YooAsset.Editor VisualElement root = rootVisualElement; // 加载布局文件 - var visualAsset = EditorHelper.LoadWindowUXML(); + var visualAsset = UxmlLoader.LoadWindowUXML(); if (visualAsset == null) return; diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs index 389f9bb..edc150b 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs @@ -24,7 +24,7 @@ namespace YooAsset.Editor public void InitViewer() { // 加载布局文件 - _visualAsset = EditorHelper.LoadWindowUXML(); + _visualAsset = UxmlLoader.LoadWindowUXML(); if (_visualAsset == null) return; @@ -45,6 +45,10 @@ namespace YooAsset.Editor _dependListView = _root.Q("BottomListView"); _dependListView.makeItem = MakeDependListViewItem; _dependListView.bindItem = BindDependListViewItem; + +#if UNITY_2020_3_OR_NEWER + SplitView.Adjuster(_root); +#endif } /// diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs index cb68f3a..c4a2e6d 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs @@ -24,7 +24,7 @@ namespace YooAsset.Editor public void InitViewer() { // 加载布局文件 - _visualAsset = EditorHelper.LoadWindowUXML(); + _visualAsset = UxmlLoader.LoadWindowUXML(); if (_visualAsset == null) return; @@ -45,6 +45,10 @@ namespace YooAsset.Editor _usingListView = _root.Q("BottomListView"); _usingListView.makeItem = MakeIncludeListViewItem; _usingListView.bindItem = BindIncludeListViewItem; + +#if UNITY_2020_3_OR_NEWER + SplitView.Adjuster(_root); +#endif } /// diff --git a/Assets/YooAsset/Editor/AssetBundleReporter/AssetBundleReporterWindow.cs b/Assets/YooAsset/Editor/AssetBundleReporter/AssetBundleReporterWindow.cs index 5cc2dd4..15009da 100644 --- a/Assets/YooAsset/Editor/AssetBundleReporter/AssetBundleReporterWindow.cs +++ b/Assets/YooAsset/Editor/AssetBundleReporter/AssetBundleReporterWindow.cs @@ -12,7 +12,7 @@ namespace YooAsset.Editor [MenuItem("YooAsset/AssetBundle Reporter", false, 103)] public static void ShowExample() { - AssetBundleReporterWindow window = GetWindow("资源包报告工具", true, EditorDefine.DockedWindowTypes); + AssetBundleReporterWindow window = GetWindow("资源包报告工具", true, WindowsDefine.DockedWindowTypes); window.minSize = new Vector2(800, 600); } @@ -55,7 +55,7 @@ namespace YooAsset.Editor VisualElement root = this.rootVisualElement; // 加载布局文件 - var visualAsset = EditorHelper.LoadWindowUXML(); + var visualAsset = UxmlLoader.LoadWindowUXML(); if (visualAsset == null) return; diff --git a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterAssetListViewer.cs b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterAssetListViewer.cs index 7830871..9417146 100644 --- a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterAssetListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterAssetListViewer.cs @@ -38,7 +38,7 @@ namespace YooAsset.Editor public void InitViewer() { // 加载布局文件 - _visualAsset = EditorHelper.LoadWindowUXML(); + _visualAsset = UxmlLoader.LoadWindowUXML(); if (_visualAsset == null) return; @@ -68,6 +68,10 @@ namespace YooAsset.Editor _dependListView = _root.Q("BottomListView"); _dependListView.makeItem = MakeDependListViewItem; _dependListView.bindItem = BindDependListViewItem; + +#if UNITY_2020_3_OR_NEWER + SplitView.Adjuster(_root); +#endif } /// diff --git a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterAssetListViewer.uxml b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterAssetListViewer.uxml index 18391ae..a957c06 100644 --- a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterAssetListViewer.uxml +++ b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterAssetListViewer.uxml @@ -1,10 +1,10 @@ - + - + diff --git a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterBundleListViewer.cs b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterBundleListViewer.cs index 35d800e..18ddfcc 100644 --- a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterBundleListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterBundleListViewer.cs @@ -42,7 +42,7 @@ namespace YooAsset.Editor public void InitViewer() { // 加载布局文件 - _visualAsset = EditorHelper.LoadWindowUXML(); + _visualAsset = UxmlLoader.LoadWindowUXML(); if (_visualAsset == null) return; @@ -76,6 +76,10 @@ namespace YooAsset.Editor _includeListView = _root.Q("BottomListView"); _includeListView.makeItem = MakeIncludeListViewItem; _includeListView.bindItem = BindIncludeListViewItem; + +#if UNITY_2020_3_OR_NEWER + SplitView.Adjuster(_root); +#endif } /// diff --git a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterBundleListViewer.uxml b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterBundleListViewer.uxml index 73f0c86..460124c 100644 --- a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterBundleListViewer.uxml +++ b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterBundleListViewer.uxml @@ -1,21 +1,19 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterSummaryViewer.cs b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterSummaryViewer.cs index c78b4c4..a12b53b 100644 --- a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterSummaryViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterSummaryViewer.cs @@ -27,7 +27,6 @@ namespace YooAsset.Editor private TemplateContainer _root; private ListView _listView; - private BuildReport _buildReport; private readonly List _items = new List(); @@ -37,7 +36,7 @@ namespace YooAsset.Editor public void InitViewer() { // 加载布局文件 - _visualAsset = EditorHelper.LoadWindowUXML(); + _visualAsset = UxmlLoader.LoadWindowUXML(); if (_visualAsset == null) return; @@ -55,14 +54,12 @@ namespace YooAsset.Editor /// public void FillViewData(BuildReport buildReport) { - _buildReport = buildReport; - _items.Clear(); _items.Add(new ItemWrapper("YooAsset版本", buildReport.Summary.YooVersion)); _items.Add(new ItemWrapper("引擎版本", buildReport.Summary.UnityVersion)); _items.Add(new ItemWrapper("构建时间", buildReport.Summary.BuildDate)); - _items.Add(new ItemWrapper("构建耗时", $"{buildReport.Summary.BuildSeconds}秒")); + _items.Add(new ItemWrapper("构建耗时", ConvertTime(buildReport.Summary.BuildSeconds))); _items.Add(new ItemWrapper("构建平台", $"{buildReport.Summary.BuildTarget}")); _items.Add(new ItemWrapper("构建管线", $"{buildReport.Summary.BuildPipeline}")); _items.Add(new ItemWrapper("构建模式", $"{buildReport.Summary.BuildMode}")); @@ -154,16 +151,23 @@ namespace YooAsset.Editor label2.text = itemWrapper.Value; } + private string ConvertTime(int time) + { + if (time <= 60) + { + return $"{time}秒钟"; + } + else + { + int minute = time / 60; + return $"{minute}分钟"; + } + } private string ConvertSize(long size) { if (size == 0) return "0"; - if (size < 1024) - return $"{size} Bytes"; - else if (size < 1024 * 1024) - return $"{(int)(size / 1024)} KB"; - else - return $"{(int)(size / (1024 * 1024))} MB"; + return EditorUtility.FormatBytes(size); } } } diff --git a/Assets/YooAsset/Editor/EditorDefine.cs b/Assets/YooAsset/Editor/EditorDefine.cs index cbb03fc..1cff7da 100644 --- a/Assets/YooAsset/Editor/EditorDefine.cs +++ b/Assets/YooAsset/Editor/EditorDefine.cs @@ -2,13 +2,13 @@ namespace YooAsset.Editor { - public class EditorDefine + public class WindowsDefine { #if UNITY_2019_4_OR_NEWER /// /// 停靠窗口类型集合 /// - public static readonly Type[] DockedWindowTypes = + public static readonly Type[] DockedWindowTypes = { typeof(AssetBundleBuilderWindow), typeof(AssetBundleCollectorWindow), diff --git a/Assets/YooAsset/Editor/EditorHelper.cs b/Assets/YooAsset/Editor/EditorHelper.cs deleted file mode 100644 index 08b3b4a..0000000 --- a/Assets/YooAsset/Editor/EditorHelper.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; - -namespace YooAsset.Editor -{ - public class EditorHelper - { -#if UNITY_2019_4_OR_NEWER - private readonly static Dictionary _uxmlDic = new Dictionary(); - - /* - static EditorHelper() - { - // 资源包收集 - _uxmlDic.Add(typeof(AssetBundleCollectorWindow), "355c4ac5cdebddc4c8362bed6f17a79e"); - - // 资源包构建 - _uxmlDic.Add(typeof(AssetBundleBuilderWindow), "28ba29adb4949284e8c48893218b0d9a"); - - // 资源包调试 - _uxmlDic.Add(typeof(AssetBundleDebuggerWindow), "790db12999afd334e8fb6ba70ef0a947"); - _uxmlDic.Add(typeof(DebuggerAssetListViewer), "31c6096c1cb29b4469096b7b4942a322"); - _uxmlDic.Add(typeof(DebuggerBundleListViewer), "932a25ffd05c13c47994d66e9d73bc37"); - - // 构建报告 - _uxmlDic.Add(typeof(AssetBundleReporterWindow), "9052b72c383e95043a0c7e7f369b1ad7"); - _uxmlDic.Add(typeof(ReporterSummaryViewer), "f8929271050855e42a1ccc6b14993a04"); - _uxmlDic.Add(typeof(ReporterAssetListViewer), "5f81bc15a55ee0a49a266f9d71e2372b"); - _uxmlDic.Add(typeof(ReporterBundleListViewer), "56d6dbe0d65ce334a8996beb19612989"); - } - - /// - /// 加载窗口的布局文件 - /// - public static UnityEngine.UIElements.VisualTreeAsset LoadWindowUXML() where TWindow : class - { - var windowType = typeof(TWindow); - if (_uxmlDic.TryGetValue(windowType, out string uxmlGUID)) - { - string assetPath = AssetDatabase.GUIDToAssetPath(uxmlGUID); - if (string.IsNullOrEmpty(assetPath)) - throw new System.Exception($"Invalid YooAsset uxml guid : {uxmlGUID}"); - var visualTreeAsset = AssetDatabase.LoadAssetAtPath(assetPath); - if (visualTreeAsset == null) - throw new System.Exception($"Failed to load {windowType}.uxml"); - return visualTreeAsset; - } - else - { - throw new System.Exception($"Invalid YooAsset window type : {windowType}"); - } - } - */ - - /// - /// 加载窗口的布局文件 - /// - public static UnityEngine.UIElements.VisualTreeAsset LoadWindowUXML() where TWindow : class - { - var windowType = typeof(TWindow); - - // 缓存里查询并加载 - if (_uxmlDic.TryGetValue(windowType, out string uxmlGUID)) - { - string assetPath = AssetDatabase.GUIDToAssetPath(uxmlGUID); - if (string.IsNullOrEmpty(assetPath)) - { - _uxmlDic.Clear(); - throw new System.Exception($"Invalid UXML GUID : {uxmlGUID} ! Please close the window and open it again !"); - } - var treeAsset = AssetDatabase.LoadAssetAtPath(assetPath); - return treeAsset; - } - - // 全局搜索并加载 - string[] guids = AssetDatabase.FindAssets(windowType.Name); - if (guids.Length == 0) - throw new System.Exception($"Not found any assets : {windowType.Name}"); - - foreach (string assetGUID in guids) - { - string assetPath = AssetDatabase.GUIDToAssetPath(assetGUID); - var assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); - if (assetType == typeof(UnityEngine.UIElements.VisualTreeAsset)) - { - _uxmlDic.Add(windowType, assetGUID); - var treeAsset = AssetDatabase.LoadAssetAtPath(assetPath); - return treeAsset; - } - } - throw new System.Exception($"Not found UXML file : {windowType.Name}"); - } -#endif - - /// - /// 加载相关的配置文件 - /// - public static TSetting LoadSettingData() where TSetting : ScriptableObject - { - var settingType = typeof(TSetting); - var guids = AssetDatabase.FindAssets($"t:{settingType.Name}"); - if (guids.Length == 0) - { - Debug.LogWarning($"Create new {settingType.Name}.asset"); - var setting = ScriptableObject.CreateInstance(); - string filePath = $"Assets/{settingType.Name}.asset"; - AssetDatabase.CreateAsset(setting, filePath); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - return setting; - } - else - { - if (guids.Length != 1) - { - foreach (var guid in guids) - { - string path = AssetDatabase.GUIDToAssetPath(guid); - Debug.LogWarning($"Found multiple file : {path}"); - } - throw new System.Exception($"Found multiple {settingType.Name} files !"); - } - - string filePath = AssetDatabase.GUIDToAssetPath(guids[0]); - var setting = AssetDatabase.LoadAssetAtPath(filePath); - return setting; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Editor/EditorTools.cs b/Assets/YooAsset/Editor/EditorTools.cs index 8b33a51..a03830f 100644 --- a/Assets/YooAsset/Editor/EditorTools.cs +++ b/Assets/YooAsset/Editor/EditorTools.cs @@ -582,7 +582,7 @@ namespace YooAsset.Editor /// 关键字 /// 分割的结果里是否包含关键字 /// 是否使用初始匹配的位置,否则使用末尾匹配的位置 - private static string Substring(string content, string key, bool includeKey, bool firstMatch = true) + public static string Substring(string content, string key, bool includeKey, bool firstMatch = true) { if (string.IsNullOrEmpty(key)) return content; diff --git a/Assets/YooAsset/Editor/SettingLoader.cs b/Assets/YooAsset/Editor/SettingLoader.cs new file mode 100644 index 0000000..2aaf434 --- /dev/null +++ b/Assets/YooAsset/Editor/SettingLoader.cs @@ -0,0 +1,45 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace YooAsset.Editor +{ + public class SettingLoader + { + /// + /// 加载相关的配置文件 + /// + public static TSetting LoadSettingData() where TSetting : ScriptableObject + { + var settingType = typeof(TSetting); + var guids = AssetDatabase.FindAssets($"t:{settingType.Name}"); + if (guids.Length == 0) + { + Debug.LogWarning($"Create new {settingType.Name}.asset"); + var setting = ScriptableObject.CreateInstance(); + string filePath = $"Assets/{settingType.Name}.asset"; + AssetDatabase.CreateAsset(setting, filePath); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + return setting; + } + else + { + if (guids.Length != 1) + { + foreach (var guid in guids) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + Debug.LogWarning($"Found multiple file : {path}"); + } + throw new System.Exception($"Found multiple {settingType.Name} files !"); + } + + string filePath = AssetDatabase.GUIDToAssetPath(guids[0]); + var setting = AssetDatabase.LoadAssetAtPath(filePath); + return setting; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Editor/EditorHelper.cs.meta b/Assets/YooAsset/Editor/SettingLoader.cs.meta similarity index 100% rename from Assets/YooAsset/Editor/EditorHelper.cs.meta rename to Assets/YooAsset/Editor/SettingLoader.cs.meta diff --git a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollector.cs b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollector.cs index 1d69b1b..420e7e4 100644 --- a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollector.cs +++ b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollector.cs @@ -12,134 +12,169 @@ namespace YooAsset.Editor { public static class ShaderVariantCollector { + private enum ESteps + { + None, + Prepare, + CollectAllMaterial, + CollectVariants, + CollectSleeping, + WaitingDone, + } + private const float WaitMilliseconds = 1000f; - private static string _saveFilePath; - private static bool _isStarted = false; - private static readonly Stopwatch _elapsedTime = new Stopwatch(); + private const float SleepMilliseconds = 100f; + private static string _savePath; + private static string _packageName; + private static int _processMaxNum; private static Action _completedCallback; - private static void EditorUpdate() - { - // 注意:一定要延迟保存才会起效 - if (_isStarted && _elapsedTime.ElapsedMilliseconds > WaitMilliseconds) - { - _isStarted = false; - _elapsedTime.Stop(); - EditorApplication.update -= EditorUpdate; + private static ESteps _steps = ESteps.None; + private static Stopwatch _elapsedTime; + private static List _allMaterials; + private static List _allSpheres = new List(1000); - // 保存结果 - ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_saveFilePath); - - // 创建清单 - CreateManifest(); - - Debug.Log($"搜集SVC完毕!"); - _completedCallback?.Invoke(); - } - } /// /// 开始收集 /// - public static void Run(string saveFilePath, Action completedCallback) + public static void Run(string savePath, string packageName, int processMaxNum, Action completedCallback) { - if (_isStarted) + if (_steps != ESteps.None) return; - if (Path.HasExtension(saveFilePath) == false) - saveFilePath = $"{saveFilePath}.shadervariants"; - if (Path.GetExtension(saveFilePath) != ".shadervariants") + if (Path.HasExtension(savePath) == false) + savePath = $"{savePath}.shadervariants"; + if (Path.GetExtension(savePath) != ".shadervariants") throw new System.Exception("Shader variant file extension is invalid."); + if (string.IsNullOrEmpty(packageName)) + throw new System.Exception("Package name is null or empty !"); // 注意:先删除再保存,否则ShaderVariantCollection内容将无法及时刷新 - AssetDatabase.DeleteAsset(ShaderVariantCollectorSettingData.Setting.SavePath); - EditorTools.CreateFileDirectory(saveFilePath); - _saveFilePath = saveFilePath; + AssetDatabase.DeleteAsset(savePath); + EditorTools.CreateFileDirectory(savePath); + _savePath = savePath; + _packageName = packageName; + _processMaxNum = processMaxNum; _completedCallback = completedCallback; // 聚焦到游戏窗口 EditorTools.FocusUnityGameWindow(); - // 清空旧数据 - ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection(); - // 创建临时测试场景 CreateTempScene(); - // 收集着色器变种 - var materials = GetAllMaterials(); - CollectVariants(materials); - + _steps = ESteps.Prepare; EditorApplication.update += EditorUpdate; - _isStarted = true; - _elapsedTime.Reset(); - _elapsedTime.Start(); } + private static void EditorUpdate() + { + if (_steps == ESteps.None) + return; + + if (_steps == ESteps.Prepare) + { + ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection(); + _steps = ESteps.CollectAllMaterial; + return; //等待一帧 + } + + if (_steps == ESteps.CollectAllMaterial) + { + _allMaterials = GetAllMaterials(); + _steps = ESteps.CollectVariants; + return; //等待一帧 + } + + if (_steps == ESteps.CollectVariants) + { + int count = Mathf.Min(_processMaxNum, _allMaterials.Count); + List range = _allMaterials.GetRange(0, count); + _allMaterials.RemoveRange(0, count); + CollectVariants(range); + + if (_allMaterials.Count > 0) + { + _elapsedTime = Stopwatch.StartNew(); + _steps = ESteps.CollectSleeping; + } + else + { + _elapsedTime = Stopwatch.StartNew(); + _steps = ESteps.WaitingDone; + } + } + + if (_steps == ESteps.CollectSleeping) + { + if (_elapsedTime.ElapsedMilliseconds > SleepMilliseconds) + { + DestroyAllSpheres(); + _elapsedTime.Stop(); + _steps = ESteps.CollectVariants; + } + } + + if (_steps == ESteps.WaitingDone) + { + // 注意:一定要延迟保存才会起效 + if (_elapsedTime.ElapsedMilliseconds > WaitMilliseconds) + { + _elapsedTime.Stop(); + _steps = ESteps.None; + + // 保存结果并创建清单 + ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_savePath); + CreateManifest(); + + Debug.Log($"搜集SVC完毕!"); + EditorApplication.update -= EditorUpdate; + _completedCallback?.Invoke(); + } + } + } private static void CreateTempScene() { EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); } - private static List GetAllMaterials() + private static List GetAllMaterials() { int progressValue = 0; List allAssets = new List(1000); // 获取所有打包的资源 - List allCollectAssetInfos = new List(); - List collectResults = AssetBundleCollectorSettingData.Setting.GetAllPackageAssets(EBuildMode.DryRunBuild); - foreach (var collectResult in collectResults) + CollectResult collectResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(EBuildMode.DryRunBuild, _packageName); + foreach (var assetInfo in collectResult.CollectAssets) { - allCollectAssetInfos.AddRange(collectResult.CollectAssets); - } - List allAssetPath = allCollectAssetInfos.Select(t => t.AssetPath).ToList(); - foreach (var assetPath in allAssetPath) - { - string[] depends = AssetDatabase.GetDependencies(assetPath, true); - foreach (var depend in depends) + string[] depends = AssetDatabase.GetDependencies(assetInfo.AssetPath, true); + foreach (var dependAsset in depends) { - if (allAssets.Contains(depend) == false) - allAssets.Add(depend); + if (allAssets.Contains(dependAsset) == false) + allAssets.Add(dependAsset); } - EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, allAssetPath.Count); + EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, collectResult.CollectAssets.Count); } EditorTools.ClearProgressBar(); // 搜集所有材质球 progressValue = 0; - var shaderDic = new Dictionary>(100); + List allMaterial = new List(1000); foreach (var assetPath in allAssets) { System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); if (assetType == typeof(UnityEngine.Material)) { - var material = AssetDatabase.LoadAssetAtPath(assetPath); - var shader = material.shader; - if (shader == null) - continue; - - if (shaderDic.ContainsKey(shader) == false) - { - shaderDic.Add(shader, new List()); - } - if (shaderDic[shader].Contains(material) == false) - { - shaderDic[shader].Add(material); - } + allMaterial.Add(assetPath); } EditorTools.DisplayProgressBar("搜集所有材质球", ++progressValue, allAssets.Count); } EditorTools.ClearProgressBar(); // 返回结果 - var materials = new List(1000); - foreach (var valuePair in shaderDic) - { - materials.AddRange(valuePair.Value); - } - return materials; + return allMaterial; } - private static void CollectVariants(List materials) + private static void CollectVariants(List materials) { Camera camera = Camera.main; if (camera == null) @@ -164,7 +199,9 @@ namespace YooAsset.Editor { var material = materials[i]; var position = new Vector3(x - halfWidth + 1f, y - halfHeight + 1f, 0f); - CreateSphere(material, position, i); + var go = CreateSphere(material, position, i); + if (go != null) + _allSpheres.Add(go); if (x == xMax) { x = 0; @@ -174,27 +211,44 @@ namespace YooAsset.Editor { x++; } - EditorTools.DisplayProgressBar("测试所有材质球", ++progressValue, materials.Count); + EditorTools.DisplayProgressBar("照射所有材质球", ++progressValue, materials.Count); } EditorTools.ClearProgressBar(); } - private static void CreateSphere(Material material, Vector3 position, int index) + private static GameObject CreateSphere(string assetPath, Vector3 position, int index) { + var material = AssetDatabase.LoadAssetAtPath(assetPath); + var shader = material.shader; + if (shader == null) + return null; + var go = GameObject.CreatePrimitive(PrimitiveType.Sphere); - go.GetComponent().material = material; + go.GetComponent().sharedMaterial = material; go.transform.position = position; - go.name = $"Sphere_{index}|{material.name}"; + go.name = $"Sphere_{index} | {material.name}"; + return go; + } + private static void DestroyAllSpheres() + { + foreach(var go in _allSpheres) + { + GameObject.DestroyImmediate(go); + } + _allSpheres.Clear(); + + // 尝试释放编辑器加载的资源 + EditorUtility.UnloadUnusedAssetsImmediate(true); } private static void CreateManifest() { AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); - ShaderVariantCollection svc = AssetDatabase.LoadAssetAtPath(_saveFilePath); + ShaderVariantCollection svc = AssetDatabase.LoadAssetAtPath(_savePath); if (svc != null) { var wrapper = ShaderVariantCollectionManifest.Extract(svc); string jsonData = JsonUtility.ToJson(wrapper, true); - string savePath = _saveFilePath.Replace(".shadervariants", ".json"); + string savePath = _savePath.Replace(".shadervariants", ".json"); File.WriteAllText(savePath, jsonData); } diff --git a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSetting.cs b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSetting.cs index d7e9851..658cb1a 100644 --- a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSetting.cs +++ b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSetting.cs @@ -8,5 +8,15 @@ namespace YooAsset.Editor /// 文件存储路径 /// public string SavePath = "Assets/MyShaderVariants.shadervariants"; + + /// + /// 收集的包裹名称 + /// + public string CollectPackage = string.Empty; + + /// + /// 容器值 + /// + public int ProcessCapacity = 1000; } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSettingData.cs b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSettingData.cs index 465add8..7b097cf 100644 --- a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSettingData.cs +++ b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSettingData.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using UnityEngine; using UnityEditor; @@ -20,12 +19,17 @@ namespace YooAsset.Editor } } + /// + /// 配置数据是否被修改 + /// + public static bool IsDirty { set; get; } = false; + /// /// 加载配置文件 /// private static void LoadSettingData() { - _setting = EditorHelper.LoadSettingData(); + _setting = SettingLoader.LoadSettingData(); } /// @@ -35,6 +39,7 @@ namespace YooAsset.Editor { if (Setting != null) { + IsDirty = false; EditorUtility.SetDirty(Setting); AssetDatabase.SaveAssets(); Debug.Log($"{nameof(ShaderVariantCollectorSetting)}.asset is saved!"); diff --git a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorWindow.cs b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorWindow.cs index 9d8b9d9..46e9d39 100644 --- a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorWindow.cs +++ b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorWindow.cs @@ -14,14 +14,19 @@ namespace YooAsset.Editor [MenuItem("YooAsset/ShaderVariant Collector", false, 201)] public static void ShowExample() { - ShaderVariantCollectorWindow window = GetWindow("着色器变种收集工具", true, EditorDefine.DockedWindowTypes); + ShaderVariantCollectorWindow window = GetWindow("着色器变种收集工具", true, WindowsDefine.DockedWindowTypes); window.minSize = new Vector2(800, 600); } + private List _packageNames; + + private Button _saveButton; private Button _collectButton; private TextField _collectOutputField; private Label _currentShaderCountField; private Label _currentVariantCountField; + private SliderInt _processCapacitySlider; + private PopupField _packageField; public void CreateGUI() { @@ -30,36 +35,103 @@ namespace YooAsset.Editor VisualElement root = this.rootVisualElement; // 加载布局文件 - var visualAsset = EditorHelper.LoadWindowUXML(); + var visualAsset = UxmlLoader.LoadWindowUXML(); if (visualAsset == null) return; visualAsset.CloneTree(root); + // 配置保存按钮 + _saveButton = root.Q public void UnloadUnusedAssets() { + if (_isUnloadSafe == false) + { + YooLogger.Warning("Can not unload unused assets when processing resource loading !"); + return; + } + // 注意:资源包之间可能存在多层深层嵌套,需要多次循环释放。 int loopCount = 10; for (int i = 0; i < loopCount; i++) @@ -102,32 +123,21 @@ namespace YooAsset } private void UnloadUnusedAssetsInternal() { - if (_simulationOnEditor) + for (int i = _loaderList.Count - 1; i >= 0; i--) { - for (int i = _providers.Count - 1; i >= 0; i--) - { - if (_providers[i].CanDestroy()) - { - _providers[i].Destroy(); - _providers.RemoveAt(i); - } - } + BundleLoaderBase loader = _loaderList[i]; + loader.TryDestroyAllProviders(); } - else + + for (int i = _loaderList.Count - 1; i >= 0; i--) { - for (int i = _loaders.Count - 1; i >= 0; i--) + BundleLoaderBase loader = _loaderList[i]; + if (loader.CanDestroy()) { - BundleLoaderBase loader = _loaders[i]; - loader.TryDestroyAllProviders(); - } - for (int i = _loaders.Count - 1; i >= 0; i--) - { - BundleLoaderBase loader = _loaders[i]; - if (loader.CanDestroy()) - { - loader.Destroy(false); - _loaders.RemoveAt(i); - } + string bundleName = loader.MainBundleInfo.Bundle.BundleName; + loader.Destroy(false); + _loaderList.RemoveAt(i); + _loaderDic.Remove(bundleName); } } } @@ -137,17 +147,19 @@ namespace YooAsset /// public void ForceUnloadAllAssets() { - foreach (var provider in _providers) + foreach (var provider in _providerList) { provider.Destroy(); } - foreach (var loader in _loaders) + foreach (var loader in _loaderList) { loader.Destroy(true); } - _providers.Clear(); - _loaders.Clear(); + _providerList.Clear(); + _providerDic.Clear(); + _loaderList.Clear(); + _loaderDic.Clear(); ClearSceneHandle(); // 注意:调用底层接口释放所有资源 @@ -182,7 +194,8 @@ namespace YooAsset else provider = new BundledSceneProvider(this, providerGUID, assetInfo, sceneMode, activateOnLoad, priority); provider.InitSpawnDebugInfo(); - _providers.Add(provider); + _providerList.Add(provider); + _providerDic.Add(providerGUID, provider); } var handle = provider.CreateHandle(); @@ -213,7 +226,8 @@ namespace YooAsset else provider = new BundledAssetProvider(this, providerGUID, assetInfo); provider.InitSpawnDebugInfo(); - _providers.Add(provider); + _providerList.Add(provider); + _providerDic.Add(providerGUID, provider); } return provider.CreateHandle(); } @@ -240,7 +254,8 @@ namespace YooAsset else provider = new BundledSubAssetsProvider(this, providerGUID, assetInfo); provider.InitSpawnDebugInfo(); - _providers.Add(provider); + _providerList.Add(provider); + _providerDic.Add(providerGUID, provider); } return provider.CreateHandle(); } @@ -267,7 +282,8 @@ namespace YooAsset else provider = new BundledRawFileProvider(this, providerGUID, assetInfo); provider.InitSpawnDebugInfo(); - _providers.Add(provider); + _providerList.Add(provider); + _providerDic.Add(providerGUID, provider); } return provider.CreateHandle(); } @@ -281,9 +297,6 @@ namespace YooAsset // 释放子场景句柄 _sceneHandles[providerGUID].ReleaseInternal(); _sceneHandles.Remove(providerGUID); - - // 卸载未被使用的资源(包括场景) - UnloadUnusedAssets(); } internal void UnloadAllScene() { @@ -293,9 +306,6 @@ namespace YooAsset valuePair.Value.ReleaseInternal(); } _sceneHandles.Clear(); - - // 卸载未被使用的资源(包括场景) - UnloadUnusedAssets(); } internal void ClearSceneHandle() { @@ -338,64 +348,71 @@ namespace YooAsset { foreach (var provider in providers) { - _providers.Remove(provider); + _providerList.Remove(provider); + _providerDic.Remove(provider.ProviderGUID); } } + internal bool CheckBundleDestroyed(int bundleID) + { + string bundleName = BundleServices.GetBundleName(bundleID); + BundleLoaderBase loader = TryGetAssetBundleLoader(bundleName); + if (loader == null) + return true; + return loader.IsDestroyed; + } private BundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo) { // 如果加载器已经存在 - BundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.Bundle.BundleName); + string bundleName = bundleInfo.Bundle.BundleName; + BundleLoaderBase loader = TryGetAssetBundleLoader(bundleName); if (loader != null) return loader; // 新增下载需求 -#if UNITY_WEBGL - loader = new AssetBundleWebLoader(this, bundleInfo); -#else - if (bundleInfo.Bundle.IsRawFile) - loader = new RawBundleFileLoader(this, bundleInfo); + if (_simulationOnEditor) + { + loader = new VirtualBundleFileLoader(this, bundleInfo); + } else - loader = new AssetBundleFileLoader(this, bundleInfo); + { +#if UNITY_WEBGL + if (bundleInfo.Bundle.IsRawFile) + loader = new RawBundleWebLoader(this, bundleInfo); + else + loader = new AssetBundleWebLoader(this, bundleInfo); +#else + if (bundleInfo.Bundle.IsRawFile) + loader = new RawBundleFileLoader(this, bundleInfo); + else + loader = new AssetBundleFileLoader(this, bundleInfo); #endif + } - _loaders.Add(loader); + _loaderList.Add(loader); + _loaderDic.Add(bundleName, loader); return loader; } private BundleLoaderBase TryGetAssetBundleLoader(string bundleName) { - BundleLoaderBase loader = null; - for (int i = 0; i < _loaders.Count; i++) - { - BundleLoaderBase temp = _loaders[i]; - if (temp.MainBundleInfo.Bundle.BundleName.Equals(bundleName)) - { - loader = temp; - break; - } - } - return loader; + if (_loaderDic.TryGetValue(bundleName, out BundleLoaderBase value)) + return value; + else + return null; } private ProviderBase TryGetProvider(string providerGUID) { - ProviderBase provider = null; - for (int i = 0; i < _providers.Count; i++) - { - ProviderBase temp = _providers[i]; - if (temp.ProviderGUID.Equals(providerGUID)) - { - provider = temp; - break; - } - } - return provider; + if (_providerDic.TryGetValue(providerGUID, out ProviderBase value)) + return value; + else + return null; } #region 调试信息 internal List GetDebugReportInfos() { - List result = new List(_providers.Count); - foreach (var provider in _providers) + List result = new List(_providerList.Count); + foreach (var provider in _providerList) { DebugProviderInfo providerInfo = new DebugProviderInfo(); providerInfo.AssetPath = provider.MainAssetInfo.AssetPath; @@ -405,22 +422,17 @@ namespace YooAsset providerInfo.RefCount = provider.RefCount; providerInfo.Status = provider.Status.ToString(); providerInfo.DependBundleInfos = new List(); + provider.GetBundleDebugInfos(providerInfo.DependBundleInfos); result.Add(providerInfo); - - if (provider is BundledProvider) - { - BundledProvider temp = provider as BundledProvider; - temp.GetBundleDebugInfos(providerInfo.DependBundleInfos); - } } return result; } internal List GetLoadedBundleInfos() { List result = new List(100); - foreach (var bundleLoader in _loaders) + foreach (var loader in _loaderList) { - result.Add(bundleLoader.MainBundleInfo); + result.Add(loader.MainBundleInfo); } return result; } diff --git a/Assets/YooAsset/Runtime/AssetSystem/Handles/AssetOperationHandle.cs b/Assets/YooAsset/Runtime/AssetSystem/Handles/AssetOperationHandle.cs index f9f9451..24a43d2 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Handles/AssetOperationHandle.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Handles/AssetOperationHandle.cs @@ -92,58 +92,63 @@ namespace YooAsset /// /// 同步初始化游戏对象 /// - /// 父类对象 - /// - public GameObject InstantiateSync(Transform parent = null) + public GameObject InstantiateSync() { - return InstantiateSyncInternal(Vector3.zero, Quaternion.identity, parent); + return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, null, false); } - - /// - /// 同步初始化游戏对象 - /// - /// 坐标 - /// 角度 - /// 父类对象 - public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent = null) + public GameObject InstantiateSync(Transform parent) { - return InstantiateSyncInternal(position, rotation, parent); + return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, false); + } + public GameObject InstantiateSync(Transform parent, bool worldPositionStays) + { + return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays); + } + public GameObject InstantiateSync(Vector3 position, Quaternion rotation) + { + return InstantiateSyncInternal(true, position, rotation, null, false); + } + public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent) + { + return InstantiateSyncInternal(true, position, rotation, parent, false); } /// /// 异步初始化游戏对象 /// - /// 父类对象 - public InstantiateOperation InstantiateAsync(Transform parent = null) + public InstantiateOperation InstantiateAsync() { - return InstantiateAsyncInternal(Vector3.zero, Quaternion.identity, parent); + return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, null, false); + } + public InstantiateOperation InstantiateAsync(Transform parent) + { + return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, false); + } + public InstantiateOperation InstantiateAsync(Transform parent, bool worldPositionStays) + { + return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays); + } + public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation) + { + return InstantiateAsyncInternal(true, position, rotation, null, false); + } + public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent) + { + return InstantiateAsyncInternal(true, position, rotation, parent, false); } - /// - /// 异步初始化游戏对象 - /// - /// 坐标 - /// 角度 - /// 父类对象 - public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent = null) - { - return InstantiateAsyncInternal(position, rotation, parent); - } - - - private GameObject InstantiateSyncInternal(Vector3 position, Quaternion rotation, Transform parent) + private GameObject InstantiateSyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) { if (IsValidWithWarning == false) return null; if (Provider.AssetObject == null) return null; - GameObject clone = UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation, parent); - return clone; + return InstantiateOperation.InstantiateInternal(Provider.AssetObject, setPositionAndRotation, position, rotation, parent, worldPositionStays); } - private InstantiateOperation InstantiateAsyncInternal(Vector3 position, Quaternion rotation, Transform parent) + private InstantiateOperation InstantiateAsyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) { - InstantiateOperation operation = new InstantiateOperation(this, position, rotation, parent); + InstantiateOperation operation = new InstantiateOperation(this, setPositionAndRotation, position, rotation, parent, worldPositionStays); OperationSystem.StartOperation(operation); return operation; } diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs index 0ec9208..9de9906 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs @@ -26,7 +26,7 @@ namespace YooAsset private DownloaderBase _unpacker; private DownloaderBase _downloader; private AssetBundleCreateRequest _createRequest; - private FileStream _fileStream; + private Stream _stream; public AssetBundleFileLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo) @@ -46,7 +46,7 @@ namespace YooAsset if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) { _steps = ESteps.Download; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) { @@ -55,7 +55,7 @@ namespace YooAsset if (loadMethod == EBundleLoadMethod.LoadFromMemory || loadMethod == EBundleLoadMethod.LoadFromStream) { _steps = ESteps.Unpack; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { @@ -70,7 +70,7 @@ namespace YooAsset else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { _steps = ESteps.LoadFile; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { @@ -81,7 +81,7 @@ namespace YooAsset // 1. 从服务器下载 if (_steps == ESteps.Download) { - int failedTryAgain = int.MaxValue; + int failedTryAgain = Impl.DownloadFailedTryAgain; _downloader = DownloadSystem.BeginDownload(MainBundleInfo, failedTryAgain); _steps = ESteps.CheckDownload; } @@ -110,7 +110,7 @@ namespace YooAsset if (_steps == ESteps.Unpack) { int failedTryAgain = 1; - var bundleInfo = PatchManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); + var bundleInfo = ManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); _unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain); _steps = ESteps.CheckUnpack; } @@ -196,12 +196,12 @@ namespace YooAsset } else if (loadMethod == EBundleLoadMethod.LoadFromStream) { - _fileStream = Impl.DecryptionServices.LoadFromStream(fileInfo); + _stream = Impl.DecryptionServices.LoadFromStream(fileInfo); uint managedReadBufferSize = Impl.DecryptionServices.GetManagedReadBufferSize(); if (_isWaitForAsyncComplete) - CacheBundle = AssetBundle.LoadFromStream(_fileStream, 0, managedReadBufferSize); + CacheBundle = AssetBundle.LoadFromStream(_stream, 0, managedReadBufferSize); else - _createRequest = AssetBundle.LoadFromStreamAsync(_fileStream, 0, managedReadBufferSize); + _createRequest = AssetBundle.LoadFromStreamAsync(_stream, 0, managedReadBufferSize); } else { @@ -242,14 +242,11 @@ namespace YooAsset // 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { - string cacheLoadPath = MainBundleInfo.Bundle.CachedFilePath; - if (CacheSystem.VerifyBundle(MainBundleInfo.Bundle, EVerifyLevel.High) != EVerifyResult.Succeed) + var result = CacheSystem.VerifyingRecordFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID); + if (result != EVerifyResult.Succeed) { - if (File.Exists(cacheLoadPath)) - { - YooLogger.Error($"Delete the invalid cache file : {cacheLoadPath}"); - File.Delete(cacheLoadPath); - } + YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID}"); + CacheSystem.DiscardFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID); } } } @@ -268,11 +265,11 @@ namespace YooAsset { base.Destroy(forceDestroy); - if (_fileStream != null) + if (_stream != null) { - _fileStream.Close(); - _fileStream.Dispose(); - _fileStream = null; + _stream.Close(); + _stream.Dispose(); + _stream = null; } } @@ -289,9 +286,12 @@ namespace YooAsset // 文件解压 if (_unpacker != null) { - _unpacker.Update(); if (_unpacker.IsDone() == false) + { + _unpacker.WaitForAsyncComplete = true; + _unpacker.Update(); continue; + } } // 保险机制 @@ -302,7 +302,7 @@ namespace YooAsset if (_isShowWaitForAsyncError == false) { _isShowWaitForAsyncError = true; - YooLogger.Error($"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !"); + YooLogger.Error($"{nameof(WaitForAsyncComplete)} failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !"); } break; } diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs index 5a68de7..f3fedb5 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs @@ -7,6 +7,9 @@ using UnityEngine.Networking; namespace YooAsset { + /// + /// WebGL平台加载器 + /// internal sealed class AssetBundleWebLoader : BundleLoaderBase { private enum ESteps @@ -24,7 +27,6 @@ namespace YooAsset private ESteps _steps = ESteps.None; private float _tryTimer = 0; - private bool _isShowWaitForAsyncError = false; private DownloaderBase _downloader; private UnityWebRequest _webRequest; private AssetBundleCreateRequest _createRequest; @@ -47,7 +49,7 @@ namespace YooAsset if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) { _steps = ESteps.Download; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) { @@ -57,7 +59,7 @@ namespace YooAsset else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { _steps = ESteps.LoadCacheFile; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { @@ -68,7 +70,7 @@ namespace YooAsset // 1. 从服务器下载 if (_steps == ESteps.Download) { - int failedTryAgain = int.MaxValue; + int failedTryAgain = Impl.DownloadFailedTryAgain; _downloader = DownloadSystem.BeginDownload(MainBundleInfo, failedTryAgain); _steps = ESteps.CheckDownload; } @@ -147,14 +149,11 @@ namespace YooAsset // 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { - string cacheLoadPath = MainBundleInfo.Bundle.CachedFilePath; - if (CacheSystem.VerifyBundle(MainBundleInfo.Bundle, EVerifyLevel.High) != EVerifyResult.Succeed) + var result = CacheSystem.VerifyingRecordFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID); + if (result != EVerifyResult.Succeed) { - if (File.Exists(cacheLoadPath)) - { - YooLogger.Error($"Delete the invalid cache file : {cacheLoadPath}"); - File.Delete(cacheLoadPath); - } + YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID}"); + CacheSystem.DiscardFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID); } } } @@ -228,10 +227,11 @@ namespace YooAsset /// public override void WaitForAsyncComplete() { - if (_isShowWaitForAsyncError == false) + if (IsDone() == false) { - _isShowWaitForAsyncError = true; - YooLogger.Error($"WebGL platform not support {nameof(WaitForAsyncComplete)} ! Use the async load method instead of the sync load method !"); + Status = EStatus.Failed; + LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !"; + YooLogger.Error(LastError); } } } diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/BundleLoaderBase.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/BundleLoaderBase.cs index dc9ef22..b559029 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/BundleLoaderBase.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/BundleLoaderBase.cs @@ -100,7 +100,18 @@ namespace YooAsset if (IsDone() == false) return false; - return RefCount <= 0; + if (RefCount > 0) + return false; + + // 检查引用链上的资源包是否已经全部销毁 + // 注意:互相引用的资源包无法卸载! + foreach (var bundleID in MainBundleInfo.Bundle.ReferenceIDs) + { + if (Impl.CheckBundleDestroyed(bundleID) == false) + return false; + } + + return true; } /// @@ -123,14 +134,14 @@ namespace YooAsset return; // 销毁所有Providers - foreach (var provider in _providers) { - provider.Destroy(); + foreach (var provider in _providers) + { + provider.Destroy(); + } + Impl.RemoveBundleProviders(_providers); + _providers.Clear(); } - - // 从列表里移除Providers - Impl.RemoveBundleProviders(_providers); - _providers.Clear(); } diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleFileLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleFileLoader.cs index cf6fa78..b7ee11a 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleFileLoader.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleFileLoader.cs @@ -16,7 +16,6 @@ namespace YooAsset } private ESteps _steps = ESteps.None; - private bool _isShowWaitForAsyncError = false; private DownloaderBase _unpacker; private DownloaderBase _downloader; @@ -38,13 +37,13 @@ namespace YooAsset if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) { _steps = ESteps.Download; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) { -#if UNITY_ANDROID || UNITY_WEBGL +#if UNITY_ANDROID _steps = ESteps.Unpack; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; #else _steps = ESteps.CheckFile; FileLoadPath = MainBundleInfo.Bundle.StreamingFilePath; @@ -53,7 +52,7 @@ namespace YooAsset else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { _steps = ESteps.CheckFile; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { @@ -64,7 +63,7 @@ namespace YooAsset // 1. 下载远端文件 if (_steps == ESteps.Download) { - int failedTryAgain = int.MaxValue; + int failedTryAgain = Impl.DownloadFailedTryAgain; _downloader = DownloadSystem.BeginDownload(MainBundleInfo, failedTryAgain); _steps = ESteps.CheckDownload; } @@ -93,7 +92,7 @@ namespace YooAsset if (_steps == ESteps.Unpack) { int failedTryAgain = 1; - var bundleInfo = PatchManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); + var bundleInfo = ManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); _unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain); _steps = ESteps.CheckUnpack; } @@ -125,13 +124,14 @@ namespace YooAsset DownloadProgress = 1f; DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize; - _steps = ESteps.Done; if (File.Exists(FileLoadPath)) { + _steps = ESteps.Done; Status = EStatus.Succeed; } else { + _steps = ESteps.Done; Status = EStatus.Failed; LastError = $"Raw file not found : {FileLoadPath}"; } @@ -149,20 +149,24 @@ namespace YooAsset // 文件解压 if (_unpacker != null) { - _unpacker.Update(); if (_unpacker.IsDone() == false) + { + _unpacker.WaitForAsyncComplete = true; + _unpacker.Update(); continue; + } } // 保险机制 - // 注意:如果需要从WEB端下载资源,可能会触发保险机制! + // 注意:如果需要从远端下载资源,可能会触发保险机制! frame--; if (frame == 0) { - if (_isShowWaitForAsyncError == false) + if (IsDone() == false) { - _isShowWaitForAsyncError = true; - YooLogger.Error($"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !"); + Status = EStatus.Failed; + LastError = $"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !"; + YooLogger.Error(LastError); } break; } diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleWebLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleWebLoader.cs new file mode 100644 index 0000000..b5513d6 --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleWebLoader.cs @@ -0,0 +1,151 @@ +using System.IO; + +namespace YooAsset +{ + /// + /// WebGL平台加载器 + /// + internal class RawBundleWebLoader : BundleLoaderBase + { + private enum ESteps + { + None, + Download, + CheckDownload, + Website, + CheckWebsite, + CheckFile, + Done, + } + + private ESteps _steps = ESteps.None; + private DownloaderBase _website; + private DownloaderBase _downloader; + + + public RawBundleWebLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo) + { + } + + /// + /// 轮询更新 + /// + public override void Update() + { + if (_steps == ESteps.Done) + return; + + if (_steps == ESteps.None) + { + if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) + { + _steps = ESteps.Download; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; + } + else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) + { + _steps = ESteps.Website; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; + } + else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) + { + _steps = ESteps.CheckFile; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; + } + else + { + throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString()); + } + } + + // 1. 下载远端文件 + if (_steps == ESteps.Download) + { + int failedTryAgain = Impl.DownloadFailedTryAgain; + _downloader = DownloadSystem.BeginDownload(MainBundleInfo, failedTryAgain); + _steps = ESteps.CheckDownload; + } + + // 2. 检测下载结果 + if (_steps == ESteps.CheckDownload) + { + DownloadProgress = _downloader.DownloadProgress; + DownloadedBytes = _downloader.DownloadedBytes; + if (_downloader.IsDone() == false) + return; + + if (_downloader.HasError()) + { + _steps = ESteps.Done; + Status = EStatus.Failed; + LastError = _downloader.GetLastError(); + } + else + { + _steps = ESteps.CheckFile; + } + } + + // 3. 从站点下载 + if (_steps == ESteps.Website) + { + int failedTryAgain = 1; + var bundleInfo = ManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); + _website = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain); + _steps = ESteps.CheckWebsite; + } + + // 4. 检测站点下载 + if (_steps == ESteps.CheckWebsite) + { + DownloadProgress = _website.DownloadProgress; + DownloadedBytes = _website.DownloadedBytes; + if (_website.IsDone() == false) + return; + + if (_website.HasError()) + { + _steps = ESteps.Done; + Status = EStatus.Failed; + LastError = _website.GetLastError(); + } + else + { + _steps = ESteps.CheckFile; + } + } + + // 5. 检测结果 + if (_steps == ESteps.CheckFile) + { + // 设置下载进度 + DownloadProgress = 1f; + DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize; + + _steps = ESteps.Done; + if (File.Exists(FileLoadPath)) + { + Status = EStatus.Succeed; + } + else + { + Status = EStatus.Failed; + LastError = $"Raw file not found : {FileLoadPath}"; + } + } + } + + /// + /// 主线程等待异步操作完毕 + /// + public override void WaitForAsyncComplete() + { + if (IsDone() == false) + { + Status = EStatus.Failed; + LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !"; + YooLogger.Error(LastError); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleWebLoader.cs.meta b/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleWebLoader.cs.meta new file mode 100644 index 0000000..6420e98 --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleWebLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d16b689f73611e44bd01a4cc429a6ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/VirtualBundleFileLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/VirtualBundleFileLoader.cs new file mode 100644 index 0000000..e429fbe --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/VirtualBundleFileLoader.cs @@ -0,0 +1,82 @@ + +namespace YooAsset +{ + internal class VirtualBundleFileLoader : BundleLoaderBase + { + private enum ESteps + { + None, + CheckFile, + Done, + } + + private ESteps _steps = ESteps.None; + + public VirtualBundleFileLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo) + { + } + + /// + /// 轮询更新 + /// + public override void Update() + { + if (_steps == ESteps.Done) + return; + + if (_steps == ESteps.None) + { + if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromEditor) + { + _steps = ESteps.CheckFile; + } + else + { + throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString()); + } + } + + // 1. 检测结果 + if (_steps == ESteps.CheckFile) + { + // 设置下载进度 + DownloadProgress = 1f; + DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize; + + _steps = ESteps.Done; + Status = EStatus.Succeed; + } + } + + /// + /// 主线程等待异步操作完毕 + /// + public override void WaitForAsyncComplete() + { + int frame = 1000; + while (true) + { + // 保险机制 + // 注意:如果需要从远端下载资源,可能会触发保险机制! + frame--; + if (frame == 0) + { + if (IsDone() == false) + { + Status = EStatus.Failed; + LastError = $"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !"; + YooLogger.Error(LastError); + } + break; + } + + // 驱动流程 + Update(); + + // 完成后退出 + if (IsDone()) + break; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/VirtualBundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/AssetSystem/Loader/VirtualBundleFileLoader.cs.meta new file mode 100644 index 0000000..c8289e1 --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/VirtualBundleFileLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b9023a940b496549894d9d8872219fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/AssetSystem/Operations/InstantiateOperation.cs b/Assets/YooAsset/Runtime/AssetSystem/Operations/InstantiateOperation.cs index 76b39b8..02f2d5a 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Operations/InstantiateOperation.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Operations/InstantiateOperation.cs @@ -12,9 +12,11 @@ namespace YooAsset } private readonly AssetOperationHandle _handle; + private readonly bool _setPositionAndRotation; private readonly Vector3 _position; private readonly Quaternion _rotation; private readonly Transform _parent; + private readonly bool _worldPositionStays; private ESteps _steps = ESteps.None; /// @@ -23,12 +25,14 @@ namespace YooAsset public GameObject Result = null; - internal InstantiateOperation(AssetOperationHandle handle, Vector3 position, Quaternion rotation, Transform parent) + internal InstantiateOperation(AssetOperationHandle handle, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) { _handle = handle; + _setPositionAndRotation = setPositionAndRotation; _position = position; _rotation = rotation; _parent = parent; + _worldPositionStays = worldPositionStays; } internal override void Start() { @@ -61,7 +65,7 @@ namespace YooAsset } // 实例化游戏对象 - Result = Object.Instantiate(_handle.AssetObject as GameObject, _position, _rotation, _parent); + Result = InstantiateInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays); _steps = ESteps.Done; Status = EOperationStatus.Succeed; @@ -91,5 +95,38 @@ namespace YooAsset _handle.WaitForAsyncComplete(); Update(); } + + internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) + { + if (assetObject == null) + return null; + + if (setPositionAndRotation) + { + if (parent != null) + { + GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent); + return clone; + } + else + { + GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation); + return clone; + } + } + else + { + if (parent != null) + { + GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays); + return clone; + } + else + { + GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject); + return clone; + } + } + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledAssetProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledAssetProvider.cs index 56bd186..82acd2b 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledAssetProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledAssetProvider.cs @@ -4,7 +4,7 @@ using UnityEngine; namespace YooAsset { - internal sealed class BundledAssetProvider : BundledProvider + internal sealed class BundledAssetProvider : ProviderBase { private AssetBundleRequest _cacheRequest; @@ -13,7 +13,7 @@ namespace YooAsset } public override void Update() { - DebugRecording(); + DebugBeginRecording(); if (IsDone) return; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs deleted file mode 100644 index 340173a..0000000 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal abstract class BundledProvider : ProviderBase - { - protected BundleLoaderBase OwnerBundle { private set; get; } - protected DependAssetBundleGroup DependBundleGroup { private set; get; } - - public BundledProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo) - { - OwnerBundle = impl.CreateOwnerAssetBundleLoader(assetInfo); - OwnerBundle.Reference(); - OwnerBundle.AddProvider(this); - - var dependBundles = impl.CreateDependAssetBundleLoaders(assetInfo); - DependBundleGroup = new DependAssetBundleGroup(dependBundles); - DependBundleGroup.Reference(); - } - public override void Destroy() - { - base.Destroy(); - - // 释放资源包 - if (OwnerBundle != null) - { - OwnerBundle.Release(); - OwnerBundle = null; - } - if (DependBundleGroup != null) - { - DependBundleGroup.Release(); - DependBundleGroup = null; - } - } - - /// - /// 获取下载报告 - /// - public override DownloadReport GetDownloadReport() - { - DownloadReport result = new DownloadReport(); - result.TotalSize = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize; - result.DownloadedBytes = OwnerBundle.DownloadedBytes; - foreach (var dependBundle in DependBundleGroup.DependBundles) - { - result.TotalSize += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize; - result.DownloadedBytes += dependBundle.DownloadedBytes; - } - result.Progress = result.DownloadedBytes / result.TotalSize; - return result; - } - - /// - /// 获取资源包的调试信息列表 - /// - internal void GetBundleDebugInfos(List output) - { - var bundleInfo = new DebugBundleInfo(); - bundleInfo.BundleName = OwnerBundle.MainBundleInfo.Bundle.BundleName; - bundleInfo.RefCount = OwnerBundle.RefCount; - bundleInfo.Status = OwnerBundle.Status.ToString(); - output.Add(bundleInfo); - - DependBundleGroup.GetBundleDebugInfos(output); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledRawFileProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledRawFileProvider.cs index 80a2a9f..c8ee879 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledRawFileProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledRawFileProvider.cs @@ -1,14 +1,14 @@  namespace YooAsset { - internal class BundledRawFileProvider : BundledProvider + internal class BundledRawFileProvider : ProviderBase { public BundledRawFileProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo) { } public override void Update() { - DebugRecording(); + DebugBeginRecording(); if (IsDone) return; @@ -18,6 +18,7 @@ namespace YooAsset Status = EStatus.CheckBundle; } + // 1. 检测资源包 if (Status == EStatus.CheckBundle) { if (IsWaitForAsyncComplete) @@ -39,6 +40,7 @@ namespace YooAsset Status = EStatus.Checking; } + // 2. 检测加载结果 if (Status == EStatus.Checking) { RawFilePath = OwnerBundle.FileLoadPath; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSceneProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSceneProvider.cs index 6a9bd22..0364b86 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSceneProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSceneProvider.cs @@ -6,7 +6,7 @@ using UnityEngine.SceneManagement; namespace YooAsset { - internal sealed class BundledSceneProvider : BundledProvider + internal sealed class BundledSceneProvider : ProviderBase { public readonly LoadSceneMode SceneMode; private readonly string _sceneName; @@ -23,7 +23,7 @@ namespace YooAsset } public override void Update() { - DebugRecording(); + DebugBeginRecording(); if (IsDone) return; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSubAssetsProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSubAssetsProvider.cs index 800a548..36c6545 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSubAssetsProvider.cs @@ -4,7 +4,7 @@ using UnityEngine; namespace YooAsset { - internal sealed class BundledSubAssetsProvider : BundledProvider + internal sealed class BundledSubAssetsProvider : ProviderBase { private AssetBundleRequest _cacheRequest; @@ -13,7 +13,7 @@ namespace YooAsset } public override void Update() { - DebugRecording(); + DebugBeginRecording(); if (IsDone) return; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseAssetProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseAssetProvider.cs index 8363518..e3590a2 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseAssetProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseAssetProvider.cs @@ -28,14 +28,36 @@ namespace YooAsset return; } - Status = EStatus.Loading; + Status = EStatus.CheckBundle; // 注意:模拟异步加载效果提前返回 if (IsWaitForAsyncComplete == false) return; } - // 1. 加载资源对象 + // 1. 检测资源包 + if (Status == EStatus.CheckBundle) + { + if (IsWaitForAsyncComplete) + { + OwnerBundle.WaitForAsyncComplete(); + } + + if (OwnerBundle.IsDone() == false) + return; + + if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + { + Status = EStatus.Failed; + LastError = OwnerBundle.LastError; + InvokeCompletion(); + return; + } + + Status = EStatus.Loading; + } + + // 2. 加载资源对象 if (Status == EStatus.Loading) { if (MainAssetInfo.AssetType == null) @@ -45,7 +67,7 @@ namespace YooAsset Status = EStatus.Checking; } - // 2. 检测加载结果 + // 3. 检测加载结果 if (Status == EStatus.Checking) { Status = AssetObject == null ? EStatus.Failed : EStatus.Succeed; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseRawFileProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseRawFileProvider.cs index 3e609e8..167d287 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseRawFileProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseRawFileProvider.cs @@ -25,14 +25,37 @@ namespace YooAsset return; } - Status = EStatus.Checking; + Status = EStatus.CheckBundle; // 注意:模拟异步加载效果提前返回 if (IsWaitForAsyncComplete == false) return; } - if(Status == EStatus.Checking) + // 1. 检测资源包 + if (Status == EStatus.CheckBundle) + { + if (IsWaitForAsyncComplete) + { + OwnerBundle.WaitForAsyncComplete(); + } + + if (OwnerBundle.IsDone() == false) + return; + + if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + { + Status = EStatus.Failed; + LastError = OwnerBundle.LastError; + InvokeCompletion(); + return; + } + + Status = EStatus.Checking; + } + + // 2. 检测加载结果 + if (Status == EStatus.Checking) { RawFilePath = MainAssetInfo.AssetPath; Status = EStatus.Succeed; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSceneProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSceneProvider.cs index 962d64f..48b9497 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSceneProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSceneProvider.cs @@ -24,10 +24,32 @@ namespace YooAsset if (Status == EStatus.None) { + Status = EStatus.CheckBundle; + } + + // 1. 检测资源包 + if (Status == EStatus.CheckBundle) + { + if (IsWaitForAsyncComplete) + { + OwnerBundle.WaitForAsyncComplete(); + } + + if (OwnerBundle.IsDone() == false) + return; + + if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + { + Status = EStatus.Failed; + LastError = OwnerBundle.LastError; + InvokeCompletion(); + return; + } + Status = EStatus.Loading; } - // 1. 加载资源对象 + // 2. 加载资源对象 if (Status == EStatus.Loading) { LoadSceneParameters loadSceneParameters = new LoadSceneParameters(); @@ -49,7 +71,7 @@ namespace YooAsset } } - // 2. 检测加载结果 + // 3. 检测加载结果 if (Status == EStatus.Checking) { Progress = _asyncOp.progress; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSubAssetsProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSubAssetsProvider.cs index d6d1b94..f89d3e7 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSubAssetsProvider.cs @@ -28,14 +28,36 @@ namespace YooAsset return; } - Status = EStatus.Loading; + Status = EStatus.CheckBundle; // 注意:模拟异步加载效果提前返回 if (IsWaitForAsyncComplete == false) return; } - // 1. 加载资源对象 + // 1. 检测资源包 + if (Status == EStatus.CheckBundle) + { + if (IsWaitForAsyncComplete) + { + OwnerBundle.WaitForAsyncComplete(); + } + + if (OwnerBundle.IsDone() == false) + return; + + if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + { + Status = EStatus.Failed; + LastError = OwnerBundle.LastError; + InvokeCompletion(); + return; + } + + Status = EStatus.Loading; + } + + // 2. 加载资源对象 if (Status == EStatus.Loading) { if (MainAssetInfo.AssetType == null) @@ -56,7 +78,7 @@ namespace YooAsset Status = EStatus.Checking; } - // 2. 检测加载结果 + // 3. 检测加载结果 if (Status == EStatus.Checking) { Status = AllAssetObjects == null ? EStatus.Failed : EStatus.Succeed; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/ProviderBase.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/ProviderBase.cs index 806314c..aa01530 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/ProviderBase.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/ProviderBase.cs @@ -90,6 +90,8 @@ namespace YooAsset } + protected BundleLoaderBase OwnerBundle { private set; get; } + protected DependAssetBundleGroup DependBundleGroup { private set; get; } protected bool IsWaitForAsyncComplete { private set; get; } = false; private readonly List _handles = new List(); @@ -99,6 +101,18 @@ namespace YooAsset Impl = impl; ProviderGUID = providerGUID; MainAssetInfo = assetInfo; + + // 创建资源包加载器 + if (impl != null) + { + OwnerBundle = impl.CreateOwnerAssetBundleLoader(assetInfo); + OwnerBundle.Reference(); + OwnerBundle.AddProvider(this); + + var dependBundles = impl.CreateDependAssetBundleLoaders(assetInfo); + DependBundleGroup = new DependAssetBundleGroup(dependBundles); + DependBundleGroup.Reference(); + } } /// @@ -112,14 +126,18 @@ namespace YooAsset public virtual void Destroy() { IsDestroyed = true; - } - /// - /// 获取下载进度 - /// - public virtual DownloadReport GetDownloadReport() - { - return DownloadReport.CreateDefaultReport(); + // 释放资源包加载器 + if (OwnerBundle != null) + { + OwnerBundle.Release(); + OwnerBundle = null; + } + if (DependBundleGroup != null) + { + DependBundleGroup.Release(); + DependBundleGroup = null; + } } /// @@ -221,14 +239,17 @@ namespace YooAsset private TaskCompletionSource _taskCompletionSource; protected void InvokeCompletion() { + DebugEndRecording(); + // 进度百分百完成 Progress = 1f; // 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。 + // 注意:回调方法如果发生异常,会阻断列表里的后续回调方法! List tempers = new List(_handles); foreach (var hande in tempers) { - if (hande.IsValidWithWarning) + if (hande.IsValid) { hande.InvokeCallback(); } @@ -256,8 +277,7 @@ namespace YooAsset public long LoadingTime { protected set; get; } // 加载耗时统计 - private bool _isRecording = false; - private Stopwatch _watch; + private Stopwatch _watch = null; [Conditional("DEBUG")] public void InitSpawnDebugInfo() @@ -274,23 +294,54 @@ namespace YooAsset } [Conditional("DEBUG")] - protected void DebugRecording() + protected void DebugBeginRecording() { - if (_isRecording == false) + if (_watch == null) { - _isRecording = true; _watch = Stopwatch.StartNew(); } + } + [Conditional("DEBUG")] + private void DebugEndRecording() + { if (_watch != null) { - if (IsDone) - { - LoadingTime = _watch.ElapsedMilliseconds; - _watch = null; - } + LoadingTime = _watch.ElapsedMilliseconds; + _watch = null; } } + + /// + /// 获取下载报告 + /// + internal DownloadReport GetDownloadReport() + { + DownloadReport result = new DownloadReport(); + result.TotalSize = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize; + result.DownloadedBytes = OwnerBundle.DownloadedBytes; + foreach (var dependBundle in DependBundleGroup.DependBundles) + { + result.TotalSize += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize; + result.DownloadedBytes += dependBundle.DownloadedBytes; + } + result.Progress = (float)result.DownloadedBytes / result.TotalSize; + return result; + } + + /// + /// 获取资源包的调试信息列表 + /// + internal void GetBundleDebugInfos(List output) + { + var bundleInfo = new DebugBundleInfo(); + bundleInfo.BundleName = OwnerBundle.MainBundleInfo.Bundle.BundleName; + bundleInfo.RefCount = OwnerBundle.RefCount; + bundleInfo.Status = OwnerBundle.Status.ToString(); + output.Add(bundleInfo); + + DependBundleGroup.GetBundleDebugInfos(output); + } #endregion } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs new file mode 100644 index 0000000..e18e340 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs @@ -0,0 +1,36 @@ +using System; +using System.IO; + +namespace YooAsset +{ + internal class CacheFileInfo + { + private static readonly BufferWriter SharedBuffer = new BufferWriter(1024); + + /// + /// 写入资源包信息 + /// + public static void WriteInfoToFile(string filePath, string dataFileCRC, long dataFileSize) + { + using (FileStream fs = new FileStream(filePath, FileMode.Create)) + { + SharedBuffer.Clear(); + SharedBuffer.WriteUTF8(dataFileCRC); + SharedBuffer.WriteInt64(dataFileSize); + SharedBuffer.WriteToStream(fs); + fs.Flush(); + } + } + + /// + /// 读取资源包信息 + /// + public static void ReadInfoFromFile(string filePath, out string dataFileCRC, out long dataFileSize) + { + byte[] binaryData = FileUtility.ReadAllBytes(filePath); + BufferReader buffer = new BufferReader(binaryData); + dataFileCRC = buffer.ReadUTF8(); + dataFileSize = buffer.ReadInt64(); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta new file mode 100644 index 0000000..8d035ba --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e4a97c06e069c1146a881fcb359f9b4b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheSystem.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheSystem.cs index 501cdc1..94310ae 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/CacheSystem.cs +++ b/Assets/YooAsset/Runtime/CacheSystem/CacheSystem.cs @@ -2,18 +2,18 @@ using System.IO; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; namespace YooAsset { internal static class CacheSystem { - private readonly static Dictionary _cachedDic = new Dictionary(1000); + private readonly static Dictionary _cachedDic = new Dictionary(1000); /// /// 初始化时的验证级别 /// - public static EVerifyLevel InitVerifyLevel { set; get; } = EVerifyLevel.Low; - + public static EVerifyLevel InitVerifyLevel { set; get; } = EVerifyLevel.Middle; /// /// 清空所有数据 @@ -24,104 +24,137 @@ namespace YooAsset } /// - /// 查询是否为验证文件 - /// 注意:被收录的文件完整性是绝对有效的 + /// 获取缓存文件总数 /// - public static bool IsCached(PatchBundle patchBundle) + public static int GetCachedFilesCount(string packageName) { - string cacheKey = patchBundle.CacheKey; - if (_cachedDic.ContainsKey(cacheKey)) + var cache = GetOrCreateCache(packageName); + return cache.GetCachedFilesCount(); + } + + /// + /// 查询是否为验证文件 + /// + public static bool IsCached(string packageName, string cacheGUID) + { + var cache = GetOrCreateCache(packageName); + return cache.IsCached(cacheGUID); + } + + /// + /// 录入验证的文件 + /// + public static void RecordFile(string packageName, string cacheGUID, PackageCache.RecordWrapper wrapper) + { + //YooLogger.Log($"Record file : {packageName} = {cacheGUID}"); + var cache = GetOrCreateCache(packageName); + cache.Record(cacheGUID, wrapper); + } + + /// + /// 丢弃验证的文件(同时删除文件) + /// + public static void DiscardFile(string packageName, string cacheGUID) + { + var cache = GetOrCreateCache(packageName); + var wrapper = cache.TryGetWrapper(cacheGUID); + if (wrapper == null) + return; + + cache.Discard(cacheGUID); + + try { - string filePath = patchBundle.CachedFilePath; - if (File.Exists(filePath)) + string dataFilePath = wrapper.DataFilePath; + FileInfo fileInfo = new FileInfo(dataFilePath); + if (fileInfo.Exists) + fileInfo.Directory.Delete(true); + } + catch (Exception e) + { + YooLogger.Error($"Failed to delete cache file ! {e.Message}"); + } + } + + /// + /// 验证缓存文件(子线程内操作) + /// + public static EVerifyResult VerifyingCacheFile(VerifyCacheElement element) + { + try + { + if (InitVerifyLevel == EVerifyLevel.Low) { - return true; + if (File.Exists(element.InfoFilePath) == false) + return EVerifyResult.InfoFileNotExisted; + if (File.Exists(element.DataFilePath) == false) + return EVerifyResult.DataFileNotExisted; + return EVerifyResult.Succeed; } else { - _cachedDic.Remove(cacheKey); - YooLogger.Error($"Cache file is missing : {filePath}"); - return false; + if (File.Exists(element.InfoFilePath) == false) + return EVerifyResult.InfoFileNotExisted; + + // 解析信息文件获取验证数据 + CacheFileInfo.ReadInfoFromFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize); } } - else + catch (Exception) { - return false; + return EVerifyResult.Exception; } + + return VerifyingInternal(element.DataFilePath, element.DataFileSize, element.DataFileCRC, InitVerifyLevel); } /// - /// 缓存补丁包文件 + /// 验证下载文件(子线程内操作) /// - public static void CacheBundle(PatchBundle patchBundle) + public static EVerifyResult VerifyingTempFile(VerifyTempElement element) { - string cacheKey = patchBundle.CacheKey; - if (_cachedDic.ContainsKey(cacheKey) == false) + return VerifyingInternal(element.TempDataFilePath, element.FileSize, element.FileCRC, EVerifyLevel.High); + } + + /// + /// 验证记录文件(主线程内操作) + /// + public static EVerifyResult VerifyingRecordFile(string packageName, string cacheGUID) + { + var cache = GetOrCreateCache(packageName); + var wrapper = cache.TryGetWrapper(cacheGUID); + if (wrapper == null) + return EVerifyResult.CacheNotFound; + + EVerifyResult result = VerifyingInternal(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EVerifyLevel.High); + return result; + } + + /// + /// 获取未被使用的缓存文件 + /// + public static List GetUnusedCacheGUIDs(ResourcePackage package) + { + var cache = GetOrCreateCache(package.PackageName); + var keys = cache.GetAllKeys(); + List result = new List(keys.Count); + foreach (var cacheGUID in keys) { - string filePath = patchBundle.CachedFilePath; - YooLogger.Log($"Cache verify file : {filePath}"); - _cachedDic.Add(cacheKey, patchBundle); - } - } - - /// - /// 验证补丁包文件 - /// - public static EVerifyResult VerifyBundle(PatchBundle patchBundle, EVerifyLevel verifyLevel) - { - return VerifyContentInternal(patchBundle.CachedFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel); - } - - /// - /// 验证并缓存本地文件 - /// - public static EVerifyResult VerifyAndCacheLocalBundleFile(PatchBundle patchBundle, EVerifyLevel verifyLevel) - { - var verifyResult = VerifyContentInternal(patchBundle.CachedFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel); - if (verifyResult == EVerifyResult.Succeed) - CacheBundle(patchBundle); - return verifyResult; - } - - /// - /// 验证并缓存下载文件 - /// - public static EVerifyResult VerifyAndCacheDownloadBundleFile(string tempFilePath, PatchBundle patchBundle, EVerifyLevel verifyLevel) - { - var verifyResult = VerifyContentInternal(tempFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel); - if (verifyResult == EVerifyResult.Succeed) - { - try + if (package.IsIncludeBundleFile(cacheGUID) == false) { - string destFilePath = patchBundle.CachedFilePath; - if (File.Exists(destFilePath)) - File.Delete(destFilePath); - - FileInfo fileInfo = new FileInfo(tempFilePath); - fileInfo.MoveTo(destFilePath); - } - catch (Exception) - { - verifyResult = EVerifyResult.FileMoveFailed; - } - - if (verifyResult == EVerifyResult.Succeed) - { - CacheBundle(patchBundle); + result.Add(cacheGUID); } } - return verifyResult; + return result; } - /// - /// 验证文件完整性 - /// - private static EVerifyResult VerifyContentInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel) + + private static EVerifyResult VerifyingInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel) { try { if (File.Exists(filePath) == false) - return EVerifyResult.FileNotExisted; + return EVerifyResult.DataFileNotExisted; // 先验证文件大小 long size = FileUtility.GetFileSize(filePath); @@ -149,5 +182,14 @@ namespace YooAsset return EVerifyResult.Exception; } } + private static PackageCache GetOrCreateCache(string packageName) + { + if (_cachedDic.TryGetValue(packageName, out PackageCache cache) == false) + { + cache = new PackageCache(packageName); + _cachedDic.Add(packageName, cache); + } + return cache; + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs b/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs index a3e7943..ac60421 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs +++ b/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs @@ -7,10 +7,15 @@ namespace YooAsset public enum EVerifyLevel { /// - /// 验证文件大小 + /// 验证文件存在 /// Low, + /// + /// 验证文件大小 + /// + Middle, + /// /// 验证文件大小和CRC /// diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs b/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs index 8179f08..a1dd0a0 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs +++ b/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs @@ -7,14 +7,19 @@ namespace YooAsset internal enum EVerifyResult { /// - /// 文件不存在 + /// 未找到缓存信息 /// - FileNotExisted = -5, + CacheNotFound = -6, /// - /// 文件移动失败(重命名失败) + /// 信息文件不存在 /// - FileMoveFailed = -4, + InfoFileNotExisted = -5, + + /// + /// 数据文件不存在 + /// + DataFileNotExisted = -4, /// /// 文件内容不足(小于正常大小) diff --git a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/UniFramework/UniModule.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations.meta similarity index 77% rename from Assets/YooAsset/Samples~/Space Shooter/ThirdParty/UniFramework/UniModule.meta rename to Assets/YooAsset/Runtime/CacheSystem/Operations.meta index 60a51a3..9b6ba5b 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/UniFramework/UniModule.meta +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4e57ebf0b48a9d94dba1c0ce723da392 +guid: d29a9623b2b346e439b7a7e37fafa781 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs new file mode 100644 index 0000000..c5a7e8d --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs @@ -0,0 +1,71 @@ +using System.Collections; +using System.Collections.Generic; +using System.IO; + +namespace YooAsset +{ + /// + /// 清理本地包裹未使用的缓存文件 + /// + public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase + { + private enum ESteps + { + None, + GetUnusedCacheFiles, + ClearUnusedCacheFiles, + Done, + } + + private readonly ResourcePackage _package; + private List _unusedCacheGUIDs; + private int _unusedFileTotalCount = 0; + private ESteps _steps = ESteps.None; + + internal ClearUnusedCacheFilesOperation(ResourcePackage package) + { + _package = package; + } + internal override void Start() + { + _steps = ESteps.GetUnusedCacheFiles; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.GetUnusedCacheFiles) + { + _unusedCacheGUIDs = CacheSystem.GetUnusedCacheGUIDs(_package); + _unusedFileTotalCount = _unusedCacheGUIDs.Count; + YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}"); + _steps = ESteps.ClearUnusedCacheFiles; + } + + if (_steps == ESteps.ClearUnusedCacheFiles) + { + for (int i = _unusedCacheGUIDs.Count - 1; i >= 0; i--) + { + string cacheGUID = _unusedCacheGUIDs[i]; + CacheSystem.DiscardFile(_package.PackageName, cacheGUID); + _unusedCacheGUIDs.RemoveAt(i); + + if (OperationSystem.IsBusy) + break; + } + + if (_unusedFileTotalCount == 0) + Progress = 1.0f; + else + Progress = 1.0f - (_unusedCacheGUIDs.Count / _unusedFileTotalCount); + + if (_unusedCacheGUIDs.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs.meta diff --git a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal.meta similarity index 77% rename from Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets.meta rename to Assets/YooAsset/Runtime/CacheSystem/Operations/Internal.meta index 0571830..81927ef 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets.meta +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 89357359fd1b3f74fa7cb048a1ffa2b6 +guid: a93a516506b2b5c4492fdefe26eb1175 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/FindCacheFilesOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/FindCacheFilesOperation.cs new file mode 100644 index 0000000..b442ed1 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/FindCacheFilesOperation.cs @@ -0,0 +1,175 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class FindCacheFilesOperation : AsyncOperationBase + { + private enum ESteps + { + None, + FindPrepare, + FindBundleFiles, + FindRawFiles, + Done, + } + + private readonly string _packageName; + private float _verifyStartTime; + private IEnumerator _bundleFilesEnumerator = null; + private IEnumerator _rawFilesEnumerator = null; + private ESteps _steps = ESteps.None; + + /// + /// 需要验证的元素 + /// + public readonly List VerifyElements = new List(5000); + + public FindCacheFilesOperation(string packageName) + { + _packageName = packageName; + } + internal override void Start() + { + _steps = ESteps.FindPrepare; + _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.FindPrepare) + { + // BundleFiles + { + string rootPath = PersistentHelper.GetCachedBundleFileFolderPath(_packageName); + DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); + if (rootDirectory.Exists) + { + var directorieInfos = rootDirectory.EnumerateDirectories(); + _bundleFilesEnumerator = directorieInfos.GetEnumerator(); + } + } + + // RawFiles + { + string rootPath = PersistentHelper.GetCachedRawFileFolderPath(_packageName); + DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); + if (rootDirectory.Exists) + { + var directorieInfos = rootDirectory.EnumerateDirectories(); + _rawFilesEnumerator = directorieInfos.GetEnumerator(); + } + } + + _steps = ESteps.FindBundleFiles; + } + + if (_steps == ESteps.FindBundleFiles) + { + if (UpdateFindBundleFiles()) + return; + + _steps = ESteps.FindRawFiles; + } + + if (_steps == ESteps.FindRawFiles) + { + if (UpdateFindRawFiles()) + return; + + // 注意:总是返回成功 + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; + YooLogger.Log($"Find cache files elapsed time {costTime:f1} seconds"); + } + } + + private bool UpdateFindBundleFiles() + { + if (_bundleFilesEnumerator == null) + return false; + + bool isFindItem; + while (true) + { + isFindItem = _bundleFilesEnumerator.MoveNext(); + if (isFindItem == false) + break; + + var rootFoder = _bundleFilesEnumerator.Current; + var childDirectories = rootFoder.GetDirectories(); + foreach(var chidDirectory in childDirectories) + { + string cacheGUID = chidDirectory.Name; + if (CacheSystem.IsCached(_packageName, cacheGUID)) + continue; + + // 创建验证元素类 + string fileRootPath = chidDirectory.FullName; + string dataFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleDataFileName}"; + string infoFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleInfoFileName}"; + VerifyCacheElement element = new VerifyCacheElement(_packageName, cacheGUID, fileRootPath, dataFilePath, infoFilePath); + VerifyElements.Add(element); + } + + if (OperationSystem.IsBusy) + break; + } + + return isFindItem; + } + private bool UpdateFindRawFiles() + { + if (_rawFilesEnumerator == null) + return false; + + bool isFindItem; + while (true) + { + isFindItem = _rawFilesEnumerator.MoveNext(); + if (isFindItem == false) + break; + + var rootFoder = _rawFilesEnumerator.Current; + var childDirectories = rootFoder.GetDirectories(); + foreach (var chidDirectory in childDirectories) + { + string cacheGUID = chidDirectory.Name; + if (CacheSystem.IsCached(_packageName, cacheGUID)) + continue; + + // 获取数据文件的后缀名 + string dataFileExtension = string.Empty; + var fileInfos = chidDirectory.GetFiles(); + foreach (var fileInfo in fileInfos) + { + if (fileInfo.Extension == ".temp") + continue; + if (fileInfo.Name.StartsWith(YooAssetSettings.CacheBundleDataFileName)) + { + dataFileExtension = fileInfo.Extension; + break; + } + } + + // 创建验证元素类 + string fileRootPath = chidDirectory.FullName; + string dataFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleDataFileName}{dataFileExtension}"; + string infoFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleInfoFileName}"; + VerifyCacheElement element = new VerifyCacheElement(_packageName, cacheGUID, fileRootPath, dataFilePath, infoFilePath); + VerifyElements.Add(element); + } + + if (OperationSystem.IsBusy) + break; + } + + return isFindItem; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/FindCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/FindCacheFilesOperation.cs.meta new file mode 100644 index 0000000..66a2d13 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/FindCacheFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00ec004354d75ac499606d6959192f9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyCacheFilesOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyCacheFilesOperation.cs new file mode 100644 index 0000000..0ab4d61 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyCacheFilesOperation.cs @@ -0,0 +1,250 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Threading; + +namespace YooAsset +{ + internal abstract class VerifyCacheFilesOperation : AsyncOperationBase + { + public static VerifyCacheFilesOperation CreateOperation(List elements) + { +#if UNITY_WEBGL + var operation = new VerifyCacheFilesWithoutThreadOperation(elements); +#else + var operation = new VerifyCacheFilesWithThreadOperation(elements); +#endif + return operation; + } + } + + /// + /// 本地缓存文件验证(线程版) + /// + internal class VerifyCacheFilesWithThreadOperation : VerifyCacheFilesOperation + { + private enum ESteps + { + None, + InitVerify, + UpdateVerify, + Done, + } + + private readonly ThreadSyncContext _syncContext = new ThreadSyncContext(); + private List _waitingList; + private List _verifyingList; + private int _verifyMaxNum; + private int _verifyTotalCount; + private float _verifyStartTime; + private int _succeedCount; + private int _failedCount; + private ESteps _steps = ESteps.None; + + public VerifyCacheFilesWithThreadOperation(List elements) + { + _waitingList = elements; + } + internal override void Start() + { + _steps = ESteps.InitVerify; + _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.InitVerify) + { + int fileCount = _waitingList.Count; + + // 设置同时验证的最大数 + ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads); + YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}"); + _verifyMaxNum = Math.Min(workerThreads, ioThreads); + _verifyTotalCount = fileCount; + if (_verifyMaxNum < 1) + _verifyMaxNum = 1; + + _verifyingList = new List(_verifyMaxNum); + _steps = ESteps.UpdateVerify; + } + + if (_steps == ESteps.UpdateVerify) + { + _syncContext.Update(); + + Progress = GetProgress(); + if (_waitingList.Count == 0 && _verifyingList.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; + YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds"); + } + + for (int i = _waitingList.Count - 1; i >= 0; i--) + { + if (OperationSystem.IsBusy) + break; + + if (_verifyingList.Count >= _verifyMaxNum) + break; + + var element = _waitingList[i]; + if (BeginVerifyFileWithThread(element)) + { + _waitingList.RemoveAt(i); + _verifyingList.Add(element); + } + else + { + YooLogger.Warning("The thread pool is failed queued."); + break; + } + } + } + } + + private float GetProgress() + { + if (_verifyTotalCount == 0) + return 1f; + return (float)(_succeedCount + _failedCount) / _verifyTotalCount; + } + private bool BeginVerifyFileWithThread(VerifyCacheElement element) + { + return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element); + } + private void VerifyInThread(object obj) + { + VerifyCacheElement element = (VerifyCacheElement)obj; + element.Result = CacheSystem.VerifyingCacheFile(element); + _syncContext.Post(VerifyCallback, element); + } + private void VerifyCallback(object obj) + { + VerifyCacheElement element = (VerifyCacheElement)obj; + _verifyingList.Remove(element); + + if (element.Result == EVerifyResult.Succeed) + { + _succeedCount++; + var wrapper = new PackageCache.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); + CacheSystem.RecordFile(element.PackageName, element.CacheGUID, wrapper); + } + else + { + _failedCount++; + + YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}"); + element.DeleteFiles(); + } + } + } + + /// + /// 本地缓存文件验证(非线程版) + /// + internal class VerifyCacheFilesWithoutThreadOperation : VerifyCacheFilesOperation + { + private enum ESteps + { + None, + InitVerify, + UpdateVerify, + Done, + } + + private List _waitingList; + private List _verifyingList; + private int _verifyMaxNum; + private int _verifyTotalCount; + private float _verifyStartTime; + private int _succeedCount; + private int _failedCount; + private ESteps _steps = ESteps.None; + + public VerifyCacheFilesWithoutThreadOperation(List elements) + { + _waitingList = elements; + } + internal override void Start() + { + _steps = ESteps.InitVerify; + _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.InitVerify) + { + int fileCount = _waitingList.Count; + + // 设置同时验证的最大数 + _verifyMaxNum = fileCount; + _verifyTotalCount = fileCount; + + _verifyingList = new List(_verifyMaxNum); + _steps = ESteps.UpdateVerify; + } + + if (_steps == ESteps.UpdateVerify) + { + Progress = GetProgress(); + if (_waitingList.Count == 0 && _verifyingList.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; + YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds"); + } + + for (int i = _waitingList.Count - 1; i >= 0; i--) + { + if (OperationSystem.IsBusy) + break; + + if (_verifyingList.Count >= _verifyMaxNum) + break; + + var element = _waitingList[i]; + BeginVerifyFileWithoutThread(element); + _waitingList.RemoveAt(i); + _verifyingList.Add(element); + } + + // 主线程内验证,可以清空列表 + _verifyingList.Clear(); + } + } + + private float GetProgress() + { + if (_verifyTotalCount == 0) + return 1f; + return (float)(_succeedCount + _failedCount) / _verifyTotalCount; + } + private void BeginVerifyFileWithoutThread(VerifyCacheElement element) + { + element.Result = CacheSystem.VerifyingCacheFile(element); + if (element.Result == EVerifyResult.Succeed) + { + _succeedCount++; + var wrapper = new PackageCache.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); + CacheSystem.RecordFile(element.PackageName, element.CacheGUID, wrapper); + } + else + { + _failedCount++; + + YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}"); + element.DeleteFiles(); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyCacheFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs.meta rename to Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyCacheFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyTempFileOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyTempFileOperation.cs new file mode 100644 index 0000000..55cfdab --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyTempFileOperation.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Threading; + +namespace YooAsset +{ + internal abstract class VerifyTempFileOperation : AsyncOperationBase + { + public EVerifyResult VerifyResult { protected set; get; } + + public static VerifyTempFileOperation CreateOperation(VerifyTempElement element) + { +#if UNITY_WEBGL + var operation = new VerifyTempFileWithoutThreadOperation(element); +#else + var operation = new VerifyTempFileWithThreadOperation(element); +#endif + return operation; + } + } + + /// + /// 下载文件验证(线程版) + /// + internal class VerifyTempFileWithThreadOperation : VerifyTempFileOperation + { + private enum ESteps + { + None, + VerifyFile, + Waiting, + Done, + } + + private readonly VerifyTempElement _element; + private ESteps _steps = ESteps.None; + + public VerifyTempFileWithThreadOperation(VerifyTempElement element) + { + _element = element; + } + internal override void Start() + { + _steps = ESteps.VerifyFile; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.VerifyFile) + { + if (BeginVerifyFileWithThread(_element)) + { + _steps = ESteps.Waiting; + } + } + + if (_steps == ESteps.Waiting) + { + if (_element.IsDone == false) + return; + + VerifyResult = _element.Result; + if (_element.Result == EVerifyResult.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {_element.Result}"; + } + } + } + + private bool BeginVerifyFileWithThread(VerifyTempElement element) + { + return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element); + } + private void VerifyInThread(object obj) + { + VerifyTempElement element = (VerifyTempElement)obj; + element.Result = CacheSystem.VerifyingTempFile(element); + element.IsDone = true; + } + } + + /// + /// 下载文件验证(非线程版) + /// + internal class VerifyTempFileWithoutThreadOperation : VerifyTempFileOperation + { + private enum ESteps + { + None, + VerifyFile, + Done, + } + + private readonly VerifyTempElement _element; + private ESteps _steps = ESteps.None; + + public VerifyTempFileWithoutThreadOperation(VerifyTempElement element) + { + _element = element; + } + internal override void Start() + { + _steps = ESteps.VerifyFile; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.VerifyFile) + { + _element.Result = CacheSystem.VerifyingTempFile(_element); + _element.IsDone = true; + + VerifyResult = _element.Result; + if (_element.Result == EVerifyResult.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {_element.Result}"; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyTempFileOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyTempFileOperation.cs.meta new file mode 100644 index 0000000..9abd50f --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/Internal/VerifyTempFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd356e68c5b4ef04ab018a6388f5173a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs new file mode 100644 index 0000000..c8c9777 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class PackageCachingOperation : AsyncOperationBase + { + private enum ESteps + { + None, + FindCacheFiles, + VerifyCacheFiles, + Done, + } + + private readonly string _packageName; + private FindCacheFilesOperation _findCacheFilesOp; + private VerifyCacheFilesOperation _verifyCacheFilesOp; + private ESteps _steps = ESteps.None; + + public PackageCachingOperation(string packageName) + { + _packageName = packageName; + } + internal override void Start() + { + _steps = ESteps.FindCacheFiles; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.FindCacheFiles) + { + if (_findCacheFilesOp == null) + { + _findCacheFilesOp = new FindCacheFilesOperation(_packageName); + OperationSystem.StartOperation(_findCacheFilesOp); + } + + Progress = _findCacheFilesOp.Progress; + if (_findCacheFilesOp.IsDone == false) + return; + + _steps = ESteps.VerifyCacheFiles; + } + + if (_steps == ESteps.VerifyCacheFiles) + { + if (_verifyCacheFilesOp == null) + { + _verifyCacheFilesOp = VerifyCacheFilesOperation.CreateOperation(_findCacheFilesOp.VerifyElements); + OperationSystem.StartOperation(_verifyCacheFilesOp); + } + + Progress = _verifyCacheFilesOp.Progress; + if (_verifyCacheFilesOp.IsDone == false) + return; + + // 注意:总是返回成功 + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + + int totalCount = CacheSystem.GetCachedFilesCount(_packageName); + YooLogger.Log($"Package '{_packageName}' cached files count : {totalCount}"); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs.meta new file mode 100644 index 0000000..e7c542e --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ff95e7516dbfa148b4fe16eaab783fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs b/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs new file mode 100644 index 0000000..1ddaab7 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs @@ -0,0 +1,111 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class PackageCache + { + internal class RecordWrapper + { + public string InfoFilePath { private set; get; } + public string DataFilePath { private set; get; } + public string DataFileCRC { private set; get; } + public long DataFileSize { private set; get; } + + public RecordWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize) + { + InfoFilePath = infoFilePath; + DataFilePath = dataFilePath; + DataFileCRC = dataFileCRC; + DataFileSize = dataFileSize; + } + } + + private readonly Dictionary _wrappers = new Dictionary(); + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + + public PackageCache(string packageName) + { + PackageName = packageName; + } + + /// + /// 清空所有数据 + /// + public void ClearAll() + { + _wrappers.Clear(); + } + + /// + /// 获取缓存文件总数 + /// + public int GetCachedFilesCount() + { + return _wrappers.Count; + } + + /// + /// 查询缓存记录 + /// + public bool IsCached(string cacheGUID) + { + return _wrappers.ContainsKey(cacheGUID); + } + + /// + /// 记录验证结果 + /// + public void Record(string cacheGUID, RecordWrapper wrapper) + { + if (_wrappers.ContainsKey(cacheGUID) == false) + { + _wrappers.Add(cacheGUID, wrapper); + } + else + { + throw new Exception("Should never get here !"); + } + } + + /// + /// 丢弃验证结果 + /// + public void Discard(string cacheGUID) + { + if (_wrappers.ContainsKey(cacheGUID)) + { + _wrappers.Remove(cacheGUID); + } + } + + /// + /// 获取记录对象 + /// + public RecordWrapper TryGetWrapper(string cacheGUID) + { + if (_wrappers.TryGetValue(cacheGUID, out RecordWrapper value)) + return value; + else + return null; + } + + internal List GetAllKeys() + { + List keys = new List(_wrappers.Keys.Count); + var keyCollection = _wrappers.Keys; + foreach (var key in keyCollection) + { + keys.Add(key); + } + return keys; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta new file mode 100644 index 0000000..54c9bad --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08f3e92fdbd5d56459d8882be1f54f60 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs new file mode 100644 index 0000000..9e3841b --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs @@ -0,0 +1,62 @@ +using System.IO; + +namespace YooAsset +{ + /// + /// 缓存文件验证元素 + /// + internal class VerifyCacheElement + { + public string PackageName { private set; get; } + public string CacheGUID { private set; get; } + public string FileRootPath { private set; get; } + public string DataFilePath { private set; get; } + public string InfoFilePath { private set; get; } + + public EVerifyResult Result; + public string DataFileCRC; + public long DataFileSize; + + public VerifyCacheElement(string packageName, string cacheGUID, string fileRootPath, string dataFilePath, string infoFilePath) + { + PackageName = packageName; + CacheGUID = cacheGUID; + FileRootPath = fileRootPath; + DataFilePath = dataFilePath; + InfoFilePath = infoFilePath; + } + + public void DeleteFiles() + { + if (File.Exists(DataFilePath)) + { + File.Delete(DataFilePath); + } + + if (File.Exists(InfoFilePath)) + { + File.Delete(InfoFilePath); + } + } + } + + /// + /// 下载文件验证元素 + /// + internal class VerifyTempElement + { + public string TempDataFilePath { private set; get; } + public string FileCRC { private set; get; } + public long FileSize { private set; get; } + + public bool IsDone = false; + public EVerifyResult Result; + + public VerifyTempElement(string tempDataFilePath, string fileCRC, long fileSize) + { + TempDataFilePath = tempDataFilePath; + FileCRC = fileCRC; + FileSize = fileSize; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta new file mode 100644 index 0000000..8cb15ad --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a4b96484bd701f4289b2f74c38abaa8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs b/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs deleted file mode 100644 index c958fbb..0000000 --- a/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ - -namespace YooAsset -{ - internal class VerifyInfo - { - /// - /// 验证的资源文件是否为内置资源 - /// - public bool IsBuildinFile { private set; get; } - - /// - /// 验证的资源包实例 - /// - public PatchBundle VerifyBundle { private set; get; } - - /// - /// 验证的文件路径 - /// - public string VerifyFilePath { private set; get; } - - /// - /// 验证结果 - /// - public EVerifyResult Result; - - public VerifyInfo(bool isBuildinFile, PatchBundle verifyBundle) - { - IsBuildinFile = isBuildinFile; - VerifyBundle = verifyBundle; - VerifyFilePath = verifyBundle.CachedFilePath; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs index 9459c41..de18ee6 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs @@ -2,10 +2,16 @@ using System.IO; using System.Collections; using System.Collections.Generic; +using System.Threading; using UnityEngine.Networking; namespace YooAsset { + /// + /// 自定义下载器的请求委托 + /// + public delegate UnityWebRequest DownloadRequestDelegate(string url); + /// /// 1. 保证每一时刻资源文件只存在一个下载器 /// 2. 保证下载器下载完成后立刻验证并缓存 @@ -16,11 +22,15 @@ namespace YooAsset private static readonly Dictionary _downloaderDic = new Dictionary(); private static readonly List _removeList = new List(100); + /// + /// 自定义下载器的请求委托 + /// + public static DownloadRequestDelegate RequestDelegate = null; /// /// 自定义的证书认证实例 /// - public static CertificateHandler CertificateHandlerInstance; + public static CertificateHandler CertificateHandlerInstance = null; /// /// 启用断点续传功能文件的最小字节数 @@ -32,8 +42,16 @@ namespace YooAsset /// public static List ClearFileResponseCodes { set; get; } + /// - /// 更新所有下载器 + /// 初始化下载器 + /// + public static void Initialize() + { + } + + /// + /// 更新下载器 /// public static void Update() { @@ -66,7 +84,11 @@ namespace YooAsset } _downloaderDic.Clear(); _removeList.Clear(); + + RequestDelegate = null; + CertificateHandlerInstance = null; BreakpointResumeFileSize = int.MaxValue; + ClearFileResponseCodes = null; } @@ -77,13 +99,13 @@ namespace YooAsset public static DownloaderBase BeginDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60) { // 查询存在的下载器 - if (_downloaderDic.TryGetValue(bundleInfo.Bundle.CachedFilePath, out var downloader)) + if (_downloaderDic.TryGetValue(bundleInfo.Bundle.CachedDataFilePath, out var downloader)) { return downloader; } // 如果资源已经缓存 - if (CacheSystem.IsCached(bundleInfo.Bundle)) + if (CacheSystem.IsCached(bundleInfo.Bundle.PackageName, bundleInfo.Bundle.CacheGUID)) { var tempDownloader = new TempDownloader(bundleInfo); return tempDownloader; @@ -92,15 +114,27 @@ namespace YooAsset // 创建新的下载器 { YooLogger.Log($"Beginning to download file : {bundleInfo.Bundle.FileName} URL : {bundleInfo.RemoteMainURL}"); - FileUtility.CreateFileDirectory(bundleInfo.Bundle.CachedFilePath); + FileUtility.CreateFileDirectory(bundleInfo.Bundle.CachedDataFilePath); bool breakDownload = bundleInfo.Bundle.FileSize >= BreakpointResumeFileSize; DownloaderBase newDownloader = new FileDownloader(bundleInfo, breakDownload); newDownloader.SendRequest(failedTryAgain, timeout); - _downloaderDic.Add(bundleInfo.Bundle.CachedFilePath, newDownloader); + _downloaderDic.Add(bundleInfo.Bundle.CachedDataFilePath, newDownloader); return newDownloader; } } + /// + /// 创建一个新的网络请求 + /// + public static UnityWebRequest NewRequest(string requestURL) + { + if (RequestDelegate != null) + return RequestDelegate.Invoke(requestURL); + + var request = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET); + return request; + } + /// /// 获取下载器的总数 /// diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs index 188d408..7866417 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs @@ -6,13 +6,15 @@ namespace YooAsset protected enum ESteps { None, - CheckLocalFile, CheckTempFile, + WaitingCheckTempFile, PrepareDownload, CreateResumeDownloader, CreateGeneralDownloader, CheckDownload, - VerifyDownload, + VerifyTempFile, + WaitingVerifyTempFile, + CachingFile, TryAgain, Succeed, Failed, @@ -32,6 +34,11 @@ namespace YooAsset protected float _downloadProgress = 0f; protected ulong _downloadedBytes = 0; + /// + /// 是否等待异步结束 + /// 警告:只能用于解压APP内部资源 + /// + public bool WaitForAsyncComplete = false; /// /// 下载进度(0f~1f) @@ -60,7 +67,7 @@ namespace YooAsset { _failedTryAgain = failedTryAgain; _timeout = timeout; - _steps = ESteps.CheckLocalFile; + _steps = ESteps.CheckTempFile; } } public abstract void Update(); diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs index 20b282e..6071af7 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs @@ -13,6 +13,8 @@ namespace YooAsset private readonly string _tempFilePath; private UnityWebRequest _webRequest = null; private DownloadHandlerFileRange _downloadHandle = null; + private VerifyTempFileOperation _checkFileOp = null; + private VerifyTempFileOperation _verifyFileOp = null; // 重置变量 private bool _isAbort = false; @@ -25,7 +27,7 @@ namespace YooAsset public FileDownloader(BundleInfo bundleInfo, bool breakResume) : base(bundleInfo) { _breakResume = breakResume; - _tempFilePath = bundleInfo.Bundle.CachedFilePath + ".temp"; + _tempFilePath = bundleInfo.Bundle.TempDataFilePath; } public override void Update() { @@ -34,33 +36,31 @@ namespace YooAsset if (IsDone()) return; - // 检测本地正式文件 - if (_steps == ESteps.CheckLocalFile) - { - var verifyResult = CacheSystem.VerifyAndCacheLocalBundleFile(_bundleInfo.Bundle, CacheSystem.InitVerifyLevel); - if (verifyResult == EVerifyResult.Succeed) - { - _steps = ESteps.Succeed; - } - else - { - if (File.Exists(_bundleInfo.Bundle.CachedFilePath)) - File.Delete(_bundleInfo.Bundle.CachedFilePath); - _steps = ESteps.CheckTempFile; - } - } - - // 检测本地临时文件 + // 检测临时文件 if (_steps == ESteps.CheckTempFile) { - var verifyResult = CacheSystem.VerifyAndCacheDownloadBundleFile(_tempFilePath, _bundleInfo.Bundle, EVerifyLevel.High); - if (verifyResult == EVerifyResult.Succeed) + VerifyTempElement element = new VerifyTempElement(_bundleInfo.Bundle.TempDataFilePath, _bundleInfo.Bundle.FileCRC, _bundleInfo.Bundle.FileSize); + _checkFileOp = VerifyTempFileOperation.CreateOperation(element); + OperationSystem.StartOperation(_checkFileOp); + _steps = ESteps.WaitingCheckTempFile; + } + + // 等待检测结果 + if (_steps == ESteps.WaitingCheckTempFile) + { + if (WaitForAsyncComplete) + _checkFileOp.Update(); + + if (_checkFileOp.IsDone == false) + return; + + if (_checkFileOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.Succeed; + _steps = ESteps.CachingFile; } else { - if (verifyResult == EVerifyResult.FileOverflow) + if (_checkFileOp.VerifyResult == EVerifyResult.FileOverflow) { if (File.Exists(_tempFilePath)) File.Delete(_tempFilePath); @@ -94,11 +94,9 @@ namespace YooAsset if (_steps == ESteps.CreateGeneralDownloader) { if (File.Exists(_tempFilePath)) - { File.Delete(_tempFilePath); - } - _webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET); + _webRequest = DownloadSystem.NewRequest(_requestURL); DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath); handler.removeFileOnAbort = true; _webRequest.downloadHandler = handler; @@ -127,11 +125,11 @@ namespace YooAsset } #if UNITY_2019_4_OR_NEWER - _webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET); + _webRequest = DownloadSystem.NewRequest(_requestURL); var handler = new DownloadHandlerFile(_tempFilePath, true); handler.removeFileOnAbort = false; #else - _webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET); + _webRequest = DownloadSystem.NewRequest(_requestURL); var handler = new DownloadHandlerFileRange(_tempFilePath, _bundleInfo.Bundle.FileSize, _webRequest); _downloadHandle = handler; #endif @@ -206,7 +204,7 @@ namespace YooAsset } else { - _steps = ESteps.VerifyDownload; + _steps = ESteps.VerifyTempFile; } // 释放下载器 @@ -214,23 +212,69 @@ namespace YooAsset } // 验证下载文件 - if (_steps == ESteps.VerifyDownload) + if (_steps == ESteps.VerifyTempFile) { - var verifyResult = CacheSystem.VerifyAndCacheDownloadBundleFile(_tempFilePath, _bundleInfo.Bundle, EVerifyLevel.High); - if (verifyResult == EVerifyResult.Succeed) + VerifyTempElement element = new VerifyTempElement(_bundleInfo.Bundle.TempDataFilePath, _bundleInfo.Bundle.FileCRC, _bundleInfo.Bundle.FileSize); + _verifyFileOp = VerifyTempFileOperation.CreateOperation(element); + OperationSystem.StartOperation(_verifyFileOp); + _steps = ESteps.WaitingVerifyTempFile; + } + + // 等待验证完成 + if (_steps == ESteps.WaitingVerifyTempFile) + { + if (WaitForAsyncComplete) + _verifyFileOp.Update(); + + if (_verifyFileOp.IsDone == false) + return; + + if (_verifyFileOp.Status == EOperationStatus.Succeed) { + _steps = ESteps.CachingFile; + } + else + { + if (File.Exists(_tempFilePath)) + File.Delete(_tempFilePath); + + _lastError = _verifyFileOp.Error; + _steps = ESteps.TryAgain; + } + } + + // 缓存下载文件 + if (_steps == ESteps.CachingFile) + { + try + { + string infoFilePath = _bundleInfo.Bundle.CachedInfoFilePath; + string dataFilePath = _bundleInfo.Bundle.CachedDataFilePath; + string dataFileCRC = _bundleInfo.Bundle.FileCRC; + long dataFileSize = _bundleInfo.Bundle.FileSize; + + if (File.Exists(infoFilePath)) + File.Delete(infoFilePath); + if (File.Exists(dataFilePath)) + File.Delete(dataFilePath); + + FileInfo fileInfo = new FileInfo(_tempFilePath); + fileInfo.MoveTo(dataFilePath); + + // 写入信息文件记录验证数据 + CacheFileInfo.WriteInfoToFile(infoFilePath, dataFileCRC, dataFileSize); + + // 记录缓存文件 + var wrapper = new PackageCache.RecordWrapper(infoFilePath, dataFilePath, dataFileCRC, dataFileSize); + CacheSystem.RecordFile(_bundleInfo.Bundle.PackageName, _bundleInfo.Bundle.CacheGUID, wrapper); + _lastError = string.Empty; _lastCode = 0; _steps = ESteps.Succeed; } - else + catch (Exception e) { - _lastError = $"Verify bundle content failed : {_bundleInfo.Bundle.FileName}"; - - // 验证失败后删除文件 - if (File.Exists(_tempFilePath)) - File.Delete(_tempFilePath); - + _lastError = e.Message; _steps = ESteps.TryAgain; } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs index cdd3918..6c0a213 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs @@ -29,7 +29,7 @@ namespace YooAsset if (_webRequest == null) { URL = url; - _webRequest = new UnityWebRequest(URL, UnityWebRequest.kHttpVerbGET); + _webRequest = DownloadSystem.NewRequest(URL); DownloadHandlerBuffer handler = new DownloadHandlerBuffer(); _webRequest.downloadHandler = handler; _webRequest.disposeDownloadHandlerOnDispose = true; diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs index c85ed1a..f5c08bc 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs @@ -39,7 +39,7 @@ namespace YooAsset _latestDownloadBytes = 0; _latestDownloadRealtime = Time.realtimeSinceStartup; - _webRequest = new UnityWebRequest(URL, UnityWebRequest.kHttpVerbGET); + _webRequest = DownloadSystem.NewRequest(URL); DownloadHandlerFile handler = new DownloadHandlerFile(savePath); handler.removeFileOnAbort = true; _webRequest.downloadHandler = handler; diff --git a/Assets/YooAsset/Runtime/InitializeParameters.cs b/Assets/YooAsset/Runtime/InitializeParameters.cs index 8417830..a6e157e 100644 --- a/Assets/YooAsset/Runtime/InitializeParameters.cs +++ b/Assets/YooAsset/Runtime/InitializeParameters.cs @@ -39,10 +39,16 @@ namespace YooAsset public IDecryptionServices DecryptionServices = null; /// - /// 资源加载的最大数量 + /// 资源加载每帧处理的最大时间片段 /// 注意:默认值为MaxValue /// - public int AssetLoadingMaxNumber = int.MaxValue; + public long LoadingMaxTimeSlice = long.MaxValue; + + /// + /// 下载失败尝试次数 + /// 注意:默认值为MaxValue + /// + public int DownloadFailedTryAgain = int.MaxValue; } /// @@ -53,7 +59,7 @@ namespace YooAsset /// /// 用于模拟运行的资源清单路径 /// - public string SimulatePatchManifestPath = string.Empty; + public string SimulateManifestFilePath = string.Empty; } /// diff --git a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs index 85ce6fe..e0d4fe2 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs @@ -7,6 +7,8 @@ namespace YooAsset internal class OperationSystem { private static readonly List _operations = new List(100); + private static readonly List _addList = new List(100); + private static readonly List _removeList = new List(100); // 计时器相关 private static Stopwatch _watch; @@ -44,19 +46,40 @@ namespace YooAsset { _frameTime = _watch.ElapsedMilliseconds; - for (int i = _operations.Count - 1; i >= 0; i--) + // 添加新的异步操作 + if (_addList.Count > 0) + { + for (int i = 0; i < _addList.Count; i++) + { + var operation = _addList[i]; + _operations.Add(operation); + } + _addList.Clear(); + } + + // 更新所有的异步操作 + foreach (var operation in _operations) { if (IsBusy) - return; + break; - var operation = _operations[i]; operation.Update(); if (operation.IsDone) { - _operations.RemoveAt(i); + _removeList.Add(operation); operation.Finish(); } } + + // 移除已经完成的异步操作 + if (_removeList.Count > 0) + { + foreach (var operation in _removeList) + { + _operations.Remove(operation); + } + _removeList.Clear(); + } } /// @@ -65,6 +88,8 @@ namespace YooAsset public static void DestroyAll() { _operations.Clear(); + _addList.Clear(); + _removeList.Clear(); _watch = null; _frameTime = 0; MaxTimeSlice = long.MaxValue; @@ -73,10 +98,10 @@ namespace YooAsset /// /// 开始处理异步操作类 /// - public static void StartOperation(AsyncOperationBase operationBase) + public static void StartOperation(AsyncOperationBase operation) { - _operations.Add(operationBase); - operationBase.Start(); + _addList.Add(operation); + operation.Start(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem.meta b/Assets/YooAsset/Runtime/PackageSystem.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem.meta rename to Assets/YooAsset/Runtime/PackageSystem.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/AssetInfo.cs b/Assets/YooAsset/Runtime/PackageSystem/AssetInfo.cs similarity index 58% rename from Assets/YooAsset/Runtime/PatchSystem/AssetInfo.cs rename to Assets/YooAsset/Runtime/PackageSystem/AssetInfo.cs index 6b534b7..9a5411d 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/AssetInfo.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/AssetInfo.cs @@ -3,9 +3,20 @@ namespace YooAsset { public class AssetInfo { - private readonly PatchAsset _patchAsset; + private readonly PackageAsset _packageAsset; private string _providerGUID; + /// + /// 资源类型 + /// + public System.Type AssetType { private set; get; } + + /// + /// 错误信息 + /// + public string Error { private set; get; } + + /// /// 唯一标识符 /// @@ -31,63 +42,66 @@ namespace YooAsset { get { - return _patchAsset == null; + return _packageAsset == null; } } - /// - /// 错误信息 - /// - internal string Error { private set; get; } - /// /// 可寻址地址 /// - public string Address { private set; get; } + public string Address + { + get + { + if (_packageAsset == null) + return string.Empty; + return _packageAsset.Address; + } + } /// /// 资源路径 /// - public string AssetPath { private set; get; } - - /// - /// 资源类型 - /// - public System.Type AssetType { private set; get; } + public string AssetPath + { + get + { + if (_packageAsset == null) + return string.Empty; + return _packageAsset.AssetPath; + } + } - // 注意:这是一个内部类,严格限制外部创建。 private AssetInfo() { + // 注意:禁止从外部创建该类 } - internal AssetInfo(PatchAsset patchAsset, System.Type assetType) + internal AssetInfo(PackageAsset packageAsset, System.Type assetType) { - if (patchAsset == null) + if (packageAsset == null) throw new System.Exception("Should never get here !"); - _patchAsset = patchAsset; + _providerGUID = string.Empty; + _packageAsset = packageAsset; AssetType = assetType; - Address = patchAsset.Address; - AssetPath = patchAsset.AssetPath; Error = string.Empty; } - internal AssetInfo(PatchAsset patchAsset) + internal AssetInfo(PackageAsset packageAsset) { - if (patchAsset == null) + if (packageAsset == null) throw new System.Exception("Should never get here !"); - _patchAsset = patchAsset; + _providerGUID = string.Empty; + _packageAsset = packageAsset; AssetType = null; - Address = patchAsset.Address; - AssetPath = patchAsset.AssetPath; Error = string.Empty; } internal AssetInfo(string error) { - _patchAsset = null; + _providerGUID = string.Empty; + _packageAsset = null; AssetType = null; - Address = string.Empty; - AssetPath = string.Empty; Error = error; } } diff --git a/Assets/YooAsset/Runtime/PatchSystem/AssetInfo.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/AssetInfo.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/AssetInfo.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/AssetInfo.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs b/Assets/YooAsset/Runtime/PackageSystem/BundleInfo.cs similarity index 76% rename from Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs rename to Assets/YooAsset/Runtime/PackageSystem/BundleInfo.cs index 18a5c57..18e9007 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/BundleInfo.cs @@ -12,7 +12,7 @@ namespace YooAsset LoadFromEditor, } - public readonly PatchBundle Bundle; + public readonly PackageBundle Bundle; public readonly ELoadMode LoadMode; /// @@ -34,25 +34,25 @@ namespace YooAsset private BundleInfo() { } - public BundleInfo(PatchBundle patchBundle, ELoadMode loadMode, string mainURL, string fallbackURL) + public BundleInfo(PackageBundle bundle, ELoadMode loadMode, string mainURL, string fallbackURL) { - Bundle = patchBundle; + Bundle = bundle; LoadMode = loadMode; RemoteMainURL = mainURL; RemoteFallbackURL = fallbackURL; EditorAssetPath = string.Empty; } - public BundleInfo(PatchBundle patchBundle, ELoadMode loadMode, string editorAssetPath) + public BundleInfo(PackageBundle bundle, ELoadMode loadMode, string editorAssetPath) { - Bundle = patchBundle; + Bundle = bundle; LoadMode = loadMode; RemoteMainURL = string.Empty; RemoteFallbackURL = string.Empty; EditorAssetPath = editorAssetPath; } - public BundleInfo(PatchBundle patchBundle, ELoadMode loadMode) + public BundleInfo(PackageBundle bundle, ELoadMode loadMode) { - Bundle = patchBundle; + Bundle = bundle; LoadMode = loadMode; RemoteMainURL = string.Empty; RemoteFallbackURL = string.Empty; diff --git a/Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/BundleInfo.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/BundleInfo.cs.meta diff --git a/Assets/YooAsset/Runtime/PackageSystem/ManifestTools.cs b/Assets/YooAsset/Runtime/PackageSystem/ManifestTools.cs new file mode 100644 index 0000000..107bce9 --- /dev/null +++ b/Assets/YooAsset/Runtime/PackageSystem/ManifestTools.cs @@ -0,0 +1,201 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset +{ + internal static class ManifestTools + { + +#if UNITY_EDITOR + /// + /// 序列化(JSON文件) + /// + public static void SerializeToJson(string savePath, PackageManifest manifest) + { + string json = JsonUtility.ToJson(manifest, true); + FileUtility.CreateFile(savePath, json); + } + + /// + /// 序列化(二进制文件) + /// + public static void SerializeToBinary(string savePath, PackageManifest manifest) + { + using (FileStream fs = new FileStream(savePath, FileMode.Create)) + { + // 创建缓存器 + BufferWriter buffer = new BufferWriter(YooAssetSettings.ManifestFileMaxSize); + + // 写入文件标记 + buffer.WriteUInt32(YooAssetSettings.ManifestFileSign); + + // 写入文件版本 + buffer.WriteUTF8(manifest.FileVersion); + + // 写入文件头信息 + buffer.WriteBool(manifest.EnableAddressable); + buffer.WriteInt32(manifest.OutputNameStyle); + buffer.WriteUTF8(manifest.PackageName); + buffer.WriteUTF8(manifest.PackageVersion); + + // 写入资源列表 + buffer.WriteInt32(manifest.AssetList.Count); + for (int i = 0; i < manifest.AssetList.Count; i++) + { + var packageAsset = manifest.AssetList[i]; + buffer.WriteUTF8(packageAsset.Address); + buffer.WriteUTF8(packageAsset.AssetPath); + buffer.WriteUTF8Array(packageAsset.AssetTags); + buffer.WriteInt32(packageAsset.BundleID); + buffer.WriteInt32Array(packageAsset.DependIDs); + } + + // 写入资源包列表 + buffer.WriteInt32(manifest.BundleList.Count); + for (int i = 0; i < manifest.BundleList.Count; i++) + { + var packageBundle = manifest.BundleList[i]; + buffer.WriteUTF8(packageBundle.BundleName); + buffer.WriteUTF8(packageBundle.FileHash); + buffer.WriteUTF8(packageBundle.FileCRC); + buffer.WriteInt64(packageBundle.FileSize); + buffer.WriteBool(packageBundle.IsRawFile); + buffer.WriteByte(packageBundle.LoadMethod); + buffer.WriteUTF8Array(packageBundle.Tags); + buffer.WriteInt32Array(packageBundle.ReferenceIDs); + } + + // 写入文件流 + buffer.WriteToStream(fs); + fs.Flush(); + } + } + + /// + /// 反序列化(JSON文件) + /// + public static PackageManifest DeserializeFromJson(string jsonContent) + { + return JsonUtility.FromJson(jsonContent); + } + + /// + /// 反序列化(二进制文件) + /// + public static PackageManifest DeserializeFromBinary(byte[] binaryData) + { + // 创建缓存器 + BufferReader buffer = new BufferReader(binaryData); + + // 读取文件标记 + uint fileSign = buffer.ReadUInt32(); + if (fileSign != YooAssetSettings.ManifestFileSign) + throw new Exception("Invalid manifest file !"); + + // 读取文件版本 + string fileVersion = buffer.ReadUTF8(); + if (fileVersion != YooAssetSettings.ManifestFileVersion) + throw new Exception($"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}"); + + PackageManifest manifest = new PackageManifest(); + { + // 读取文件头信息 + manifest.FileVersion = fileVersion; + manifest.EnableAddressable = buffer.ReadBool(); + manifest.OutputNameStyle = buffer.ReadInt32(); + manifest.PackageName = buffer.ReadUTF8(); + manifest.PackageVersion = buffer.ReadUTF8(); + + // 读取资源列表 + int packageAssetCount = buffer.ReadInt32(); + manifest.AssetList = new List(packageAssetCount); + for (int i = 0; i < packageAssetCount; i++) + { + var packageAsset = new PackageAsset(); + packageAsset.Address = buffer.ReadUTF8(); + packageAsset.AssetPath = buffer.ReadUTF8(); + packageAsset.AssetTags = buffer.ReadUTF8Array(); + packageAsset.BundleID = buffer.ReadInt32(); + packageAsset.DependIDs = buffer.ReadInt32Array(); + manifest.AssetList.Add(packageAsset); + } + + // 读取资源包列表 + int packageBundleCount = buffer.ReadInt32(); + manifest.BundleList = new List(packageBundleCount); + for (int i = 0; i < packageBundleCount; i++) + { + var packageBundle = new PackageBundle(); + packageBundle.BundleName = buffer.ReadUTF8(); + packageBundle.FileHash = buffer.ReadUTF8(); + packageBundle.FileCRC = buffer.ReadUTF8(); + packageBundle.FileSize = buffer.ReadInt64(); + packageBundle.IsRawFile = buffer.ReadBool(); + packageBundle.LoadMethod = buffer.ReadByte(); + packageBundle.Tags = buffer.ReadUTF8Array(); + packageBundle.ReferenceIDs = buffer.ReadInt32Array(); + manifest.BundleList.Add(packageBundle); + } + } + + // BundleDic + manifest.BundleDic = new Dictionary(manifest.BundleList.Count); + foreach (var packageBundle in manifest.BundleList) + { + packageBundle.ParseBundle(manifest.PackageName, manifest.OutputNameStyle); + manifest.BundleDic.Add(packageBundle.BundleName, packageBundle); + } + + // AssetDic + manifest.AssetDic = new Dictionary(manifest.AssetList.Count); + foreach (var packageAsset in manifest.AssetList) + { + // 注意:我们不允许原始路径存在重名 + string assetPath = packageAsset.AssetPath; + if (manifest.AssetDic.ContainsKey(assetPath)) + throw new Exception($"AssetPath have existed : {assetPath}"); + else + manifest.AssetDic.Add(assetPath, packageAsset); + } + + return manifest; + } +#endif + + public static string GetRemoteBundleFileExtension(string bundleName) + { + string fileExtension = Path.GetExtension(bundleName); + return fileExtension; + } + public static string GetRemoteBundleFileName(int nameStyle, string bundleName, string fileExtension, string fileHash) + { + if (nameStyle == 1) //HashName + { + return StringUtility.Format("{0}{1}", fileHash, fileExtension); + } + else if (nameStyle == 4) //BundleName_HashName + { + string fileName = bundleName.Remove(bundleName.LastIndexOf('.')); + return StringUtility.Format("{0}_{1}{2}", fileName, fileHash, fileExtension); + } + else + { + throw new NotImplementedException($"Invalid name style : {nameStyle}"); + } + } + + /// + /// 获取解压BundleInfo + /// + public static BundleInfo GetUnpackInfo(PackageBundle packageBundle) + { + // 注意:我们把流加载路径指定为远端下载地址 + string streamingPath = PathHelper.ConvertToWWWPath(packageBundle.StreamingFilePath); + BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromStreaming, streamingPath, streamingPath); + return bundleInfo; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/ManifestTools.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/ManifestTools.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/DownloaderOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/DownloaderOperation.cs similarity index 81% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/DownloaderOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/DownloaderOperation.cs index b748549..352c617 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/DownloaderOperation.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/Operations/DownloaderOperation.cs @@ -32,28 +32,36 @@ namespace YooAsset private bool _isPause = false; private long _lastDownloadBytes = 0; private int _lastDownloadCount = 0; + private long _cachedDownloadBytes = 0; + private int _cachedDownloadCount = 0; private ESteps _steps = ESteps.None; - + /// - /// 下载文件总数量 + /// 统计的下载文件总数量 /// public int TotalDownloadCount { private set; get; } - + /// - /// 下载文件的总大小 + /// 统计的下载文件的总大小 /// public long TotalDownloadBytes { private set; get; } - + /// /// 当前已经完成的下载总数量 /// - public int CurrentDownloadCount { private set; get; } + public int CurrentDownloadCount + { + get { return _lastDownloadCount; } + } /// /// 当前已经完成的下载总大小 /// - public long CurrentDownloadBytes { private set; get; } + public long CurrentDownloadBytes + { + get { return _lastDownloadBytes; } + } /// /// 当下载器结束(无论成功或失败) @@ -86,9 +94,9 @@ namespace YooAsset if (downloadList != null) { TotalDownloadCount = downloadList.Count; - foreach (var patchBundle in downloadList) + foreach (var packageBundle in downloadList) { - TotalDownloadBytes += patchBundle.Bundle.FileSize; + TotalDownloadBytes += packageBundle.Bundle.FileSize; } } } @@ -120,7 +128,7 @@ namespace YooAsset { // 检测下载器结果 _removeList.Clear(); - long downloadBytes = CurrentDownloadBytes; + long downloadBytes = _cachedDownloadBytes; foreach (var downloader in _downloaders) { downloadBytes += (long)downloader.DownloadedBytes; @@ -139,8 +147,8 @@ namespace YooAsset // 下载成功 _removeList.Add(downloader); - CurrentDownloadCount++; - CurrentDownloadBytes += bundleInfo.Bundle.FileSize; + _cachedDownloadCount++; + _cachedDownloadBytes += bundleInfo.Bundle.FileSize; } // 移除已经完成的下载器(无论成功或失败) @@ -150,10 +158,10 @@ namespace YooAsset } // 如果下载进度发生变化 - if (_lastDownloadBytes != downloadBytes || _lastDownloadCount != CurrentDownloadCount) + if (_lastDownloadBytes != downloadBytes || _lastDownloadCount != _cachedDownloadCount) { _lastDownloadBytes = downloadBytes; - _lastDownloadCount = CurrentDownloadCount; + _lastDownloadCount = _cachedDownloadCount; Progress = (float)_lastDownloadBytes / TotalDownloadBytes; OnDownloadProgressCallback?.Invoke(TotalDownloadCount, _lastDownloadCount, TotalDownloadBytes, _lastDownloadBytes); } @@ -241,9 +249,9 @@ namespace YooAsset } } - public sealed class PatchDownloaderOperation : DownloaderOperation + public sealed class ResourceDownloaderOperation : DownloaderOperation { - internal PatchDownloaderOperation(List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) + internal ResourceDownloaderOperation(List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) : base(downloadList, downloadingMaxNumber, failedTryAgain, timeout) { } @@ -251,16 +259,16 @@ namespace YooAsset /// /// 创建空的下载器 /// - internal static PatchDownloaderOperation CreateEmptyDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout) + internal static ResourceDownloaderOperation CreateEmptyDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout) { List downloadList = new List(); - var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } } - public sealed class PatchUnpackerOperation : DownloaderOperation + public sealed class ResourceUnpackerOperation : DownloaderOperation { - internal PatchUnpackerOperation(List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) + internal ResourceUnpackerOperation(List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) : base(downloadList, downloadingMaxNumber, failedTryAgain, timeout) { } @@ -268,10 +276,10 @@ namespace YooAsset /// /// 创建空的解压器 /// - internal static PatchUnpackerOperation CreateEmptyUnpacker(int upackingMaxNumber, int failedTryAgain, int timeout) + internal static ResourceUnpackerOperation CreateEmptyUnpacker(int upackingMaxNumber, int failedTryAgain, int timeout) { List downloadList = new List(); - var operation = new PatchUnpackerOperation(downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue); + var operation = new ResourceUnpackerOperation(downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue); return operation; } } diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/DownloaderOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/DownloaderOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/DownloaderOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/DownloaderOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/InitializationOperation.cs similarity index 89% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/InitializationOperation.cs index a2d9fdd..8683be6 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/Operations/InitializationOperation.cs @@ -26,14 +26,14 @@ namespace YooAsset } private readonly EditorSimulateModeImpl _impl; - private readonly string _simulateManifestPath; + private readonly string _simulateManifestFilePath; private LoadEditorManifestOperation _loadEditorManifestOp; private ESteps _steps = ESteps.None; - internal EditorSimulateModeInitializationOperation(EditorSimulateModeImpl impl, string simulateManifestPath) + internal EditorSimulateModeInitializationOperation(EditorSimulateModeImpl impl, string simulateManifestFilePath) { _impl = impl; - _simulateManifestPath = simulateManifestPath; + _simulateManifestFilePath = simulateManifestFilePath; } internal override void Start() { @@ -45,7 +45,7 @@ namespace YooAsset { if (_loadEditorManifestOp == null) { - _loadEditorManifestOp = new LoadEditorManifestOperation(_simulateManifestPath); + _loadEditorManifestOp = new LoadEditorManifestOperation(_simulateManifestFilePath); OperationSystem.StartOperation(_loadEditorManifestOp); } @@ -79,7 +79,7 @@ namespace YooAsset None, QueryBuildinPackageVersion, LoadBuildinManifest, - VerifyPackage, + PackageCaching, Done, } @@ -87,7 +87,7 @@ namespace YooAsset private readonly string _packageName; private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp; private LoadBuildinManifestOperation _loadBuildinManifestOp; - private VerifyPackageOperation _verifyOperation; + private PackageCachingOperation _cachingOperation; private ESteps _steps = ESteps.None; internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl, string packageName) @@ -143,7 +143,7 @@ namespace YooAsset { PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion; _impl.ActiveManifest = _loadBuildinManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.PackageCaching; } else { @@ -153,16 +153,16 @@ namespace YooAsset } } - if (_steps == ESteps.VerifyPackage) + if (_steps == ESteps.PackageCaching) { - if (_verifyOperation == null) + if (_cachingOperation == null) { - _verifyOperation = VerifyPackageOperation.CreateOperation(_impl.ActiveManifest, _impl); - OperationSystem.StartOperation(_verifyOperation); + _cachingOperation = new PackageCachingOperation(_packageName); + OperationSystem.StartOperation(_cachingOperation); } - Progress = _verifyOperation.Progress; - if (_verifyOperation.IsDone) + Progress = _cachingOperation.Progress; + if (_cachingOperation.IsDone) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; @@ -186,7 +186,7 @@ namespace YooAsset QueryBuildinPackageVersion, UnpackBuildinManifest, LoadBuildinManifest, - VerifyPackage, + PackageCaching, Done, } @@ -197,7 +197,7 @@ namespace YooAsset private UnpackBuildinManifestOperation _unpackBuildinManifestOp; private LoadBuildinManifestOperation _loadBuildinManifestOp; private LoadCacheManifestOperation _loadCacheManifestOp; - private VerifyPackageOperation _verifyOperation; + private PackageCachingOperation _cachingOperation; private ESteps _steps = ESteps.None; internal HostPlayModeInitializationOperation(HostPlayModeImpl impl, string packageName) @@ -265,7 +265,7 @@ namespace YooAsset { PackageVersion = _loadCacheManifestOp.Manifest.PackageVersion; _impl.ActiveManifest = _loadCacheManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.PackageCaching; } else { @@ -284,15 +284,14 @@ namespace YooAsset if (_queryBuildinPackageVersionOp.IsDone == false) return; - // 注意:为了兼容MOD模式,初始化动态新增的包裹的时候,如果内置清单不存在也不需要报错! if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed) { _steps = ESteps.UnpackBuildinManifest; } else { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; + // 注意:为了兼容MOD模式,初始化动态新增的包裹的时候,如果内置清单不存在也不需要报错! + _steps = ESteps.PackageCaching; string error = _queryBuildinPackageVersionOp.Error; YooLogger.Log($"Failed to load buildin package version file : {error}"); } @@ -337,7 +336,7 @@ namespace YooAsset { PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion; _impl.ActiveManifest = _loadBuildinManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.PackageCaching; } else { @@ -347,16 +346,16 @@ namespace YooAsset } } - if (_steps == ESteps.VerifyPackage) + if (_steps == ESteps.PackageCaching) { - if (_verifyOperation == null) + if (_cachingOperation == null) { - _verifyOperation = VerifyPackageOperation.CreateOperation(_impl.ActiveManifest, _impl); - OperationSystem.StartOperation(_verifyOperation); + _cachingOperation = new PackageCachingOperation(_packageName); + OperationSystem.StartOperation(_cachingOperation); } - Progress = _verifyOperation.Progress; - if (_verifyOperation.IsDone) + Progress = _cachingOperation.Progress; + if (_cachingOperation.IsDone) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/InitializationOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/InitializationOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DeserializeManifestOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DeserializeManifestOperation.cs similarity index 54% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DeserializeManifestOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DeserializeManifestOperation.cs index 364f8aa..973246c 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DeserializeManifestOperation.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DeserializeManifestOperation.cs @@ -18,15 +18,15 @@ namespace YooAsset } private readonly BufferReader _buffer; - private int _patchAssetCount; - private int _patchBundleCount; + private int _packageAssetCount; + private int _packageBundleCount; private int _progressTotalValue; private ESteps _steps = ESteps.None; /// /// 解析的清单实例 /// - public PatchManifest Manifest { private set; get; } + public PackageManifest Manifest { private set; get; } public DeserializeManifestOperation(byte[] binaryData) { @@ -55,7 +55,7 @@ namespace YooAsset // 读取文件标记 uint fileSign = _buffer.ReadUInt32(); - if (fileSign != YooAssetSettings.PatchManifestFileSign) + if (fileSign != YooAssetSettings.ManifestFileSign) { _steps = ESteps.Done; Status = EOperationStatus.Failed; @@ -65,16 +65,16 @@ namespace YooAsset // 读取文件版本 string fileVersion = _buffer.ReadUTF8(); - if (fileVersion != YooAssetSettings.PatchManifestFileVersion) + if (fileVersion != YooAssetSettings.ManifestFileVersion) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.PatchManifestFileVersion}"; + Error = $"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}"; return; } // 读取文件头信息 - Manifest = new PatchManifest(); + Manifest = new PackageManifest(); Manifest.FileVersion = fileVersion; Manifest.EnableAddressable = _buffer.ReadBool(); Manifest.OutputNameStyle = _buffer.ReadInt32(); @@ -86,38 +86,38 @@ namespace YooAsset if (_steps == ESteps.PrepareAssetList) { - _patchAssetCount = _buffer.ReadInt32(); - Manifest.AssetList = new List(_patchAssetCount); - Manifest.AssetDic = new Dictionary(_patchAssetCount); - _progressTotalValue = _patchAssetCount; + _packageAssetCount = _buffer.ReadInt32(); + Manifest.AssetList = new List(_packageAssetCount); + Manifest.AssetDic = new Dictionary(_packageAssetCount); + _progressTotalValue = _packageAssetCount; _steps = ESteps.DeserializeAssetList; } if (_steps == ESteps.DeserializeAssetList) { - while (_patchAssetCount > 0) + while (_packageAssetCount > 0) { - var patchAsset = new PatchAsset(); - patchAsset.Address = _buffer.ReadUTF8(); - patchAsset.AssetPath = _buffer.ReadUTF8(); - patchAsset.AssetTags = _buffer.ReadUTF8Array(); - patchAsset.BundleID = _buffer.ReadInt32(); - patchAsset.DependIDs = _buffer.ReadInt32Array(); - Manifest.AssetList.Add(patchAsset); + var packageAsset = new PackageAsset(); + packageAsset.Address = _buffer.ReadUTF8(); + packageAsset.AssetPath = _buffer.ReadUTF8(); + packageAsset.AssetTags = _buffer.ReadUTF8Array(); + packageAsset.BundleID = _buffer.ReadInt32(); + packageAsset.DependIDs = _buffer.ReadInt32Array(); + Manifest.AssetList.Add(packageAsset); // 注意:我们不允许原始路径存在重名 - string assetPath = patchAsset.AssetPath; + string assetPath = packageAsset.AssetPath; if (Manifest.AssetDic.ContainsKey(assetPath)) throw new System.Exception($"AssetPath have existed : {assetPath}"); else - Manifest.AssetDic.Add(assetPath, patchAsset); + Manifest.AssetDic.Add(assetPath, packageAsset); - _patchAssetCount--; - Progress = 1f - _patchAssetCount / _progressTotalValue; + _packageAssetCount--; + Progress = 1f - _packageAssetCount / _progressTotalValue; if (OperationSystem.IsBusy) break; } - if (_patchAssetCount <= 0) + if (_packageAssetCount <= 0) { _steps = ESteps.PrepareBundleList; } @@ -125,36 +125,37 @@ namespace YooAsset if (_steps == ESteps.PrepareBundleList) { - _patchBundleCount = _buffer.ReadInt32(); - Manifest.BundleList = new List(_patchBundleCount); - Manifest.BundleDic = new Dictionary(_patchBundleCount); - _progressTotalValue = _patchBundleCount; + _packageBundleCount = _buffer.ReadInt32(); + Manifest.BundleList = new List(_packageBundleCount); + Manifest.BundleDic = new Dictionary(_packageBundleCount); + _progressTotalValue = _packageBundleCount; _steps = ESteps.DeserializeBundleList; } if (_steps == ESteps.DeserializeBundleList) { - while (_patchBundleCount > 0) + while (_packageBundleCount > 0) { - var patchBundle = new PatchBundle(); - patchBundle.BundleName = _buffer.ReadUTF8(); - patchBundle.FileHash = _buffer.ReadUTF8(); - patchBundle.FileCRC = _buffer.ReadUTF8(); - patchBundle.FileSize = _buffer.ReadInt64(); - patchBundle.IsRawFile = _buffer.ReadBool(); - patchBundle.LoadMethod = _buffer.ReadByte(); - patchBundle.Tags = _buffer.ReadUTF8Array(); - Manifest.BundleList.Add(patchBundle); + var packageBundle = new PackageBundle(); + packageBundle.BundleName = _buffer.ReadUTF8(); + packageBundle.FileHash = _buffer.ReadUTF8(); + packageBundle.FileCRC = _buffer.ReadUTF8(); + packageBundle.FileSize = _buffer.ReadInt64(); + packageBundle.IsRawFile = _buffer.ReadBool(); + packageBundle.LoadMethod = _buffer.ReadByte(); + packageBundle.Tags = _buffer.ReadUTF8Array(); + packageBundle.ReferenceIDs = _buffer.ReadInt32Array(); + Manifest.BundleList.Add(packageBundle); - patchBundle.ParseBundle(Manifest.PackageName, Manifest.OutputNameStyle); - Manifest.BundleDic.Add(patchBundle.BundleName, patchBundle); + packageBundle.ParseBundle(Manifest.PackageName, Manifest.OutputNameStyle); + Manifest.BundleDic.Add(packageBundle.BundleName, packageBundle); - _patchBundleCount--; - Progress = 1f - _patchBundleCount / _progressTotalValue; + _packageBundleCount--; + Progress = 1f - _packageBundleCount / _progressTotalValue; if (OperationSystem.IsBusy) break; } - if (_patchBundleCount <= 0) + if (_packageBundleCount <= 0) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DeserializeManifestOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DeserializeManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DeserializeManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DeserializeManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DownloadManifestOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DownloadManifestOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DownloadManifestOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DownloadManifestOperation.cs diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DownloadManifestOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DownloadManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/DownloadManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/DownloadManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadBuildinManifestOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadBuildinManifestOperation.cs similarity index 97% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadBuildinManifestOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadBuildinManifestOperation.cs index 10e183d..3791262 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadBuildinManifestOperation.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadBuildinManifestOperation.cs @@ -20,7 +20,7 @@ namespace YooAsset /// /// 加载的清单实例 /// - public PatchManifest Manifest { private set; get; } + public PackageManifest Manifest { private set; get; } public LoadBuildinManifestOperation(string buildinPackageName, string buildinPackageVersion) diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadBuildinManifestOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadBuildinManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadBuildinManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadBuildinManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadCacheManifestOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadCacheManifestOperation.cs similarity index 98% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadCacheManifestOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadCacheManifestOperation.cs index 93f651f..708d395 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadCacheManifestOperation.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadCacheManifestOperation.cs @@ -24,7 +24,7 @@ namespace YooAsset /// /// 加载的清单实例 /// - public PatchManifest Manifest { private set; get; } + public PackageManifest Manifest { private set; get; } public LoadCacheManifestOperation(string packageName, string packageVersion) diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadCacheManifestOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadCacheManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadCacheManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadCacheManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadEditorManifestOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadEditorManifestOperation.cs similarity index 96% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadEditorManifestOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadEditorManifestOperation.cs index 1fd210d..5fe071f 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadEditorManifestOperation.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadEditorManifestOperation.cs @@ -19,7 +19,7 @@ namespace YooAsset /// /// 加载的清单实例 /// - public PatchManifest Manifest { private set; get; } + public PackageManifest Manifest { private set; get; } public LoadEditorManifestOperation(string manifestFilePath) diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadEditorManifestOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadEditorManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/LoadEditorManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/LoadEditorManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryBuildinPackageVersionOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryBuildinPackageVersionOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryBuildinPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryBuildinPackageVersionOperation.cs diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryBuildinPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryBuildinPackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryBuildinPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryBuildinPackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryCachePackageHashOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryCachePackageHashOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryCachePackageHashOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryCachePackageHashOperation.cs diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryCachePackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryCachePackageHashOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryCachePackageHashOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryCachePackageHashOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryCachePackageVersionOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryCachePackageVersionOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryCachePackageVersionOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryCachePackageVersionOperation.cs diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryCachePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryCachePackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryCachePackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryCachePackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryRemotePackageVersionOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryRemotePackageVersionOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryRemotePackageVersionOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryRemotePackageVersionOperation.cs diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryRemotePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryRemotePackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/QueryRemotePackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/QueryRemotePackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/UnpackBuildinManifestOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/UnpackBuildinManifestOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/UnpackBuildinManifestOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/UnpackBuildinManifestOperation.cs diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/UnpackBuildinManifestOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/UnpackBuildinManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/UnpackBuildinManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/Internal/UnpackBuildinManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/PreDownloadPackageOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/PreDownloadContentOperation.cs similarity index 52% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/PreDownloadPackageOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/PreDownloadContentOperation.cs index fe3034c..c4dfbdc 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/PreDownloadPackageOperation.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/Operations/PreDownloadContentOperation.cs @@ -4,57 +4,69 @@ using System.Collections.Generic; namespace YooAsset { - public abstract class PreDownloadPackageOperation : AsyncOperationBase + public abstract class PreDownloadContentOperation : AsyncOperationBase { /// - /// 创建补丁下载器,用于下载更新指定资源版本所有的资源包文件 + /// 创建资源下载器,用于下载当前资源版本所有的资源包文件 /// /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public virtual PatchDownloaderOperation CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public virtual ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); } /// - /// 创建补丁下载器,用于下载更新资源标签指定的资源包文件 + /// 创建资源下载器,用于下载指定的资源标签关联的资源包文件 /// /// 资源标签 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public virtual PatchDownloaderOperation CreatePatchDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public virtual ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); } /// - /// 创建补丁下载器,用于下载更新资源标签指定的资源包文件 + /// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件 /// /// 资源标签列表 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public virtual PatchDownloaderOperation CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public virtual ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); } /// - /// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件 + /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 /// - /// 资源定位列表 + /// 资源定位地址 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public virtual PatchDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public virtual ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + } + + /// + /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 + /// + /// 资源定位地址列表 + /// 同时下载的最大文件数 + /// 下载失败的重试次数 + /// 超时时间 + public virtual ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); } } - public class EditorPlayModePreDownloadPackageOperation : PreDownloadPackageOperation + internal class EditorPlayModePreDownloadContentOperation : PreDownloadContentOperation { internal override void Start() { @@ -64,7 +76,7 @@ namespace YooAsset { } } - public class OfflinePlayModePreDownloadPackageOperation : PreDownloadPackageOperation + internal class OfflinePlayModePreDownloadContentOperation : PreDownloadContentOperation { internal override void Start() { @@ -74,7 +86,7 @@ namespace YooAsset { } } - public class HostPlayModePreDownloadPackageOperation : PreDownloadPackageOperation + internal class HostPlayModePreDownloadContentOperation : PreDownloadContentOperation { private enum ESteps { @@ -94,11 +106,11 @@ namespace YooAsset private LoadCacheManifestOperation _tryLoadCacheManifestOp; private LoadCacheManifestOperation _loadCacheManifestOp; private DownloadManifestOperation _downloadManifestOp; - private PatchManifest _manifest; + private PackageManifest _manifest; private ESteps _steps = ESteps.None; - internal HostPlayModePreDownloadPackageOperation(HostPlayModeImpl impl, string packageName, string packageVersion, int timeout) + internal HostPlayModePreDownloadContentOperation(HostPlayModeImpl impl, string packageName, string packageVersion, int timeout) { _impl = impl; _packageName = packageName; @@ -202,48 +214,64 @@ namespace YooAsset } } - public override PatchDownloaderOperation CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { if (Status != EOperationStatus.Succeed) { - YooLogger.Warning($"{nameof(PreDownloadPackageOperation)} status is not succeed !"); - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); } List downloadList = _impl.GetDownloadListByAll(_manifest); - var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public override PatchDownloaderOperation CreatePatchDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { if (Status != EOperationStatus.Succeed) { - YooLogger.Warning($"{nameof(PreDownloadPackageOperation)} status is not succeed !"); - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); } List downloadList = _impl.GetDownloadListByTags(_manifest, new string[] { tag }); - var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public override PatchDownloaderOperation CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { if (Status != EOperationStatus.Succeed) { - YooLogger.Warning($"{nameof(PreDownloadPackageOperation)} status is not succeed !"); - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); } List downloadList = _impl.GetDownloadListByTags(_manifest, tags); - var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public override PatchDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { if (Status != EOperationStatus.Succeed) { - YooLogger.Warning($"{nameof(PreDownloadPackageOperation)} status is not succeed !"); - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + } + + List assetInfos = new List(); + var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null); + assetInfos.Add(assetInfo); + + List downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray()); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; + } + public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + if (Status != EOperationStatus.Succeed) + { + YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); } List assetInfos = new List(locations.Length); @@ -254,7 +282,7 @@ namespace YooAsset } List downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray()); - var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } } diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/PreDownloadPackageOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/PreDownloadContentOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/PreDownloadPackageOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/PreDownloadContentOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageManifestOperation.cs similarity index 88% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageManifestOperation.cs index 48654e1..b9d194d 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageManifestOperation.cs @@ -5,10 +5,14 @@ using System.Collections.Generic; namespace YooAsset { /// - /// 向远端请求并更新补丁清单 + /// 向远端请求并更新清单 /// public abstract class UpdatePackageManifestOperation : AsyncOperationBase { + /// + /// 保存当前清单的版本,用于下次启动时自动加载的版本。 + /// + public virtual void SavePackageVersion() { } } /// @@ -47,7 +51,7 @@ namespace YooAsset /// /// 联机模式的更新清单操作 - /// 注意:优先加载沙盒里缓存的清单文件,如果有变化就更新远端清单文件,并保存到本地。 + /// 注意:优先加载沙盒里缓存的清单文件,如果缓存没找到就下载远端清单文件,并保存到本地。 /// internal sealed class HostPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation { @@ -59,7 +63,6 @@ namespace YooAsset DownloadManifest, LoadCacheManifest, CheckDeserializeManifest, - VerifyPackage, Done, } @@ -70,7 +73,6 @@ namespace YooAsset private LoadCacheManifestOperation _tryLoadCacheManifestOp; private LoadCacheManifestOperation _loadCacheManifestOp; private DownloadManifestOperation _downloadManifestOp; - private VerifyPackageOperation _verifyOperation; private ESteps _steps = ESteps.None; @@ -118,7 +120,8 @@ namespace YooAsset if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed) { _impl.ActiveManifest = _tryLoadCacheManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; } else { @@ -163,7 +166,8 @@ namespace YooAsset if (_loadCacheManifestOp.Status == EOperationStatus.Succeed) { _impl.ActiveManifest = _loadCacheManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; } else { @@ -172,22 +176,11 @@ namespace YooAsset Error = _loadCacheManifestOp.Error; } } + } - if (_steps == ESteps.VerifyPackage) - { - if (_verifyOperation == null) - { - _verifyOperation = VerifyPackageOperation.CreateOperation(_impl.ActiveManifest, _impl); - OperationSystem.StartOperation(_verifyOperation); - } - - Progress = _verifyOperation.Progress; - if (_verifyOperation.IsDone) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - } + public override void SavePackageVersion() + { + _impl.FlushManifestVersionFile(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageVersionOperation.cs b/Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageVersionOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageVersionOperation.cs rename to Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageVersionOperation.cs diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/Operations/UpdatePackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchAsset.cs b/Assets/YooAsset/Runtime/PackageSystem/PackageAsset.cs similarity index 96% rename from Assets/YooAsset/Runtime/PatchSystem/PatchAsset.cs rename to Assets/YooAsset/Runtime/PackageSystem/PackageAsset.cs index 6cd35d9..3ba70fb 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PatchAsset.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/PackageAsset.cs @@ -4,7 +4,7 @@ using System.Linq; namespace YooAsset { [Serializable] - internal class PatchAsset + internal class PackageAsset { /// /// 可寻址地址 diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchAsset.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/PackageAsset.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PatchAsset.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/PackageAsset.cs.meta diff --git a/Assets/YooAsset/Runtime/PackageSystem/PackageBundle.cs b/Assets/YooAsset/Runtime/PackageSystem/PackageBundle.cs new file mode 100644 index 0000000..1b12a2a --- /dev/null +++ b/Assets/YooAsset/Runtime/PackageSystem/PackageBundle.cs @@ -0,0 +1,230 @@ +using System; +using System.Linq; + +namespace YooAsset +{ + [Serializable] + internal class PackageBundle + { + /// + /// 资源包名称 + /// + public string BundleName; + + /// + /// 文件哈希值 + /// + public string FileHash; + + /// + /// 文件校验码 + /// + public string FileCRC; + + /// + /// 文件大小(字节数) + /// + public long FileSize; + + /// + /// 是否为原生文件 + /// + public bool IsRawFile; + + /// + /// 加载方法 + /// + public byte LoadMethod; + + /// + /// 资源包的分类标签 + /// + public string[] Tags; + + /// + /// 引用该资源包的ID列表 + /// + public int[] ReferenceIDs; + + + /// + /// 所属的包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 缓存GUID + /// + public string CacheGUID + { + get { return FileHash; } + } + + /// + /// 缓存的数据文件路径 + /// + private string _cachedDataFilePath; + public string CachedDataFilePath + { + get + { + if (string.IsNullOrEmpty(_cachedDataFilePath) == false) + return _cachedDataFilePath; + + string folderName = FileHash.Substring(0, 2); + if (IsRawFile) + { + string cacheRoot = PersistentHelper.GetCachedRawFileFolderPath(PackageName); + _cachedDataFilePath = $"{cacheRoot}/{folderName}/{CacheGUID}/{YooAssetSettings.CacheBundleDataFileName}{_fileExtension}"; + } + else + { + string cacheRoot = PersistentHelper.GetCachedBundleFileFolderPath(PackageName); + _cachedDataFilePath = $"{cacheRoot}/{folderName}/{CacheGUID}/{YooAssetSettings.CacheBundleDataFileName}"; + } + return _cachedDataFilePath; + } + } + + /// + /// 缓存的信息文件路径 + /// + private string _cachedInfoFilePath; + public string CachedInfoFilePath + { + get + { + if (string.IsNullOrEmpty(_cachedInfoFilePath) == false) + return _cachedInfoFilePath; + + string folderName = FileHash.Substring(0, 2); + if (IsRawFile) + { + string cacheRoot = PersistentHelper.GetCachedRawFileFolderPath(PackageName); + _cachedInfoFilePath = $"{cacheRoot}/{folderName}/{CacheGUID}/{YooAssetSettings.CacheBundleInfoFileName}"; + } + else + { + string cacheRoot = PersistentHelper.GetCachedBundleFileFolderPath(PackageName); + _cachedInfoFilePath = $"{cacheRoot}/{folderName}/{CacheGUID}/{YooAssetSettings.CacheBundleInfoFileName}"; + } + return _cachedInfoFilePath; + } + } + + /// + /// 临时的数据文件路径 + /// + private string _tempDataFilePath; + public string TempDataFilePath + { + get + { + if (string.IsNullOrEmpty(_tempDataFilePath) == false) + return _tempDataFilePath; + + _tempDataFilePath = $"{CachedDataFilePath}.temp"; + return _tempDataFilePath; + } + } + + /// + /// 内置文件路径 + /// + private string _streamingFilePath; + public string StreamingFilePath + { + get + { + if (string.IsNullOrEmpty(_streamingFilePath) == false) + return _streamingFilePath; + + _streamingFilePath = PathHelper.MakeStreamingLoadPath(FileName); + return _streamingFilePath; + } + } + + /// + /// 文件名称 + /// + private string _fileName; + public string FileName + { + get + { + if (string.IsNullOrEmpty(_fileName)) + throw new Exception("Should never get here !"); + return _fileName; + } + } + + /// + /// 文件后缀名 + /// + private string _fileExtension; + public string FileExtension + { + get + { + if (string.IsNullOrEmpty(_fileExtension)) + throw new Exception("Should never get here !"); + return _fileExtension; + } + } + + + public PackageBundle() + { + } + + /// + /// 解析资源包 + /// + public void ParseBundle(string packageName, int nameStype) + { + PackageName = packageName; + _fileExtension = ManifestTools.GetRemoteBundleFileExtension(BundleName); + _fileName = ManifestTools.GetRemoteBundleFileName(nameStype, BundleName, _fileExtension, FileHash); + } + + /// + /// 是否包含Tag + /// + public bool HasTag(string[] tags) + { + if (tags == null || tags.Length == 0) + return false; + if (Tags == null || Tags.Length == 0) + return false; + + foreach (var tag in tags) + { + if (Tags.Contains(tag)) + return true; + } + return false; + } + + /// + /// 是否包含任意Tags + /// + public bool HasAnyTags() + { + if (Tags != null && Tags.Length > 0) + return true; + else + return false; + } + + /// + /// 检测资源包文件内容是否相同 + /// + public bool Equals(PackageBundle otherBundle) + { + if (FileHash == otherBundle.FileHash) + return true; + + return false; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/PackageBundle.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/PackageBundle.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs b/Assets/YooAsset/Runtime/PackageSystem/PackageManifest.cs similarity index 71% rename from Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs rename to Assets/YooAsset/Runtime/PackageSystem/PackageManifest.cs index 44ce4d5..78bc911 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/PackageManifest.cs @@ -7,10 +7,10 @@ using System.Collections.Generic; namespace YooAsset { /// - /// 补丁清单文件 + /// 清单文件 /// [Serializable] - internal class PatchManifest + internal class PackageManifest { /// /// 文件版本 @@ -40,25 +40,25 @@ namespace YooAsset /// /// 资源列表(主动收集的资源列表) /// - public List AssetList = new List(); + public List AssetList = new List(); /// /// 资源包列表 /// - public List BundleList = new List(); + public List BundleList = new List(); /// - /// 资源包集合(提供BundleName获取PatchBundle) + /// 资源包集合(提供BundleName获取PackageBundle) /// [NonSerialized] - public Dictionary BundleDic; + public Dictionary BundleDic; /// - /// 资源映射集合(提供AssetPath获取PatchAsset) + /// 资源映射集合(提供AssetPath获取PackageAsset) /// [NonSerialized] - public Dictionary AssetDic; + public Dictionary AssetDic; /// /// 资源路径映射集合 @@ -86,22 +86,22 @@ namespace YooAsset YooLogger.Error("Addressable not support location to lower !"); AssetPathMapping = new Dictionary(AssetList.Count); - foreach (var patchAsset in AssetList) + foreach (var packageAsset in AssetList) { - string location = patchAsset.Address; + string location = packageAsset.Address; if (AssetPathMapping.ContainsKey(location)) throw new Exception($"Address have existed : {location}"); else - AssetPathMapping.Add(location, patchAsset.AssetPath); + AssetPathMapping.Add(location, packageAsset.AssetPath); } } else { _locationToLower = locationToLower; AssetPathMapping = new Dictionary(AssetList.Count * 2); - foreach (var patchAsset in AssetList) + foreach (var packageAsset in AssetList) { - string location = patchAsset.AssetPath; + string location = packageAsset.AssetPath; if (locationToLower) location = location.ToLower(); @@ -109,7 +109,7 @@ namespace YooAsset if (AssetPathMapping.ContainsKey(location)) throw new Exception($"AssetPath have existed : {location}"); else - AssetPathMapping.Add(location, patchAsset.AssetPath); + AssetPathMapping.Add(location, packageAsset.AssetPath); // 添加无后缀名路径的映射 if (Path.HasExtension(location)) @@ -118,7 +118,7 @@ namespace YooAsset if (AssetPathMapping.ContainsKey(locationWithoutExtension)) YooLogger.Warning($"AssetPath have existed : {locationWithoutExtension}"); else - AssetPathMapping.Add(locationWithoutExtension, patchAsset.AssetPath); + AssetPathMapping.Add(locationWithoutExtension, packageAsset.AssetPath); } } } @@ -170,15 +170,15 @@ namespace YooAsset /// 获取主资源包 /// 注意:传入的资源路径一定合法有效! /// - public PatchBundle GetMainPatchBundle(string assetPath) + public PackageBundle GetMainPackageBundle(string assetPath) { - if (AssetDic.TryGetValue(assetPath, out PatchAsset patchAsset)) + if (AssetDic.TryGetValue(assetPath, out PackageAsset packageAsset)) { - int bundleID = patchAsset.BundleID; + int bundleID = packageAsset.BundleID; if (bundleID >= 0 && bundleID < BundleList.Count) { - var patchBundle = BundleList[bundleID]; - return patchBundle; + var packageBundle = BundleList[bundleID]; + return packageBundle; } else { @@ -195,17 +195,17 @@ namespace YooAsset /// 获取资源依赖列表 /// 注意:传入的资源路径一定合法有效! /// - public PatchBundle[] GetAllDependencies(string assetPath) + public PackageBundle[] GetAllDependencies(string assetPath) { - if (AssetDic.TryGetValue(assetPath, out PatchAsset patchAsset)) + if (AssetDic.TryGetValue(assetPath, out PackageAsset packageAsset)) { - List result = new List(patchAsset.DependIDs.Length); - foreach (var dependID in patchAsset.DependIDs) + List result = new List(packageAsset.DependIDs.Length); + foreach (var dependID in packageAsset.DependIDs) { if (dependID >= 0 && dependID < BundleList.Count) { - var dependPatchBundle = BundleList[dependID]; - result.Add(dependPatchBundle); + var dependBundle = BundleList[dependID]; + result.Add(dependBundle); } else { @@ -221,17 +221,33 @@ namespace YooAsset } /// - /// 尝试获取补丁资源 + /// 获取资源包名称 /// - public bool TryGetPatchAsset(string assetPath, out PatchAsset result) + public string GetBundleName(int bundleID) + { + if (bundleID >= 0 && bundleID < BundleList.Count) + { + var packageBundle = BundleList[bundleID]; + return packageBundle.BundleName; + } + else + { + throw new Exception($"Invalid bundle id : {bundleID}"); + } + } + + /// + /// 尝试获取包裹的资源 + /// + public bool TryGetPackageAsset(string assetPath, out PackageAsset result) { return AssetDic.TryGetValue(assetPath, out result); } /// - /// 尝试获取补丁资源包 + /// 尝试获取包裹的资源包 /// - public bool TryGetPatchBundle(string bundleName, out PatchBundle result) + public bool TryGetPackageBundle(string bundleName, out PackageBundle result) { return BundleDic.TryGetValue(bundleName, out result); } @@ -239,11 +255,11 @@ namespace YooAsset /// /// 是否包含资源文件 /// - public bool IsIncludeBundleFile(string fileName) + public bool IsIncludeBundleFile(string cacheGUID) { - foreach (var patchBundle in BundleList) + foreach (var packageBundle in BundleList) { - if (patchBundle.FileName == fileName) + if (packageBundle.CacheGUID == cacheGUID) return true; } return false; @@ -255,11 +271,11 @@ namespace YooAsset public AssetInfo[] GetAssetsInfoByTags(string[] tags) { List result = new List(100); - foreach (var patchAsset in AssetList) + foreach (var packageAsset in AssetList) { - if (patchAsset.HasTag(tags)) + if (packageAsset.HasTag(tags)) { - AssetInfo assetInfo = new AssetInfo(patchAsset); + AssetInfo assetInfo = new AssetInfo(packageAsset); result.Add(assetInfo); } } @@ -275,9 +291,9 @@ namespace YooAsset DebugCheckLocation(location); string assetPath = MappingToAssetPath(location); - if (TryGetPatchAsset(assetPath, out PatchAsset patchAsset)) + if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset)) { - AssetInfo assetInfo = new AssetInfo(patchAsset, assetType); + AssetInfo assetInfo = new AssetInfo(packageAsset, assetType); return assetInfo; } else diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/PackageManifest.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/PackageManifest.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode.meta b/Assets/YooAsset/Runtime/PackageSystem/PlayMode.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PlayMode.meta rename to Assets/YooAsset/Runtime/PackageSystem/PlayMode.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeHelper.cs b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeHelper.cs similarity index 92% rename from Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeHelper.cs rename to Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeHelper.cs index da0daf9..ef52dd1 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeHelper.cs +++ b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeHelper.cs @@ -8,7 +8,7 @@ namespace YooAsset private static System.Type _classType; /// - /// 编辑器下模拟构建补丁清单 + /// 编辑器下模拟构建清单 /// public static string SimulateBuild(string packageName) { @@ -37,7 +37,7 @@ namespace YooAsset public static class EditorSimulateModeHelper { /// - /// 编辑器下模拟构建补丁清单 + /// 编辑器下模拟构建清单 /// public static string SimulateBuild(string packageName) { throw new System.Exception("Only support in unity editor !"); } } diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeHelper.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeHelper.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeHelper.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeHelper.cs.meta diff --git a/Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeImpl.cs b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeImpl.cs new file mode 100644 index 0000000..6d73edb --- /dev/null +++ b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeImpl.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class EditorSimulateModeImpl : IPlayModeServices, IBundleServices + { + private PackageManifest _activeManifest; + private bool _locationToLower; + + /// + /// 异步初始化 + /// + public InitializationOperation InitializeAsync(bool locationToLower, string simulateManifestFilePath) + { + _locationToLower = locationToLower; + var operation = new EditorSimulateModeInitializationOperation(this, simulateManifestFilePath); + OperationSystem.StartOperation(operation); + return operation; + } + + #region IPlayModeServices接口 + public PackageManifest ActiveManifest + { + set + { + _activeManifest = value; + _activeManifest.InitAssetPathMapping(_locationToLower); + } + get + { + return _activeManifest; + } + } + public void FlushManifestVersionFile() + { + } + + UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) + { + var operation = new EditorPlayModeUpdatePackageVersionOperation(); + OperationSystem.StartOperation(operation); + return operation; + } + UpdatePackageManifestOperation IPlayModeServices.UpdatePackageManifestAsync(string packageVersion, int timeout) + { + var operation = new EditorPlayModeUpdatePackageManifestOperation(); + OperationSystem.StartOperation(operation); + return operation; + } + PreDownloadContentOperation IPlayModeServices.PreDownloadContentAsync(string packageVersion, int timeout) + { + var operation = new EditorPlayModePreDownloadContentOperation(); + OperationSystem.StartOperation(operation); + return operation; + } + + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + } + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + } + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + } + + ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); + } + ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); + } + #endregion + + #region IBundleServices接口 + private BundleInfo CreateBundleInfo(PackageBundle packageBundle, AssetInfo assetInfo) + { + if (packageBundle == null) + throw new Exception("Should never get here !"); + + BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromEditor, assetInfo.AssetPath); + return bundleInfo; + } + BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo) + { + if (assetInfo.IsInvalid) + throw new Exception("Should never get here !"); + + // 注意:如果清单里未找到资源包会抛出异常! + var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); + return CreateBundleInfo(packageBundle, assetInfo); + } + BundleInfo[] IBundleServices.GetAllDependBundleInfos(AssetInfo assetInfo) + { + if (assetInfo.IsInvalid) + throw new Exception("Should never get here !"); + + // 注意:如果清单里未找到资源包会抛出异常! + var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + List result = new List(depends.Length); + foreach (var packageBundle in depends) + { + BundleInfo bundleInfo = CreateBundleInfo(packageBundle, assetInfo); + result.Add(bundleInfo); + } + return result.ToArray(); + } + string IBundleServices.GetBundleName(int bundleID) + { + return _activeManifest.GetBundleName(bundleID); + } + bool IBundleServices.IsServicesValid() + { + return _activeManifest != null; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeImpl.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/PlayMode/EditorSimulateModeImpl.cs.meta diff --git a/Assets/YooAsset/Runtime/PackageSystem/PlayMode/HostPlayModeImpl.cs b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/HostPlayModeImpl.cs new file mode 100644 index 0000000..290c10f --- /dev/null +++ b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/HostPlayModeImpl.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class HostPlayModeImpl : IPlayModeServices, IBundleServices, IRemoteServices + { + private PackageManifest _activeManifest; + + // 参数相关 + private string _packageName; + private bool _locationToLower; + private string _defaultHostServer; + private string _fallbackHostServer; + private IQueryServices _queryServices; + + /// + /// 异步初始化 + /// + public InitializationOperation InitializeAsync(string packageName, bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices) + { + _packageName = packageName; + _locationToLower = locationToLower; + _defaultHostServer = defaultHostServer; + _fallbackHostServer = fallbackHostServer; + _queryServices = queryServices; + + var operation = new HostPlayModeInitializationOperation(this, packageName); + OperationSystem.StartOperation(operation); + return operation; + } + + // 下载相关 + private List ConvertToDownloadList(List downloadList) + { + List result = new List(downloadList.Count); + foreach (var packageBundle in downloadList) + { + var bundleInfo = ConvertToDownloadInfo(packageBundle); + result.Add(bundleInfo); + } + return result; + } + private BundleInfo ConvertToDownloadInfo(PackageBundle packageBundle) + { + string remoteMainURL = GetRemoteMainURL(packageBundle.FileName); + string remoteFallbackURL = GetRemoteFallbackURL(packageBundle.FileName); + BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromRemote, remoteMainURL, remoteFallbackURL); + return bundleInfo; + } + + // 解压相关 + private List ConvertToUnpackList(List unpackList) + { + List result = new List(unpackList.Count); + foreach (var packageBundle in unpackList) + { + var bundleInfo = ConvertToUnpackInfo(packageBundle); + result.Add(bundleInfo); + } + return result; + } + private BundleInfo ConvertToUnpackInfo(PackageBundle packageBundle) + { + return ManifestTools.GetUnpackInfo(packageBundle); + } + + #region IRemoteServices接口 + public string GetRemoteMainURL(string fileName) + { + return $"{_defaultHostServer}/{fileName}"; + } + public string GetRemoteFallbackURL(string fileName) + { + return $"{_fallbackHostServer}/{fileName}"; + } + #endregion + + #region IPlayModeServices接口 + public PackageManifest ActiveManifest + { + set + { + _activeManifest = value; + _activeManifest.InitAssetPathMapping(_locationToLower); + } + get + { + return _activeManifest; + } + } + public void FlushManifestVersionFile() + { + if (_activeManifest != null) + PersistentHelper.SaveCachePackageVersionFile(_packageName, _activeManifest.PackageVersion); + } + + private bool IsBuildinPackageBundle(PackageBundle packageBundle) + { + return _queryServices.QueryStreamingAssets(packageBundle.FileName); + } + private bool IsCachedPackageBundle(PackageBundle packageBundle) + { + return CacheSystem.IsCached(packageBundle.PackageName, packageBundle.CacheGUID); + } + + UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) + { + var operation = new HostPlayModeUpdatePackageVersionOperation(this, _packageName, appendTimeTicks, timeout); + OperationSystem.StartOperation(operation); + return operation; + } + UpdatePackageManifestOperation IPlayModeServices.UpdatePackageManifestAsync(string packageVersion, int timeout) + { + var operation = new HostPlayModeUpdatePackageManifestOperation(this, _packageName, packageVersion, timeout); + OperationSystem.StartOperation(operation); + return operation; + } + PreDownloadContentOperation IPlayModeServices.PreDownloadContentAsync(string packageVersion, int timeout) + { + var operation = new HostPlayModePreDownloadContentOperation(this, _packageName, packageVersion, timeout); + OperationSystem.StartOperation(operation); + return operation; + } + + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) + { + List downloadList = GetDownloadListByAll(_activeManifest); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; + } + public List GetDownloadListByAll(PackageManifest manifest) + { + List downloadList = new List(1000); + foreach (var packageBundle in manifest.BundleList) + { + // 忽略缓存文件 + if (IsCachedPackageBundle(packageBundle)) + continue; + + // 忽略APP资源 + if (IsBuildinPackageBundle(packageBundle)) + continue; + + downloadList.Add(packageBundle); + } + + return ConvertToDownloadList(downloadList); + } + + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) + { + List downloadList = GetDownloadListByTags(_activeManifest, tags); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; + } + public List GetDownloadListByTags(PackageManifest manifest, string[] tags) + { + List downloadList = new List(1000); + foreach (var packageBundle in manifest.BundleList) + { + // 忽略缓存文件 + if (IsCachedPackageBundle(packageBundle)) + continue; + + // 忽略APP资源 + if (IsBuildinPackageBundle(packageBundle)) + continue; + + // 如果未带任何标记,则统一下载 + if (packageBundle.HasAnyTags() == false) + { + downloadList.Add(packageBundle); + } + else + { + // 查询DLC资源 + if (packageBundle.HasTag(tags)) + { + downloadList.Add(packageBundle); + } + } + } + + return ConvertToDownloadList(downloadList); + } + + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) + { + List downloadList = GetDownloadListByPaths(_activeManifest, assetInfos); + var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; + } + public List GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos) + { + // 获取资源对象的资源包和所有依赖资源包 + List checkList = new List(); + foreach (var assetInfo in assetInfos) + { + if (assetInfo.IsInvalid) + { + YooLogger.Warning(assetInfo.Error); + continue; + } + + // 注意:如果清单里未找到资源包会抛出异常! + PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.AssetPath); + if (checkList.Contains(mainBundle) == false) + checkList.Add(mainBundle); + + // 注意:如果清单里未找到资源包会抛出异常! + PackageBundle[] dependBundles = manifest.GetAllDependencies(assetInfo.AssetPath); + foreach (var dependBundle in dependBundles) + { + if (checkList.Contains(dependBundle) == false) + checkList.Add(dependBundle); + } + } + + List downloadList = new List(1000); + foreach (var packageBundle in checkList) + { + // 忽略缓存文件 + if (IsCachedPackageBundle(packageBundle)) + continue; + + // 忽略APP资源 + if (IsBuildinPackageBundle(packageBundle)) + continue; + + downloadList.Add(packageBundle); + } + + return ConvertToDownloadList(downloadList); + } + + ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) + { + List unpcakList = GetUnpackListByAll(_activeManifest); + var operation = new ResourceUnpackerOperation(unpcakList, upackingMaxNumber, failedTryAgain, timeout); + return operation; + } + private List GetUnpackListByAll(PackageManifest manifest) + { + List downloadList = new List(1000); + foreach (var packageBundle in manifest.BundleList) + { + // 忽略缓存文件 + if (IsCachedPackageBundle(packageBundle)) + continue; + + if (IsBuildinPackageBundle(packageBundle)) + { + downloadList.Add(packageBundle); + } + } + + return ConvertToUnpackList(downloadList); + } + + ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) + { + List unpcakList = GetUnpackListByTags(_activeManifest, tags); + var operation = new ResourceUnpackerOperation(unpcakList, upackingMaxNumber, failedTryAgain, timeout); + return operation; + } + private List GetUnpackListByTags(PackageManifest manifest, string[] tags) + { + List downloadList = new List(1000); + foreach (var packageBundle in manifest.BundleList) + { + // 忽略缓存文件 + if (IsCachedPackageBundle(packageBundle)) + continue; + + // 查询DLC资源 + if (IsBuildinPackageBundle(packageBundle)) + { + if (packageBundle.HasTag(tags)) + { + downloadList.Add(packageBundle); + } + } + } + + return ConvertToUnpackList(downloadList); + } + #endregion + + #region IBundleServices接口 + private BundleInfo CreateBundleInfo(PackageBundle packageBundle) + { + if (packageBundle == null) + throw new Exception("Should never get here !"); + + // 查询沙盒资源 + if (IsCachedPackageBundle(packageBundle)) + { + BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromCache); + return bundleInfo; + } + + // 查询APP资源 + if (IsBuildinPackageBundle(packageBundle)) + { + BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromStreaming); + return bundleInfo; + } + + // 从服务端下载 + return ConvertToDownloadInfo(packageBundle); + } + BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo) + { + if (assetInfo.IsInvalid) + throw new Exception("Should never get here !"); + + // 注意:如果清单里未找到资源包会抛出异常! + var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); + return CreateBundleInfo(packageBundle); + } + BundleInfo[] IBundleServices.GetAllDependBundleInfos(AssetInfo assetInfo) + { + if (assetInfo.IsInvalid) + throw new Exception("Should never get here !"); + + // 注意:如果清单里未找到资源包会抛出异常! + var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + List result = new List(depends.Length); + foreach (var packageBundle in depends) + { + BundleInfo bundleInfo = CreateBundleInfo(packageBundle); + result.Add(bundleInfo); + } + return result.ToArray(); + } + string IBundleServices.GetBundleName(int bundleID) + { + return _activeManifest.GetBundleName(bundleID); + } + bool IBundleServices.IsServicesValid() + { + return _activeManifest != null; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/HostPlayModeImpl.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/PlayMode/HostPlayModeImpl.cs.meta diff --git a/Assets/YooAsset/Runtime/PackageSystem/PlayMode/OfflinePlayModeImpl.cs b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/OfflinePlayModeImpl.cs new file mode 100644 index 0000000..a99439d --- /dev/null +++ b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/OfflinePlayModeImpl.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class OfflinePlayModeImpl : IPlayModeServices, IBundleServices + { + private PackageManifest _activeManifest; + private bool _locationToLower; + + /// + /// 异步初始化 + /// + public InitializationOperation InitializeAsync(string packageName, bool locationToLower) + { + _locationToLower = locationToLower; + var operation = new OfflinePlayModeInitializationOperation(this, packageName); + OperationSystem.StartOperation(operation); + return operation; + } + + #region IPlayModeServices接口 + public PackageManifest ActiveManifest + { + set + { + _activeManifest = value; + _activeManifest.InitAssetPathMapping(_locationToLower); + } + get + { + return _activeManifest; + } + } + public void FlushManifestVersionFile() + { + } + + UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) + { + var operation = new OfflinePlayModeUpdatePackageVersionOperation(); + OperationSystem.StartOperation(operation); + return operation; + } + UpdatePackageManifestOperation IPlayModeServices.UpdatePackageManifestAsync(string packageVersion, int timeout) + { + var operation = new OfflinePlayModeUpdatePackageManifestOperation(); + OperationSystem.StartOperation(operation); + return operation; + } + PreDownloadContentOperation IPlayModeServices.PreDownloadContentAsync(string packageVersion, int timeout) + { + var operation = new OfflinePlayModePreDownloadContentOperation(); + OperationSystem.StartOperation(operation); + return operation; + } + + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + } + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + } + ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); + } + + ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); + } + ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) + { + return ResourceUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); + } + #endregion + + #region IBundleServices接口 + private BundleInfo CreateBundleInfo(PackageBundle packageBundle) + { + if (packageBundle == null) + throw new Exception("Should never get here !"); + + // 查询沙盒资源 + if (CacheSystem.IsCached(packageBundle.PackageName, packageBundle.CacheGUID)) + { + BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromCache); + return bundleInfo; + } + + // 查询APP资源 + { + BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromStreaming); + return bundleInfo; + } + } + BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo) + { + if (assetInfo.IsInvalid) + throw new Exception("Should never get here !"); + + // 注意:如果清单里未找到资源包会抛出异常! + var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); + return CreateBundleInfo(packageBundle); + } + BundleInfo[] IBundleServices.GetAllDependBundleInfos(AssetInfo assetInfo) + { + if (assetInfo.IsInvalid) + throw new Exception("Should never get here !"); + + // 注意:如果清单里未找到资源包会抛出异常! + var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + List result = new List(depends.Length); + foreach (var packageBundle in depends) + { + BundleInfo bundleInfo = CreateBundleInfo(packageBundle); + result.Add(bundleInfo); + } + return result.ToArray(); + } + string IBundleServices.GetBundleName(int bundleID) + { + return _activeManifest.GetBundleName(bundleID); + } + bool IBundleServices.IsServicesValid() + { + return _activeManifest != null; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs.meta b/Assets/YooAsset/Runtime/PackageSystem/PlayMode/OfflinePlayModeImpl.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs.meta rename to Assets/YooAsset/Runtime/PackageSystem/PlayMode/OfflinePlayModeImpl.cs.meta diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs b/Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs deleted file mode 100644 index f2e58a6..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.IO; -using UnityEngine; - -namespace YooAsset -{ - /// - /// 检查包裹内容的完整性 - /// - public abstract class CheckPackageContentsOperation : AsyncOperationBase - { - } - - internal sealed class EditorSimulateModeCheckPackageContentsOperation : CheckPackageContentsOperation - { - internal EditorSimulateModeCheckPackageContentsOperation() - { - } - internal override void Start() - { - Status = EOperationStatus.Succeed; - } - internal override void Update() - { - } - } - internal sealed class OfflinePlayModeCheckPackageContentsOperation : CheckPackageContentsOperation - { - internal OfflinePlayModeCheckPackageContentsOperation() - { - } - internal override void Start() - { - Status = EOperationStatus.Succeed; - } - internal override void Update() - { - } - } - internal sealed class HostPlayModeCheckPackageContentsOperation : CheckPackageContentsOperation - { - private enum ESteps - { - None, - CheckActiveManifest, - LoadCacheManifest, - VerifyPackage, - Done, - } - - private readonly HostPlayModeImpl _impl; - private readonly string _packageName; - private readonly string _packageVersion; - private LoadCacheManifestOperation _loadCacheManifestOp; - private VerifyPackageOperation _verifyOperation; - private PatchManifest _verifyManifest; - private ESteps _steps = ESteps.None; - - internal HostPlayModeCheckPackageContentsOperation(HostPlayModeImpl impl, string packageName, string packageVersion) - { - _impl = impl; - _packageName = packageName; - _packageVersion = packageVersion; - } - internal override void Start() - { - _steps = ESteps.CheckActiveManifest; - } - internal override void Update() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckActiveManifest) - { - // 检测当前激活的清单对象 - if (_impl.ActiveManifest != null && _impl.ActiveManifest.PackageVersion == _packageVersion) - { - _verifyManifest = _impl.ActiveManifest; - _steps = ESteps.VerifyPackage; - } - else - { - _steps = ESteps.LoadCacheManifest; - } - } - - if (_steps == ESteps.LoadCacheManifest) - { - if (_loadCacheManifestOp == null) - { - _loadCacheManifestOp = new LoadCacheManifestOperation(_packageName, _packageVersion); - OperationSystem.StartOperation(_loadCacheManifestOp); - } - - if (_loadCacheManifestOp.IsDone == false) - return; - - if (_loadCacheManifestOp.Status == EOperationStatus.Succeed) - { - _verifyManifest = _loadCacheManifestOp.Manifest; - _steps = ESteps.VerifyPackage; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _loadCacheManifestOp.Error; - } - } - - if (_steps == ESteps.VerifyPackage) - { - if (_verifyOperation == null) - { - _verifyOperation = VerifyPackageOperation.CreateOperation(_verifyManifest, _impl); - OperationSystem.StartOperation(_verifyOperation); - } - - Progress = _verifyOperation.Progress; - if (_verifyOperation.IsDone == false) - return; - - bool verifySucceed = true; - foreach (var verifyInfo in _verifyOperation.VerifyFailList) - { - // 注意:跳过内置资源文件 - if (verifyInfo.IsBuildinFile) - continue; - - verifySucceed = false; - YooLogger.Warning($"Failed verify file : {verifyInfo.VerifyFilePath}"); - } - - if (verifySucceed) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"The package resource {_packageName} content has verify failed file !"; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs b/Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs deleted file mode 100644 index 2255bdf..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.IO; - -namespace YooAsset -{ - /// - /// 清理本地包裹未使用的缓存文件 - /// - public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase - { - private enum ESteps - { - None, - GetUnusedCacheFiles, - ClearUnusedCacheFiles, - Done, - } - - private readonly AssetsPackage _package; - private List _unusedCacheFilePaths; - private int _unusedFileTotalCount = 0; - private ESteps _steps = ESteps.None; - - internal ClearUnusedCacheFilesOperation(AssetsPackage package) - { - _package = package; - } - internal override void Start() - { - _steps = ESteps.GetUnusedCacheFiles; - } - internal override void Update() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.GetUnusedCacheFiles) - { - _unusedCacheFilePaths = GetUnusedCacheFilePaths(); - _unusedFileTotalCount = _unusedCacheFilePaths.Count; - YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}"); - _steps = ESteps.ClearUnusedCacheFiles; - } - - if (_steps == ESteps.ClearUnusedCacheFiles) - { - for (int i = _unusedCacheFilePaths.Count - 1; i >= 0; i--) - { - string filePath = _unusedCacheFilePaths[i]; - if (File.Exists(filePath)) - { - try - { - File.Delete(filePath); - YooLogger.Log($"Delete unused cache file : {filePath}"); - } - catch (System.Exception e) - { - YooLogger.Warning($"Failed delete cache file : {filePath} ! {e.Message}"); - } - } - _unusedCacheFilePaths.RemoveAt(i); - - if (OperationSystem.IsBusy) - break; - } - - if (_unusedFileTotalCount == 0) - Progress = 1.0f; - else - Progress = 1.0f - (_unusedCacheFilePaths.Count / _unusedFileTotalCount); - - if (_unusedCacheFilePaths.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - } - } - - /// - /// 获取未被使用的缓存文件路径集合 - /// - private List GetUnusedCacheFilePaths() - { - string cacheFolderPath = PersistentHelper.GetCacheFolderPath(_package.PackageName); - if (Directory.Exists(cacheFolderPath) == false) - return new List(); - - DirectoryInfo directoryInfo = new DirectoryInfo(cacheFolderPath); - FileInfo[] fileInfos = directoryInfo.GetFiles(); - List result = new List(fileInfos.Length); - foreach (FileInfo fileInfo in fileInfos) - { - if (_package.IsIncludeBundleFile(fileInfo.Name) == false) - { - result.Add(fileInfo.FullName); - } - } - return result; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs b/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs deleted file mode 100644 index 6600ffa..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs +++ /dev/null @@ -1,294 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Threading; - -namespace YooAsset -{ - internal abstract class VerifyPackageOperation : AsyncOperationBase - { - public List VerifySuccessList { protected set; get; } - public List VerifyFailList { protected set; get; } - - public static VerifyPackageOperation CreateOperation(PatchManifest manifest, IPlayModeServices playModeServices) - { -#if UNITY_WEBGL - VerifyPackageOperation operation = new VerifyPackageWithoutThreadOperation(manifest, playModeServices); -#else - VerifyPackageOperation operation = new VerifyPackageWithThreadOperation(manifest, playModeServices); -#endif - return operation; - } - } - - /// - /// 本地缓存文件验证(线程版) - /// - internal class VerifyPackageWithThreadOperation : VerifyPackageOperation - { - private enum ESteps - { - None, - InitVerify, - PrepareVerify, - UpdateVerify, - Done, - } - - private readonly PatchManifest _manifest; - private readonly IPlayModeServices _playModeServices; - private readonly ThreadSyncContext _syncContext = new ThreadSyncContext(); - private List _waitingList; - private List _verifyingList; - private int _verifyMaxNum; - private int _verifyTotalCount; - private float _verifyStartTime; - private ESteps _steps = ESteps.None; - - public VerifyPackageWithThreadOperation(PatchManifest manifest, IPlayModeServices playModeServices) - { - _manifest = manifest; - _playModeServices = playModeServices; - } - internal override void Start() - { - _steps = ESteps.InitVerify; - _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; - } - internal override void Update() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.InitVerify) - { - int bundleCount = _manifest.BundleList.Count; - VerifySuccessList = new List(bundleCount); - VerifyFailList = new List(bundleCount); - - // 设置同时验证的最大数 - ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads); - YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}"); - _verifyMaxNum = Math.Min(workerThreads, ioThreads); - _verifyTotalCount = bundleCount; - if (_verifyMaxNum < 1) - _verifyMaxNum = 1; - - _waitingList = new List(bundleCount); - _verifyingList = new List(_verifyMaxNum); - _steps = ESteps.PrepareVerify; - } - - if (_steps == ESteps.PrepareVerify) - { - foreach (var patchBundle in _manifest.BundleList) - { - if (CacheSystem.IsCached(patchBundle)) - continue; - - bool isBuildinFile = _playModeServices.IsBuildinPatchBundle(patchBundle); - VerifyInfo verifyInfo = new VerifyInfo(isBuildinFile, patchBundle); - _waitingList.Add(verifyInfo); - } - _steps = ESteps.UpdateVerify; - } - - if (_steps == ESteps.UpdateVerify) - { - _syncContext.Update(); - - Progress = GetVerifierProgress(); - if (_waitingList.Count == 0 && _verifyingList.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; - YooLogger.Log($"Verify elapsed time {costTime:f1} seconds"); - } - - for (int i = _waitingList.Count - 1; i >= 0; i--) - { - if (OperationSystem.IsBusy) - break; - - if (_verifyingList.Count >= _verifyMaxNum) - break; - - var verifyIno = _waitingList[i]; - if (VerifyFileWithThread(verifyIno)) - { - _waitingList.RemoveAt(i); - _verifyingList.Add(verifyIno); - } - else - { - YooLogger.Warning("The thread pool is failed queued."); - break; - } - } - } - } - - private float GetVerifierProgress() - { - if (_verifyTotalCount == 0) - return 1f; - return (float)(VerifySuccessList.Count + VerifyFailList.Count) / _verifyTotalCount; - } - private bool VerifyFileWithThread(VerifyInfo verifyInfo) - { - return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), verifyInfo); - } - private void VerifyInThread(object infoObj) - { - VerifyInfo verifyInfo = (VerifyInfo)infoObj; - verifyInfo.Result = CacheSystem.VerifyBundle(verifyInfo.VerifyBundle, CacheSystem.InitVerifyLevel); - _syncContext.Post(VerifyCallback, verifyInfo); - } - private void VerifyCallback(object obj) - { - VerifyInfo verifyIno = (VerifyInfo)obj; - if (verifyIno.Result == EVerifyResult.Succeed) - { - VerifySuccessList.Add(verifyIno); - CacheSystem.CacheBundle(verifyIno.VerifyBundle); - } - else - { - VerifyFailList.Add(verifyIno); - - // 删除验证失败的缓存文件 - if (File.Exists(verifyIno.VerifyBundle.CachedFilePath)) - { - YooLogger.Warning($"Delete verify failed bundle file : {verifyIno.VerifyBundle.CachedFilePath}"); - File.Delete(verifyIno.VerifyBundle.CachedFilePath); - } - } - _verifyingList.Remove(verifyIno); - } - } - - /// - /// 本地缓存文件验证(非线程版) - /// - internal class VerifyPackageWithoutThreadOperation : VerifyPackageOperation - { - private enum ESteps - { - None, - InitVerify, - PrepareVerify, - UpdateVerify, - Done, - } - - private readonly PatchManifest _manifest; - private readonly IPlayModeServices _playModeServices; - private List _waitingList; - private List _verifyingList; - private int _verifyMaxNum; - private int _verifyTotalCount; - private float _verifyStartTime; - private ESteps _steps = ESteps.None; - - public VerifyPackageWithoutThreadOperation(PatchManifest manifest, IPlayModeServices playModeServices) - { - _manifest = manifest; - _playModeServices = playModeServices; - } - internal override void Start() - { - _steps = ESteps.InitVerify; - _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; - } - internal override void Update() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.InitVerify) - { - int bundleCount = _manifest.BundleList.Count; - VerifySuccessList = new List(bundleCount); - VerifyFailList = new List(bundleCount); - - // 设置同时验证的最大数 - _verifyMaxNum = bundleCount; - _verifyTotalCount = _waitingList.Count; - - _waitingList = new List(bundleCount); - _verifyingList = new List(_verifyMaxNum); - _steps = ESteps.PrepareVerify; - } - - if (_steps == ESteps.PrepareVerify) - { - foreach (var patchBundle in _manifest.BundleList) - { - if (CacheSystem.IsCached(patchBundle)) - continue; - - bool isBuildinFile = _playModeServices.IsBuildinPatchBundle(patchBundle); - VerifyInfo verifyInfo = new VerifyInfo(isBuildinFile, patchBundle); - _waitingList.Add(verifyInfo); - } - _steps = ESteps.UpdateVerify; - } - - if (_steps == ESteps.UpdateVerify) - { - Progress = GetVerifierProgress(); - if (_waitingList.Count == 0 && _verifyingList.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; - YooLogger.Log($"Verify elapsed time {costTime:f1} seconds"); - } - - for (int i = _waitingList.Count - 1; i >= 0; i--) - { - if (OperationSystem.IsBusy) - break; - - if (_verifyingList.Count >= _verifyMaxNum) - break; - - var verifyIno = _waitingList[i]; - VerifyFileWithoutThread(verifyIno); - _waitingList.RemoveAt(i); - _verifyingList.Add(verifyIno); - } - - _verifyingList.Clear(); - } - } - - private float GetVerifierProgress() - { - if (_verifyTotalCount == 0) - return 1f; - return (float)(VerifySuccessList.Count + VerifyFailList.Count) / _verifyTotalCount; - } - private void VerifyFileWithoutThread(VerifyInfo verifyIno) - { - var verifyResult = CacheSystem.VerifyAndCacheLocalBundleFile(verifyIno.VerifyBundle, CacheSystem.InitVerifyLevel); - if (verifyResult == EVerifyResult.Succeed) - { - VerifySuccessList.Add(verifyIno); - } - else - { - VerifyFailList.Add(verifyIno); - - // 删除验证失败的缓存文件 - if (File.Exists(verifyIno.VerifyBundle.CachedFilePath)) - { - YooLogger.Warning($"Delete verify failed bundle file : {verifyIno.VerifyBundle.CachedFilePath}"); - File.Delete(verifyIno.VerifyBundle.CachedFilePath); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs b/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs deleted file mode 100644 index 4b6b7de..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using System.Linq; - -namespace YooAsset -{ - [Serializable] - internal class PatchBundle - { - /// - /// 资源包名称 - /// - public string BundleName; - - /// - /// 文件哈希值 - /// - public string FileHash; - - /// - /// 文件校验码 - /// - public string FileCRC; - - /// - /// 文件大小(字节数) - /// - public long FileSize; - - /// - /// 是否为原生文件 - /// - public bool IsRawFile; - - /// - /// 加载方法 - /// - public byte LoadMethod; - - /// - /// 资源包的分类标签 - /// - public string[] Tags; - - - /// - /// 所属的包裹名称 - /// - private string _packageName; - - /// - /// 缓存文件路径 - /// - private string _cachedFilePath; - public string CachedFilePath - { - get - { - if (string.IsNullOrEmpty(_cachedFilePath) == false) - return _cachedFilePath; - - string cacheRoot = PersistentHelper.GetCacheFolderPath(_packageName); - _cachedFilePath = $"{cacheRoot}/{FileName}"; - return _cachedFilePath; - } - } - - /// - /// 内置文件路径 - /// - private string _streamingFilePath; - public string StreamingFilePath - { - get - { - if (string.IsNullOrEmpty(_streamingFilePath) == false) - return _streamingFilePath; - - _streamingFilePath = PathHelper.MakeStreamingLoadPath(FileName); - return _streamingFilePath; - } - } - - /// - /// 文件名称 - /// - private string _fileName; - public string FileName - { - get - { - if (string.IsNullOrEmpty(_fileName)) - throw new Exception("Should never get here !"); - return _fileName; - } - } - - /// - /// 缓存查询Key - /// - private string _cacheKey; - public string CacheKey - { - get - { - if (string.IsNullOrEmpty(_cacheKey)) - throw new Exception("Should never get here !"); - return _cacheKey; - } - } - - - public PatchBundle() - { - } - - /// - /// 解析资源包 - /// - public void ParseBundle(string packageName, int nameStype) - { - _packageName = packageName; - _cacheKey = $"{packageName}-{FileHash}"; - _fileName = PatchManifestTools.CreateBundleFileName(nameStype, BundleName, FileHash, IsRawFile); - } - - /// - /// 是否包含Tag - /// - public bool HasTag(string[] tags) - { - if (tags == null || tags.Length == 0) - return false; - if (Tags == null || Tags.Length == 0) - return false; - - foreach (var tag in tags) - { - if (Tags.Contains(tag)) - return true; - } - return false; - } - - /// - /// 是否包含任意Tags - /// - public bool HasAnyTags() - { - if (Tags != null && Tags.Length > 0) - return true; - else - return false; - } - - /// - /// 检测资源包文件内容是否相同 - /// - public bool Equals(PatchBundle otherBundle) - { - if (FileHash == otherBundle.FileHash) - return true; - - return false; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs b/Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs deleted file mode 100644 index 35790fa..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace YooAsset -{ - internal static class PatchManifestTools - { - /// - /// 序列化(JSON文件) - /// - public static void SerializeToJson(string savePath, PatchManifest manifest) - { - string json = JsonUtility.ToJson(manifest, true); - FileUtility.CreateFile(savePath, json); - } - - /// - /// 序列化(二进制文件) - /// - public static void SerializeToBinary(string savePath, PatchManifest patchManifest) - { - using (FileStream fs = new FileStream(savePath, FileMode.Create)) - { - // 创建缓存器 - BufferWriter buffer = new BufferWriter(YooAssetSettings.PatchManifestFileMaxSize); - - // 写入文件标记 - buffer.WriteUInt32(YooAssetSettings.PatchManifestFileSign); - - // 写入文件版本 - buffer.WriteUTF8(patchManifest.FileVersion); - - // 写入文件头信息 - buffer.WriteBool(patchManifest.EnableAddressable); - buffer.WriteInt32(patchManifest.OutputNameStyle); - buffer.WriteUTF8(patchManifest.PackageName); - buffer.WriteUTF8(patchManifest.PackageVersion); - - // 写入资源列表 - buffer.WriteInt32(patchManifest.AssetList.Count); - for (int i = 0; i < patchManifest.AssetList.Count; i++) - { - var patchAsset = patchManifest.AssetList[i]; - buffer.WriteUTF8(patchAsset.Address); - buffer.WriteUTF8(patchAsset.AssetPath); - buffer.WriteUTF8Array(patchAsset.AssetTags); - buffer.WriteInt32(patchAsset.BundleID); - buffer.WriteInt32Array(patchAsset.DependIDs); - } - - // 写入资源包列表 - buffer.WriteInt32(patchManifest.BundleList.Count); - for (int i = 0; i < patchManifest.BundleList.Count; i++) - { - var patchBundle = patchManifest.BundleList[i]; - buffer.WriteUTF8(patchBundle.BundleName); - buffer.WriteUTF8(patchBundle.FileHash); - buffer.WriteUTF8(patchBundle.FileCRC); - buffer.WriteInt64(patchBundle.FileSize); - buffer.WriteBool(patchBundle.IsRawFile); - buffer.WriteByte(patchBundle.LoadMethod); - buffer.WriteUTF8Array(patchBundle.Tags); - } - - // 写入文件流 - buffer.WriteToStream(fs); - fs.Flush(); - } - } - - /// - /// 反序列化(二进制文件) - /// - public static PatchManifest DeserializeFromBinary(byte[] binaryData) - { - // 创建缓存器 - BufferReader buffer = new BufferReader(binaryData); - - // 读取文件标记 - uint fileSign = buffer.ReadUInt32(); - if (fileSign != YooAssetSettings.PatchManifestFileSign) - throw new Exception("Invalid manifest file !"); - - // 读取文件版本 - string fileVersion = buffer.ReadUTF8(); - if (fileVersion != YooAssetSettings.PatchManifestFileVersion) - throw new Exception($"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.PatchManifestFileVersion}"); - - PatchManifest manifest = new PatchManifest(); - { - // 读取文件头信息 - manifest.FileVersion = fileVersion; - manifest.EnableAddressable = buffer.ReadBool(); - manifest.OutputNameStyle = buffer.ReadInt32(); - manifest.PackageName = buffer.ReadUTF8(); - manifest.PackageVersion = buffer.ReadUTF8(); - - // 读取资源列表 - int patchAssetCount = buffer.ReadInt32(); - manifest.AssetList = new List(patchAssetCount); - for (int i = 0; i < patchAssetCount; i++) - { - var patchAsset = new PatchAsset(); - patchAsset.Address = buffer.ReadUTF8(); - patchAsset.AssetPath = buffer.ReadUTF8(); - patchAsset.AssetTags = buffer.ReadUTF8Array(); - patchAsset.BundleID = buffer.ReadInt32(); - patchAsset.DependIDs = buffer.ReadInt32Array(); - manifest.AssetList.Add(patchAsset); - } - - // 读取资源包列表 - int patchBundleCount = buffer.ReadInt32(); - manifest.BundleList = new List(patchBundleCount); - for (int i = 0; i < patchBundleCount; i++) - { - var patchBundle = new PatchBundle(); - patchBundle.BundleName = buffer.ReadUTF8(); - patchBundle.FileHash = buffer.ReadUTF8(); - patchBundle.FileCRC = buffer.ReadUTF8(); - patchBundle.FileSize = buffer.ReadInt64(); - patchBundle.IsRawFile = buffer.ReadBool(); - patchBundle.LoadMethod = buffer.ReadByte(); - patchBundle.Tags = buffer.ReadUTF8Array(); - manifest.BundleList.Add(patchBundle); - } - } - - // BundleDic - manifest.BundleDic = new Dictionary(manifest.BundleList.Count); - foreach (var patchBundle in manifest.BundleList) - { - patchBundle.ParseBundle(manifest.PackageName, manifest.OutputNameStyle); - manifest.BundleDic.Add(patchBundle.BundleName, patchBundle); - } - - // AssetDic - manifest.AssetDic = new Dictionary(manifest.AssetList.Count); - foreach (var patchAsset in manifest.AssetList) - { - // 注意:我们不允许原始路径存在重名 - string assetPath = patchAsset.AssetPath; - if (manifest.AssetDic.ContainsKey(assetPath)) - throw new Exception($"AssetPath have existed : {assetPath}"); - else - manifest.AssetDic.Add(assetPath, patchAsset); - } - - return manifest; - } - - /// - /// 生成Bundle文件的正式名称 - /// - public static string CreateBundleFileName(int nameStyle, string bundleName, string fileHash, bool isRawFile) - { - if (nameStyle == 1) //HashName - { - string fileExtension = isRawFile ? YooAssetSettingsData.Setting.RawFileVariant : YooAssetSettingsData.Setting.AssetBundleFileVariant; - return StringUtility.Format("{0}.{1}", fileHash, fileExtension); - } - else if (nameStyle == 4) //BundleName_HashName - { - string fileName = bundleName.Remove(bundleName.LastIndexOf('.')); - string fileExtension = isRawFile ? YooAssetSettingsData.Setting.RawFileVariant : YooAssetSettingsData.Setting.AssetBundleFileVariant; - return StringUtility.Format("{0}_{1}.{2}", fileName, fileHash, fileExtension); - } - else - { - throw new NotImplementedException($"Invalid name style : {nameStyle}"); - } - } - - /// - /// 获取解压BundleInfo - /// - public static BundleInfo GetUnpackInfo(PatchBundle patchBundle) - { - // 注意:我们把流加载路径指定为远端下载地址 - string streamingPath = PathHelper.ConvertToWWWPath(patchBundle.StreamingFilePath); - BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromStreaming, streamingPath, streamingPath); - return bundleInfo; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs deleted file mode 100644 index 72ff0ce..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal class EditorSimulateModeImpl : IPlayModeServices, IBundleServices - { - private PatchManifest _activeManifest; - private bool _locationToLower; - - /// - /// 异步初始化 - /// - public InitializationOperation InitializeAsync(bool locationToLower, string simulatePatchManifestPath) - { - _locationToLower = locationToLower; - var operation = new EditorSimulateModeInitializationOperation(this, simulatePatchManifestPath); - OperationSystem.StartOperation(operation); - return operation; - } - - #region IPlayModeServices接口 - public PatchManifest ActiveManifest - { - set - { - _activeManifest = value; - _activeManifest.InitAssetPathMapping(_locationToLower); - } - get - { - return _activeManifest; - } - } - public bool IsBuildinPatchBundle(PatchBundle patchBundle) - { - return true; - } - - UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) - { - var operation = new EditorPlayModeUpdatePackageVersionOperation(); - OperationSystem.StartOperation(operation); - return operation; - } - UpdatePackageManifestOperation IPlayModeServices.UpdatePackageManifestAsync(string packageVersion, int timeout) - { - var operation = new EditorPlayModeUpdatePackageManifestOperation(); - OperationSystem.StartOperation(operation); - return operation; - } - PreDownloadPackageOperation IPlayModeServices.PreDownloadPackageAsync(string packageVersion, int timeout) - { - var operation = new EditorPlayModePreDownloadPackageOperation(); - OperationSystem.StartOperation(operation); - return operation; - } - CheckPackageContentsOperation IPlayModeServices.CheckPackageContentsOperation(string packageVersion) - { - var operation = new EditorSimulateModeCheckPackageContentsOperation(); - OperationSystem.StartOperation(operation); - return operation; - } - - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) - { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); - } - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) - { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); - } - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) - { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); - } - - PatchUnpackerOperation IPlayModeServices.CreatePatchUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) - { - return PatchUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); - } - PatchUnpackerOperation IPlayModeServices.CreatePatchUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) - { - return PatchUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); - } - #endregion - - #region IBundleServices接口 - BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo) - { - if (assetInfo.IsInvalid) - throw new Exception("Should never get here !"); - - // 注意:如果补丁清单里未找到资源包会抛出异常! - var patchBundle = _activeManifest.GetMainPatchBundle(assetInfo.AssetPath); - BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromEditor, assetInfo.AssetPath); - return bundleInfo; - } - BundleInfo[] IBundleServices.GetAllDependBundleInfos(AssetInfo assetInfo) - { - throw new NotImplementedException(); - } - bool IBundleServices.IsServicesValid() - { - return _activeManifest != null; - } - #endregion - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs deleted file mode 100644 index 85f19fa..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs +++ /dev/null @@ -1,341 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal class HostPlayModeImpl : IPlayModeServices, IBundleServices, IRemoteServices - { - private PatchManifest _activeManifest; - - // 参数相关 - private string _packageName; - private bool _locationToLower; - private string _defaultHostServer; - private string _fallbackHostServer; - private IQueryServices _queryServices; - - /// - /// 异步初始化 - /// - public InitializationOperation InitializeAsync(string packageName, bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices) - { - _packageName = packageName; - _locationToLower = locationToLower; - _defaultHostServer = defaultHostServer; - _fallbackHostServer = fallbackHostServer; - _queryServices = queryServices; - - var operation = new HostPlayModeInitializationOperation(this, packageName); - OperationSystem.StartOperation(operation); - return operation; - } - - // 下载相关 - private List ConvertToDownloadList(List downloadList) - { - List result = new List(downloadList.Count); - foreach (var patchBundle in downloadList) - { - var bundleInfo = ConvertToDownloadInfo(patchBundle); - result.Add(bundleInfo); - } - return result; - } - private BundleInfo ConvertToDownloadInfo(PatchBundle patchBundle) - { - string remoteMainURL = GetRemoteMainURL(patchBundle.FileName); - string remoteFallbackURL = GetRemoteFallbackURL(patchBundle.FileName); - BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromRemote, remoteMainURL, remoteFallbackURL); - return bundleInfo; - } - - // 解压相关 - private List ConvertToUnpackList(List unpackList) - { - List result = new List(unpackList.Count); - foreach (var patchBundle in unpackList) - { - var bundleInfo = ConvertToUnpackInfo(patchBundle); - result.Add(bundleInfo); - } - return result; - } - private BundleInfo ConvertToUnpackInfo(PatchBundle patchBundle) - { - return PatchManifestTools.GetUnpackInfo(patchBundle); - } - - #region IRemoteServices接口 - public string GetRemoteMainURL(string fileName) - { - return $"{_defaultHostServer}/{fileName}"; - } - public string GetRemoteFallbackURL(string fileName) - { - return $"{_fallbackHostServer}/{fileName}"; - } - #endregion - - #region IPlayModeServices接口 - public PatchManifest ActiveManifest - { - set - { - _activeManifest = value; - _activeManifest.InitAssetPathMapping(_locationToLower); - PersistentHelper.SaveCachePackageVersionFile(_packageName, _activeManifest.PackageVersion); - } - get - { - return _activeManifest; - } - } - public bool IsBuildinPatchBundle(PatchBundle patchBundle) - { - return _queryServices.QueryStreamingAssets(patchBundle.FileName); - } - - UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) - { - var operation = new HostPlayModeUpdatePackageVersionOperation(this, _packageName, appendTimeTicks, timeout); - OperationSystem.StartOperation(operation); - return operation; - } - UpdatePackageManifestOperation IPlayModeServices.UpdatePackageManifestAsync(string packageVersion, int timeout) - { - var operation = new HostPlayModeUpdatePackageManifestOperation(this, _packageName, packageVersion, timeout); - OperationSystem.StartOperation(operation); - return operation; - } - PreDownloadPackageOperation IPlayModeServices.PreDownloadPackageAsync(string packageVersion, int timeout) - { - var operation = new HostPlayModePreDownloadPackageOperation(this, _packageName, packageVersion, timeout); - OperationSystem.StartOperation(operation); - return operation; - } - CheckPackageContentsOperation IPlayModeServices.CheckPackageContentsOperation(string packageVersion) - { - var operation = new HostPlayModeCheckPackageContentsOperation(this, _packageName, packageVersion); - OperationSystem.StartOperation(operation); - return operation; - } - - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) - { - List downloadList = GetDownloadListByAll(_activeManifest); - var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); - return operation; - } - public List GetDownloadListByAll(PatchManifest patchManifest) - { - List downloadList = new List(1000); - foreach (var patchBundle in patchManifest.BundleList) - { - // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPatchBundle(patchBundle)) - continue; - - downloadList.Add(patchBundle); - } - - return ConvertToDownloadList(downloadList); - } - - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) - { - List downloadList = GetDownloadListByTags(_activeManifest, tags); - var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); - return operation; - } - public List GetDownloadListByTags(PatchManifest patchManifest, string[] tags) - { - List downloadList = new List(1000); - foreach (var patchBundle in patchManifest.BundleList) - { - // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPatchBundle(patchBundle)) - continue; - - // 如果未带任何标记,则统一下载 - if (patchBundle.HasAnyTags() == false) - { - downloadList.Add(patchBundle); - } - else - { - // 查询DLC资源 - if (patchBundle.HasTag(tags)) - { - downloadList.Add(patchBundle); - } - } - } - - return ConvertToDownloadList(downloadList); - } - - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) - { - List downloadList = GetDownloadListByPaths(_activeManifest, assetInfos); - var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout); - return operation; - } - public List GetDownloadListByPaths(PatchManifest patchManifest, AssetInfo[] assetInfos) - { - // 获取资源对象的资源包和所有依赖资源包 - List checkList = new List(); - foreach (var assetInfo in assetInfos) - { - if (assetInfo.IsInvalid) - { - YooLogger.Warning(assetInfo.Error); - continue; - } - - // 注意:如果补丁清单里未找到资源包会抛出异常! - PatchBundle mainBundle = patchManifest.GetMainPatchBundle(assetInfo.AssetPath); - if (checkList.Contains(mainBundle) == false) - checkList.Add(mainBundle); - - // 注意:如果补丁清单里未找到资源包会抛出异常! - PatchBundle[] dependBundles = patchManifest.GetAllDependencies(assetInfo.AssetPath); - foreach (var dependBundle in dependBundles) - { - if (checkList.Contains(dependBundle) == false) - checkList.Add(dependBundle); - } - } - - List downloadList = new List(1000); - foreach (var patchBundle in checkList) - { - // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPatchBundle(patchBundle)) - continue; - - downloadList.Add(patchBundle); - } - - return ConvertToDownloadList(downloadList); - } - - PatchUnpackerOperation IPlayModeServices.CreatePatchUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) - { - List unpcakList = GetUnpackListByAll(_activeManifest); - var operation = new PatchUnpackerOperation(unpcakList, upackingMaxNumber, failedTryAgain, timeout); - return operation; - } - private List GetUnpackListByAll(PatchManifest patchManifest) - { - List downloadList = new List(1000); - foreach (var patchBundle in patchManifest.BundleList) - { - // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) - continue; - - if (IsBuildinPatchBundle(patchBundle)) - { - downloadList.Add(patchBundle); - } - } - - return ConvertToUnpackList(downloadList); - } - - PatchUnpackerOperation IPlayModeServices.CreatePatchUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) - { - List unpcakList = GetUnpackListByTags(_activeManifest, tags); - var operation = new PatchUnpackerOperation(unpcakList, upackingMaxNumber, failedTryAgain, timeout); - return operation; - } - private List GetUnpackListByTags(PatchManifest patchManifest, string[] tags) - { - List downloadList = new List(1000); - foreach (var patchBundle in patchManifest.BundleList) - { - // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) - continue; - - // 查询DLC资源 - if (IsBuildinPatchBundle(patchBundle)) - { - if (patchBundle.HasTag(tags)) - { - downloadList.Add(patchBundle); - } - } - } - - return ConvertToUnpackList(downloadList); - } - #endregion - - #region IBundleServices接口 - private BundleInfo CreateBundleInfo(PatchBundle patchBundle) - { - if (patchBundle == null) - throw new Exception("Should never get here !"); - - // 查询沙盒资源 - if (CacheSystem.IsCached(patchBundle)) - { - BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromCache); - return bundleInfo; - } - - // 查询APP资源 - if (IsBuildinPatchBundle(patchBundle)) - { - BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromStreaming); - return bundleInfo; - } - - // 从服务端下载 - return ConvertToDownloadInfo(patchBundle); - } - BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo) - { - if (assetInfo.IsInvalid) - throw new Exception("Should never get here !"); - - // 注意:如果补丁清单里未找到资源包会抛出异常! - var patchBundle = _activeManifest.GetMainPatchBundle(assetInfo.AssetPath); - return CreateBundleInfo(patchBundle); - } - BundleInfo[] IBundleServices.GetAllDependBundleInfos(AssetInfo assetInfo) - { - if (assetInfo.IsInvalid) - throw new Exception("Should never get here !"); - - // 注意:如果补丁清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); - List result = new List(depends.Length); - foreach (var patchBundle in depends) - { - BundleInfo bundleInfo = CreateBundleInfo(patchBundle); - result.Add(bundleInfo); - } - return result.ToArray(); - } - bool IBundleServices.IsServicesValid() - { - return _activeManifest != null; - } - #endregion - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs deleted file mode 100644 index c5a9a91..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal class OfflinePlayModeImpl : IPlayModeServices, IBundleServices - { - private PatchManifest _activeManifest; - private bool _locationToLower; - - /// - /// 异步初始化 - /// - public InitializationOperation InitializeAsync(string packageName, bool locationToLower) - { - _locationToLower = locationToLower; - var operation = new OfflinePlayModeInitializationOperation(this, packageName); - OperationSystem.StartOperation(operation); - return operation; - } - - #region IPlayModeServices接口 - public PatchManifest ActiveManifest - { - set - { - _activeManifest = value; - _activeManifest.InitAssetPathMapping(_locationToLower); - } - get - { - return _activeManifest; - } - } - public bool IsBuildinPatchBundle(PatchBundle patchBundle) - { - return true; - } - - UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) - { - var operation = new OfflinePlayModeUpdatePackageVersionOperation(); - OperationSystem.StartOperation(operation); - return operation; - } - UpdatePackageManifestOperation IPlayModeServices.UpdatePackageManifestAsync(string packageVersion, int timeout) - { - var operation = new OfflinePlayModeUpdatePackageManifestOperation(); - OperationSystem.StartOperation(operation); - return operation; - } - PreDownloadPackageOperation IPlayModeServices.PreDownloadPackageAsync(string packageVersion, int timeout) - { - var operation = new OfflinePlayModePreDownloadPackageOperation(); - OperationSystem.StartOperation(operation); - return operation; - } - CheckPackageContentsOperation IPlayModeServices.CheckPackageContentsOperation(string packageVersion) - { - var operation = new OfflinePlayModeCheckPackageContentsOperation(); - OperationSystem.StartOperation(operation); - return operation; - } - - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) - { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); - } - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) - { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); - } - PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) - { - return PatchDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); - } - - PatchUnpackerOperation IPlayModeServices.CreatePatchUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) - { - return PatchUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); - } - PatchUnpackerOperation IPlayModeServices.CreatePatchUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) - { - return PatchUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); - } - #endregion - - #region IBundleServices接口 - private BundleInfo CreateBundleInfo(PatchBundle patchBundle) - { - if (patchBundle == null) - throw new Exception("Should never get here !"); - - // 查询沙盒资源 - if (CacheSystem.IsCached(patchBundle)) - { - BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromCache); - return bundleInfo; - } - - // 查询APP资源 - { - BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromStreaming); - return bundleInfo; - } - } - BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo) - { - if (assetInfo.IsInvalid) - throw new Exception("Should never get here !"); - - // 注意:如果补丁清单里未找到资源包会抛出异常! - var patchBundle = _activeManifest.GetMainPatchBundle(assetInfo.AssetPath); - return CreateBundleInfo(patchBundle); - } - BundleInfo[] IBundleServices.GetAllDependBundleInfos(AssetInfo assetInfo) - { - if (assetInfo.IsInvalid) - throw new Exception("Should never get here !"); - - // 注意:如果补丁清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); - List result = new List(depends.Length); - foreach (var patchBundle in depends) - { - BundleInfo bundleInfo = CreateBundleInfo(patchBundle); - result.Add(bundleInfo); - } - return result.ToArray(); - } - bool IBundleServices.IsServicesValid() - { - return _activeManifest != null; - } - #endregion - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Properties/AssemblyInfo.cs b/Assets/YooAsset/Runtime/Properties/AssemblyInfo.cs index fd67af8..47e196b 100644 --- a/Assets/YooAsset/Runtime/Properties/AssemblyInfo.cs +++ b/Assets/YooAsset/Runtime/Properties/AssemblyInfo.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("YooAsset.Editor")] +[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")] [assembly: InternalsVisibleTo("YooAsset.EditorExtension")] [assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")] \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetsPackage.cs b/Assets/YooAsset/Runtime/ResourcePackage.cs similarity index 78% rename from Assets/YooAsset/Runtime/AssetsPackage.cs rename to Assets/YooAsset/Runtime/ResourcePackage.cs index a25b032..3fd3df1 100644 --- a/Assets/YooAsset/Runtime/AssetsPackage.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage.cs @@ -6,7 +6,7 @@ using UnityEngine.SceneManagement; namespace YooAsset { - public class AssetsPackage + public class ResourcePackage { private bool _isInitialize = false; private string _initializeError = string.Empty; @@ -30,10 +30,10 @@ namespace YooAsset } - private AssetsPackage() + private ResourcePackage() { } - internal AssetsPackage(string packageName) + internal ResourcePackage(string packageName) { PackageName = packageName; } @@ -87,17 +87,21 @@ namespace YooAsset var editorSimulateModeImpl = new EditorSimulateModeImpl(); _bundleServices = editorSimulateModeImpl; _playModeServices = editorSimulateModeImpl; - _assetSystemImpl.Initialize(PackageName, true, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices); + _assetSystemImpl.Initialize(PackageName, true, + parameters.LoadingMaxTimeSlice, parameters.DownloadFailedTryAgain, + parameters.DecryptionServices, _bundleServices); var initializeParameters = parameters as EditorSimulateModeParameters; - initializeOperation = editorSimulateModeImpl.InitializeAsync(initializeParameters.LocationToLower, initializeParameters.SimulatePatchManifestPath); + initializeOperation = editorSimulateModeImpl.InitializeAsync(initializeParameters.LocationToLower, initializeParameters.SimulateManifestFilePath); } else if (_playMode == EPlayMode.OfflinePlayMode) { var offlinePlayModeImpl = new OfflinePlayModeImpl(); _bundleServices = offlinePlayModeImpl; _playModeServices = offlinePlayModeImpl; - _assetSystemImpl.Initialize(PackageName, false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices); + _assetSystemImpl.Initialize(PackageName, false, + parameters.LoadingMaxTimeSlice, parameters.DownloadFailedTryAgain, + parameters.DecryptionServices, _bundleServices); var initializeParameters = parameters as OfflinePlayModeParameters; initializeOperation = offlinePlayModeImpl.InitializeAsync(PackageName, initializeParameters.LocationToLower); @@ -107,7 +111,9 @@ namespace YooAsset var hostPlayModeImpl = new HostPlayModeImpl(); _bundleServices = hostPlayModeImpl; _playModeServices = hostPlayModeImpl; - _assetSystemImpl.Initialize(PackageName, false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices); + _assetSystemImpl.Initialize(PackageName, false, + parameters.LoadingMaxTimeSlice, parameters.DownloadFailedTryAgain, + parameters.DecryptionServices, _bundleServices); var initializeParameters = parameters as HostPlayModeParameters; initializeOperation = hostPlayModeImpl.InitializeAsync( @@ -143,10 +149,10 @@ namespace YooAsset private void CheckInitializeParameters(InitializeParameters parameters) { if (_isInitialize) - throw new Exception($"{nameof(AssetsPackage)} is initialized yet."); + throw new Exception($"{nameof(ResourcePackage)} is initialized yet."); if (parameters == null) - throw new Exception($"{nameof(AssetsPackage)} create parameters is null."); + throw new Exception($"{nameof(ResourcePackage)} create parameters is null."); #if !UNITY_EDITOR if (parameters is EditorSimulateModeParameters) @@ -156,8 +162,8 @@ namespace YooAsset if (parameters is EditorSimulateModeParameters) { var editorSimulateModeParameters = parameters as EditorSimulateModeParameters; - if (string.IsNullOrEmpty(editorSimulateModeParameters.SimulatePatchManifestPath)) - throw new Exception($"{nameof(editorSimulateModeParameters.SimulatePatchManifestPath)} is null or empty."); + if (string.IsNullOrEmpty(editorSimulateModeParameters.SimulateManifestFilePath)) + throw new Exception($"{nameof(editorSimulateModeParameters.SimulateManifestFilePath)} is null or empty."); } if (parameters is HostPlayModeParameters) @@ -182,10 +188,15 @@ namespace YooAsset throw new NotImplementedException(); // 检测参数范围 - if (parameters.AssetLoadingMaxNumber < 1) + if (parameters.LoadingMaxTimeSlice < 10) { - parameters.AssetLoadingMaxNumber = 1; - YooLogger.Warning($"{nameof(parameters.AssetLoadingMaxNumber)} minimum value is 1"); + parameters.LoadingMaxTimeSlice = 10; + YooLogger.Warning($"{nameof(parameters.LoadingMaxTimeSlice)} minimum value is 10 milliseconds."); + } + if (parameters.DownloadFailedTryAgain < 1) + { + parameters.DownloadFailedTryAgain = 1; + YooLogger.Warning($"{nameof(parameters.DownloadFailedTryAgain)} minimum value is 1"); } } private void InitializeOperation_Completed(AsyncOperationBase op) @@ -206,7 +217,7 @@ namespace YooAsset } /// - /// 向网络端请求并更新补丁清单 + /// 向网络端请求并更新清单 /// /// 更新的包裹版本 /// 自动激活清单 @@ -223,19 +234,10 @@ namespace YooAsset /// /// 下载的包裹版本 /// 超时时间(默认值:60秒) - public PreDownloadPackageOperation PreDownloadPackageAsync(string packageVersion, int timeout = 60) + public PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout = 60) { DebugCheckInitialize(); - return _playModeServices.PreDownloadPackageAsync(packageVersion, timeout); - } - - /// - /// 检查包裹内容的完整性 - /// - public CheckPackageContentsOperation CheckPackageContentsAsync(string packageVersion) - { - DebugCheckInitialize(); - return _playModeServices.CheckPackageContentsOperation(packageVersion); + return _playModeServices.PreDownloadContentAsync(packageVersion, timeout); } /// @@ -639,91 +641,139 @@ namespace YooAsset #region 资源下载 /// - /// 创建补丁下载器,用于下载更新资源标签指定的资源包文件 + /// 创建资源下载器,用于下载当前资源版本所有的资源包文件 + /// + /// 同时下载的最大文件数 + /// 下载失败的重试次数 + /// 超时时间 + public ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + DebugCheckInitialize(); + return _playModeServices.CreateResourceDownloaderByAll(downloadingMaxNumber, failedTryAgain, timeout); + } + + /// + /// 创建资源下载器,用于下载指定的资源标签关联的资源包文件 /// /// 资源标签 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public PatchDownloaderOperation CreatePatchDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { DebugCheckInitialize(); - return _playModeServices.CreatePatchDownloaderByTags(new string[] { tag }, downloadingMaxNumber, failedTryAgain, timeout); + return _playModeServices.CreateResourceDownloaderByTags(new string[] { tag }, downloadingMaxNumber, failedTryAgain, timeout); } /// - /// 创建补丁下载器,用于下载更新资源标签指定的资源包文件 + /// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件 /// /// 资源标签列表 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public PatchDownloaderOperation CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { DebugCheckInitialize(); - return _playModeServices.CreatePatchDownloaderByTags(tags, downloadingMaxNumber, failedTryAgain, timeout); + return _playModeServices.CreateResourceDownloaderByTags(tags, downloadingMaxNumber, failedTryAgain, timeout); } /// - /// 创建补丁下载器,用于下载更新当前资源版本所有的资源包文件 + /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 /// + /// 资源的定位地址 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public PatchDownloaderOperation CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { DebugCheckInitialize(); - return _playModeServices.CreatePatchDownloaderByAll(downloadingMaxNumber, failedTryAgain, timeout); + var assetInfo = ConvertLocationToAssetInfo(location, null); + AssetInfo[] assetInfos = new AssetInfo[] { assetInfo }; + return _playModeServices.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout); } /// - /// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件 + /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 + /// + /// 资源的定位地址列表 + /// 同时下载的最大文件数 + /// 下载失败的重试次数 + /// 超时时间 + public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + DebugCheckInitialize(); + List assetInfos = new List(locations.Length); + foreach (var location in locations) + { + var assetInfo = ConvertLocationToAssetInfo(location, null); + assetInfos.Add(assetInfo); + } + return _playModeServices.CreateResourceDownloaderByPaths(assetInfos.ToArray(), downloadingMaxNumber, failedTryAgain, timeout); + } + + /// + /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 + /// + /// 资源信息 + /// 同时下载的最大文件数 + /// 下载失败的重试次数 + /// 超时时间 + public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + DebugCheckInitialize(); + AssetInfo[] assetInfos = new AssetInfo[] { assetInfo }; + return _playModeServices.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout); + } + + /// + /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 /// /// 资源信息列表 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public PatchDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { DebugCheckInitialize(); - return _playModeServices.CreatePatchDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout); + return _playModeServices.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout); } #endregion #region 资源解压 /// - /// 创建补丁解压器 + /// 创建内置资源解压器 /// /// 资源标签 /// 同时解压的最大文件数 /// 解压失败的重试次数 - public PatchUnpackerOperation CreatePatchUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain) + public ResourceUnpackerOperation CreateResourceUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain) { DebugCheckInitialize(); - return _playModeServices.CreatePatchUnpackerByTags(new string[] { tag }, unpackingMaxNumber, failedTryAgain, int.MaxValue); + return _playModeServices.CreateResourceUnpackerByTags(new string[] { tag }, unpackingMaxNumber, failedTryAgain, int.MaxValue); } /// - /// 创建补丁解压器 + /// 创建内置资源解压器 /// /// 资源标签列表 /// 同时解压的最大文件数 /// 解压失败的重试次数 - public PatchUnpackerOperation CreatePatchUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain) + public ResourceUnpackerOperation CreateResourceUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain) { DebugCheckInitialize(); - return _playModeServices.CreatePatchUnpackerByTags(tags, unpackingMaxNumber, failedTryAgain, int.MaxValue); + return _playModeServices.CreateResourceUnpackerByTags(tags, unpackingMaxNumber, failedTryAgain, int.MaxValue); } /// - /// 创建补丁解压器 + /// 创建内置资源解压器 /// /// 同时解压的最大文件数 /// 解压失败的重试次数 - public PatchUnpackerOperation CreatePatchUnpacker(int unpackingMaxNumber, int failedTryAgain) + public ResourceUnpackerOperation CreateResourceUnpacker(int unpackingMaxNumber, int failedTryAgain) { DebugCheckInitialize(); - return _playModeServices.CreatePatchUnpackerByAll(unpackingMaxNumber, failedTryAgain, int.MaxValue); + return _playModeServices.CreateResourceUnpackerByAll(unpackingMaxNumber, failedTryAgain, int.MaxValue); } #endregion @@ -731,12 +781,12 @@ namespace YooAsset /// /// 是否包含资源文件 /// - internal bool IsIncludeBundleFile(string fileName) + internal bool IsIncludeBundleFile(string cacheGUID) { // NOTE : 编辑器模拟模式下始终返回TRUE if (_playMode == EPlayMode.EditorSimulateMode) return true; - return _playModeServices.ActiveManifest.IsIncludeBundleFile(fileName); + return _playModeServices.ActiveManifest.IsIncludeBundleFile(cacheGUID); } /// diff --git a/Assets/YooAsset/Runtime/AssetsPackage.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/AssetsPackage.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage.cs.meta diff --git a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs b/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs index 11ea5b0..52e8fd9 100644 --- a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs +++ b/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs @@ -32,7 +32,7 @@ namespace YooAsset /// /// 文件流解密方法 /// - System.IO.FileStream LoadFromStream(DecryptFileInfo fileInfo); + System.IO.Stream LoadFromStream(DecryptFileInfo fileInfo); /// /// 文件流解密的托管缓存大小 diff --git a/Assets/YooAsset/Runtime/Services/IPlayModeServices.cs b/Assets/YooAsset/Runtime/Services/IPlayModeServices.cs deleted file mode 100644 index 9a73a21..0000000 --- a/Assets/YooAsset/Runtime/Services/IPlayModeServices.cs +++ /dev/null @@ -1,45 +0,0 @@ - -namespace YooAsset -{ - internal interface IPlayModeServices - { - /// - /// 激活的清单 - /// - PatchManifest ActiveManifest { set; get; } - - /// - /// 是否为内置资源文件 - /// - bool IsBuildinPatchBundle(PatchBundle patchBundle); - - /// - /// 向网络端请求最新的资源版本 - /// - UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks, int timeout); - - /// - /// 向网络端请求并更新补丁清单 - /// - UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout); - - /// - /// 预下载指定版本的包裹资源 - /// - PreDownloadPackageOperation PreDownloadPackageAsync(string packageVersion, int timeout); - - /// - /// 检查包裹内容的完整性 - /// - CheckPackageContentsOperation CheckPackageContentsOperation(string packageVersion); - - // 下载相关 - PatchDownloaderOperation CreatePatchDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout); - PatchDownloaderOperation CreatePatchDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout); - PatchDownloaderOperation CreatePatchDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout); - - // 解压相关 - PatchUnpackerOperation CreatePatchUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout); - PatchUnpackerOperation CreatePatchUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/LICENSE.md.meta b/Assets/YooAsset/Runtime/Services/Internal.meta similarity index 67% rename from Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/LICENSE.md.meta rename to Assets/YooAsset/Runtime/Services/Internal.meta index 1be7bc7..79cd3b3 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/LICENSE.md.meta +++ b/Assets/YooAsset/Runtime/Services/Internal.meta @@ -1,5 +1,6 @@ fileFormatVersion: 2 -guid: f3d9e435137e34d34a54f181bf3dc7c2 +guid: 40c870edb8e84064a8be2d56acb8bbc0 +folderAsset: yes DefaultImporter: externalObjects: {} userData: diff --git a/Assets/YooAsset/Runtime/Services/IBundleServices.cs b/Assets/YooAsset/Runtime/Services/Internal/IBundleServices.cs similarity index 80% rename from Assets/YooAsset/Runtime/Services/IBundleServices.cs rename to Assets/YooAsset/Runtime/Services/Internal/IBundleServices.cs index 253a014..75c8620 100644 --- a/Assets/YooAsset/Runtime/Services/IBundleServices.cs +++ b/Assets/YooAsset/Runtime/Services/Internal/IBundleServices.cs @@ -13,6 +13,11 @@ namespace YooAsset /// BundleInfo[] GetAllDependBundleInfos(AssetInfo assetPath); + /// + /// 获取资源包名称 + /// + string GetBundleName(int bundleID); + /// /// 服务接口是否有效 /// diff --git a/Assets/YooAsset/Runtime/Services/IBundleServices.cs.meta b/Assets/YooAsset/Runtime/Services/Internal/IBundleServices.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/Services/IBundleServices.cs.meta rename to Assets/YooAsset/Runtime/Services/Internal/IBundleServices.cs.meta diff --git a/Assets/YooAsset/Runtime/Services/Internal/IPlayModeServices.cs b/Assets/YooAsset/Runtime/Services/Internal/IPlayModeServices.cs new file mode 100644 index 0000000..834e0bc --- /dev/null +++ b/Assets/YooAsset/Runtime/Services/Internal/IPlayModeServices.cs @@ -0,0 +1,40 @@ + +namespace YooAsset +{ + internal interface IPlayModeServices + { + /// + /// 激活的清单 + /// + PackageManifest ActiveManifest { set; get; } + + /// + /// 保存清单版本文件到沙盒 + /// + void FlushManifestVersionFile(); + + /// + /// 向网络端请求最新的资源版本 + /// + UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks, int timeout); + + /// + /// 向网络端请求并更新清单 + /// + UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout); + + /// + /// 预下载指定版本的包裹内容 + /// + PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout); + + // 下载相关 + ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout); + ResourceDownloaderOperation CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout); + ResourceDownloaderOperation CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout); + + // 解压相关 + ResourceUnpackerOperation CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout); + ResourceUnpackerOperation CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Services/IPlayModeServices.cs.meta b/Assets/YooAsset/Runtime/Services/Internal/IPlayModeServices.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/Services/IPlayModeServices.cs.meta rename to Assets/YooAsset/Runtime/Services/Internal/IPlayModeServices.cs.meta diff --git a/Assets/YooAsset/Runtime/Services/IRemoteServices.cs b/Assets/YooAsset/Runtime/Services/Internal/IRemoteServices.cs similarity index 100% rename from Assets/YooAsset/Runtime/Services/IRemoteServices.cs rename to Assets/YooAsset/Runtime/Services/Internal/IRemoteServices.cs diff --git a/Assets/YooAsset/Runtime/Services/IRemoteServices.cs.meta b/Assets/YooAsset/Runtime/Services/Internal/IRemoteServices.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/Services/IRemoteServices.cs.meta rename to Assets/YooAsset/Runtime/Services/Internal/IRemoteServices.cs.meta diff --git a/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs b/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs index 237f1d0..8696b05 100644 --- a/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs +++ b/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs @@ -5,41 +5,37 @@ namespace YooAsset [CreateAssetMenu(fileName = "YooAssetSettings", menuName = "YooAsset/Create Settings")] internal class YooAssetSettings : ScriptableObject { - /// - /// AssetBundle文件的后缀名 - /// - public string AssetBundleFileVariant = "bundle"; - - /// - /// 原生文件的后缀名 - /// - public string RawFileVariant = "rawfile"; - /// /// 清单文件名称 /// - public string PatchManifestFileName = "PatchManifest"; - - /// - /// 资源包名正规化(移除路径分隔符) - /// - public bool RegularBundleName = true; + public string ManifestFileName = "PackageManifest"; /// /// 清单文件头标记 /// - public const uint PatchManifestFileSign = 0x594F4F; + public const uint ManifestFileSign = 0x594F4F; /// /// 清单文件极限大小(100MB) /// - public const int PatchManifestFileMaxSize = 104857600; + public const int ManifestFileMaxSize = 104857600; /// /// 清单文件格式版本 /// - public const string PatchManifestFileVersion = "1.4.0"; + public const string ManifestFileVersion = "1.4.6"; + + + /// + /// 缓存的数据文件名称 + /// + public const string CacheBundleDataFileName = "__data"; + + /// + /// 缓存的信息文件名称 + /// + public const string CacheBundleInfoFileName = "__info"; /// @@ -52,20 +48,9 @@ namespace YooAsset /// public const string ReportFileName = "BuildReport"; - /// - /// Unity着色器资源包名称 - /// - public const string UnityShadersBundleName = "unityshaders"; - /// /// 内置资源目录名称 /// public const string StreamingAssetsBuildinFolder = "BuildinFiles"; - - - /// - /// 忽略的文件类型 - /// - public static readonly string[] IgnoreFileExtensions = { "", ".so", ".dll", ".cs", ".js", ".boo", ".meta", ".cginc" }; } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs b/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs index 05cbf2a..16ac6b8 100644 --- a/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs +++ b/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs @@ -45,7 +45,7 @@ namespace YooAsset /// public static string GetManifestBinaryFileName(string packageName, string packageVersion) { - return $"{Setting.PatchManifestFileName}_{packageName}_{packageVersion}.bytes"; + return $"{Setting.ManifestFileName}_{packageName}_{packageVersion}.bytes"; } /// @@ -53,7 +53,7 @@ namespace YooAsset /// public static string GetManifestJsonFileName(string packageName, string packageVersion) { - return $"{Setting.PatchManifestFileName}_{packageName}_{packageVersion}.json"; + return $"{Setting.ManifestFileName}_{packageName}_{packageVersion}.json"; } /// @@ -61,7 +61,7 @@ namespace YooAsset /// public static string GetPackageHashFileName(string packageName, string packageVersion) { - return $"{Setting.PatchManifestFileName}_{packageName}_{packageVersion}.hash"; + return $"{Setting.ManifestFileName}_{packageName}_{packageVersion}.hash"; } /// @@ -69,20 +69,7 @@ namespace YooAsset /// public static string GetPackageVersionFileName(string packageName) { - return $"{Setting.PatchManifestFileName}_{packageName}.version"; - } - - /// - /// 获取着色器资源包全名称(包含后缀名) - /// - public static string GetUnityShadersBundleFullName(bool uniqueBundleName, string packageName) - { - string shareBundleName; - if (uniqueBundleName) - shareBundleName = $"{packageName.ToLower()}_{YooAssetSettings.UnityShadersBundleName}.{Setting.AssetBundleFileVariant}"; - else - shareBundleName = $"{YooAssetSettings.UnityShadersBundleName}.{Setting.AssetBundleFileVariant}"; - return shareBundleName.ToLower(); + return $"{Setting.ManifestFileName}_{packageName}.version"; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/BufferWriter.cs b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs index 225939e..940b438 100644 --- a/Assets/YooAsset/Runtime/Utility/BufferWriter.cs +++ b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs @@ -28,6 +28,14 @@ namespace YooAsset get { return _buffer.Length; } } + /// + /// 清空缓冲区 + /// + public void Clear() + { + _index = 0; + } + /// /// 将有效数据写入文件流 /// diff --git a/Assets/YooAsset/Runtime/Utility/YooHelper.cs b/Assets/YooAsset/Runtime/Utility/YooHelper.cs index a8e4835..25a03d2 100644 --- a/Assets/YooAsset/Runtime/Utility/YooHelper.cs +++ b/Assets/YooAsset/Runtime/Utility/YooHelper.cs @@ -84,6 +84,8 @@ namespace YooAsset internal static class PersistentHelper { private const string CacheFolderName = "CacheFiles"; + private const string CachedBundleFileFolder = "BundleFiles"; + private const string CachedRawFileFolder = "RawFiles"; private const string ManifestFolderName = "ManifestFiles"; private const string AppFootPrintFileName = "ApplicationFootPrint.bytes"; @@ -120,12 +122,33 @@ namespace YooAsset /// - /// 获取缓存文件夹路径 + /// 获取缓存的BundleFile文件夹路径 /// - public static string GetCacheFolderPath(string packageName) + private readonly static Dictionary _cachedBundleFileFolder = new Dictionary(100); + public static string GetCachedBundleFileFolderPath(string packageName) { - string root = PathHelper.MakePersistentLoadPath(CacheFolderName); - return $"{root}/{packageName}"; + if (_cachedBundleFileFolder.TryGetValue(packageName, out string value) == false) + { + string root = PathHelper.MakePersistentLoadPath(CacheFolderName); + value = $"{root}/{packageName}/{CachedBundleFileFolder}"; + _cachedBundleFileFolder.Add(packageName, value); + } + return value; + } + + /// + /// 获取缓存的RawFile文件夹路径 + /// + private readonly static Dictionary _cachedRawFileFolder = new Dictionary(100); + public static string GetCachedRawFileFolderPath(string packageName) + { + if (_cachedRawFileFolder.TryGetValue(packageName, out string value) == false) + { + string root = PathHelper.MakePersistentLoadPath(CacheFolderName); + value = $"{root}/{packageName}/{CachedRawFileFolder}"; + _cachedRawFileFolder.Add(packageName, value); + } + return value; } /// diff --git a/Assets/YooAsset/Runtime/Utility/YooLogger.cs b/Assets/YooAsset/Runtime/Utility/YooLogger.cs index c148a85..5962e95 100644 --- a/Assets/YooAsset/Runtime/Utility/YooLogger.cs +++ b/Assets/YooAsset/Runtime/Utility/YooLogger.cs @@ -2,15 +2,35 @@ namespace YooAsset { + /// + /// 自定义日志处理 + /// + public interface ILogger + { + void Log(string message); + void Warning(string message); + void Error(string message); + void Exception(System.Exception exception); + } + internal static class YooLogger { + public static ILogger Logger = null; + /// /// 日志 /// [Conditional("DEBUG")] public static void Log(string info) { - UnityEngine.Debug.Log(info); + if (Logger != null) + { + Logger.Log(info); + } + else + { + UnityEngine.Debug.Log(info); + } } /// @@ -18,7 +38,14 @@ namespace YooAsset /// public static void Warning(string info) { - UnityEngine.Debug.LogWarning(info); + if (Logger != null) + { + Logger.Warning(info); + } + else + { + UnityEngine.Debug.LogWarning(info); + } } /// @@ -26,7 +53,14 @@ namespace YooAsset /// public static void Error(string info) { - UnityEngine.Debug.LogError(info); + if (Logger != null) + { + Logger.Error(info); + } + else + { + UnityEngine.Debug.LogError(info); + } } /// @@ -34,7 +68,14 @@ namespace YooAsset /// public static void Exception(System.Exception exception) { - UnityEngine.Debug.LogException(exception); + if (Logger != null) + { + Logger.Exception(exception); + } + else + { + UnityEngine.Debug.LogException(exception); + } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/YooAssets.cs b/Assets/YooAsset/Runtime/YooAssets.cs index 4fce4f6..63d7819 100644 --- a/Assets/YooAsset/Runtime/YooAssets.cs +++ b/Assets/YooAsset/Runtime/YooAssets.cs @@ -10,18 +10,21 @@ namespace YooAsset { private static bool _isInitialize = false; private static GameObject _driver = null; - private static readonly List _packages = new List(); + private static readonly List _packages = new List(); /// /// 初始化资源系统 /// - public static void Initialize() + /// 自定义日志处理 + public static void Initialize(ILogger logger = null) { if (_isInitialize) throw new Exception($"{nameof(YooAssets)} is initialized !"); if (_isInitialize == false) { + YooLogger.Logger = logger; + // 创建驱动器 _isInitialize = true; _driver = new UnityEngine.GameObject($"[{nameof(YooAssets)}]"); @@ -34,8 +37,8 @@ namespace YooAsset _driver.AddComponent(); #endif - // 初始化异步系统 OperationSystem.Initialize(); + DownloadSystem.Initialize(); } } @@ -85,7 +88,7 @@ namespace YooAsset /// 创建资源包 /// /// 资源包名称 - public static AssetsPackage CreateAssetsPackage(string packageName) + public static ResourcePackage CreatePackage(string packageName) { if (_isInitialize == false) throw new Exception($"{nameof(YooAssets)} not initialize !"); @@ -93,23 +96,23 @@ namespace YooAsset if (string.IsNullOrEmpty(packageName)) throw new Exception("Package name is null or empty !"); - if (HasAssetsPackage(packageName)) + if (HasPackage(packageName)) throw new Exception($"Package {packageName} already existed !"); - AssetsPackage assetsPackage = new AssetsPackage(packageName); - _packages.Add(assetsPackage); - return assetsPackage; + ResourcePackage package = new ResourcePackage(packageName); + _packages.Add(package); + return package; } /// /// 获取资源包 /// /// 资源包名称 - public static AssetsPackage GetAssetsPackage(string packageName) + public static ResourcePackage GetPackage(string packageName) { - var package = TryGetAssetsPackage(packageName); + var package = TryGetPackage(packageName); if (package == null) - YooLogger.Warning($"Not found assets package : {packageName}"); + YooLogger.Error($"Not found assets package : {packageName}"); return package; } @@ -117,7 +120,7 @@ namespace YooAsset /// 尝试获取资源包 /// /// 资源包名称 - public static AssetsPackage TryGetAssetsPackage(string packageName) + public static ResourcePackage TryGetPackage(string packageName) { if (_isInitialize == false) throw new Exception($"{nameof(YooAssets)} not initialize !"); @@ -137,7 +140,7 @@ namespace YooAsset /// 检测资源包是否存在 /// /// 资源包名称 - public static bool HasAssetsPackage(string packageName) + public static bool HasPackage(string packageName) { if (_isInitialize == false) throw new Exception($"{nameof(YooAssets)} not initialize !"); @@ -184,15 +187,23 @@ namespace YooAsset DownloadSystem.CertificateHandlerInstance = instance; } + /// + /// 设置下载系统参数,自定义下载请求 + /// + public static void SetDownloadSystemUnityWebRequest(DownloadRequestDelegate requestDelegate) + { + DownloadSystem.RequestDelegate = requestDelegate; + } + /// /// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒) /// public static void SetOperationSystemMaxTimeSlice(long milliseconds) { - if (milliseconds < 30) + if (milliseconds < 10) { - milliseconds = 30; - YooLogger.Warning($"MaxTimeSlice minimum value is 30 milliseconds."); + milliseconds = 10; + YooLogger.Warning($"MaxTimeSlice minimum value is 10 milliseconds."); } OperationSystem.MaxTimeSlice = milliseconds; } diff --git a/Assets/YooAsset/Runtime/YooAssetsExtension.cs b/Assets/YooAsset/Runtime/YooAssetsExtension.cs index c4b2fd0..1e0220b 100644 --- a/Assets/YooAsset/Runtime/YooAssetsExtension.cs +++ b/Assets/YooAsset/Runtime/YooAssetsExtension.cs @@ -8,14 +8,14 @@ namespace YooAsset { public static partial class YooAssets { - private static AssetsPackage _defaultPackage; + private static ResourcePackage _defaultPackage; /// /// 设置默认的资源包 /// - public static void SetDefaultAssetsPackage(AssetsPackage assetsPackage) + public static void SetDefaultPackage(ResourcePackage package) { - _defaultPackage = assetsPackage; + _defaultPackage = package; } #region 资源信息 @@ -286,47 +286,83 @@ namespace YooAsset #region 资源下载 /// - /// 创建补丁下载器,用于下载更新资源标签指定的资源包文件 + /// 创建资源下载器,用于下载当前资源版本所有的资源包文件 + /// + /// 同时下载的最大文件数 + /// 下载失败的重试次数 + public static ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain) + { + DebugCheckDefaultPackageValid(); + return _defaultPackage.CreateResourceDownloader(downloadingMaxNumber, failedTryAgain); + } + + /// + /// 创建资源下载器,用于下载指定的资源标签关联的资源包文件 /// /// 资源标签 /// 同时下载的最大文件数 /// 下载失败的重试次数 - public static PatchDownloaderOperation CreatePatchDownloader(string tag, int downloadingMaxNumber, int failedTryAgain) + public static ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain) { DebugCheckDefaultPackageValid(); - return _defaultPackage.CreatePatchDownloader(new string[] { tag }, downloadingMaxNumber, failedTryAgain); + return _defaultPackage.CreateResourceDownloader(new string[] { tag }, downloadingMaxNumber, failedTryAgain); } /// - /// 创建补丁下载器,用于下载更新资源标签指定的资源包文件 + /// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件 /// /// 资源标签列表 /// 同时下载的最大文件数 /// 下载失败的重试次数 - public static PatchDownloaderOperation CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain) + public static ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain) { DebugCheckDefaultPackageValid(); - return _defaultPackage.CreatePatchDownloader(tags, downloadingMaxNumber, failedTryAgain); + return _defaultPackage.CreateResourceDownloader(tags, downloadingMaxNumber, failedTryAgain); } /// - /// 创建补丁下载器,用于下载更新当前资源版本所有的资源包文件 + /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 /// + /// 资源定位地址 /// 同时下载的最大文件数 /// 下载失败的重试次数 - public static PatchDownloaderOperation CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain) + public static ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain) { DebugCheckDefaultPackageValid(); - return _defaultPackage.CreatePatchDownloader(downloadingMaxNumber, failedTryAgain); + return _defaultPackage.CreateBundleDownloader(location, downloadingMaxNumber, failedTryAgain); } /// - /// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件 + /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 + /// + /// 资源定位地址列表 + /// 同时下载的最大文件数 + /// 下载失败的重试次数 + public static ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain) + { + DebugCheckDefaultPackageValid(); + return _defaultPackage.CreateBundleDownloader(locations, downloadingMaxNumber, failedTryAgain); + } + + /// + /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 + /// + /// 资源信息 + /// 同时下载的最大文件数 + /// 下载失败的重试次数 + public static ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain) + { + DebugCheckDefaultPackageValid(); + return _defaultPackage.CreateBundleDownloader(assetInfo, downloadingMaxNumber, failedTryAgain); + } + + /// + /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 /// /// 资源信息列表 /// 同时下载的最大文件数 /// 下载失败的重试次数 - public static PatchDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain) + public static ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain) { DebugCheckDefaultPackageValid(); return _defaultPackage.CreateBundleDownloader(assetInfos, downloadingMaxNumber, failedTryAgain); @@ -335,38 +371,38 @@ namespace YooAsset #region 资源解压 /// - /// 创建补丁解压器 + /// 创建内置资源解压器 /// /// 资源标签 /// 同时解压的最大文件数 /// 解压失败的重试次数 - public static PatchUnpackerOperation CreatePatchUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain) + public static ResourceUnpackerOperation CreateResourceUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain) { DebugCheckDefaultPackageValid(); - return _defaultPackage.CreatePatchUnpacker(tag, unpackingMaxNumber, failedTryAgain); + return _defaultPackage.CreateResourceUnpacker(tag, unpackingMaxNumber, failedTryAgain); } /// - /// 创建补丁解压器 + /// 创建内置资源解压器 /// /// 资源标签列表 /// 同时解压的最大文件数 /// 解压失败的重试次数 - public static PatchUnpackerOperation CreatePatchUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain) + public static ResourceUnpackerOperation CreateResourceUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain) { DebugCheckDefaultPackageValid(); - return _defaultPackage.CreatePatchUnpacker(tags, unpackingMaxNumber, failedTryAgain); + return _defaultPackage.CreateResourceUnpacker(tags, unpackingMaxNumber, failedTryAgain); } /// - /// 创建补丁解压器 + /// 创建内置资源解压器 /// /// 同时解压的最大文件数 /// 解压失败的重试次数 - public static PatchUnpackerOperation CreatePatchUnpacker(int unpackingMaxNumber, int failedTryAgain) + public static ResourceUnpackerOperation CreateResourceUnpacker(int unpackingMaxNumber, int failedTryAgain) { DebugCheckDefaultPackageValid(); - return _defaultPackage.CreatePatchUnpacker(unpackingMaxNumber, failedTryAgain); + return _defaultPackage.CreateResourceUnpacker(unpackingMaxNumber, failedTryAgain); } #endregion @@ -375,7 +411,7 @@ namespace YooAsset private static void DebugCheckDefaultPackageValid() { if (_defaultPackage == null) - throw new Exception($"Default package is null. Please use {nameof(YooAssets.SetDefaultAssetsPackage)} !"); + throw new Exception($"Default package is null. Please use {nameof(YooAssets.SetDefaultPackage)} !"); } #endregion } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/CustomPackRule.cs b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/CustomPackRule.cs index 653df5a..ebd7a3c 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/CustomPackRule.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/CustomPackRule.cs @@ -10,7 +10,7 @@ public class PackEffectTexture : IPackRule { private const string PackDirectory = "Assets/Effect/Textures/"; - string IPackRule.GetBundleName(PackRuleData data) + PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data) { string assetPath = data.AssetPath; if (assetPath.StartsWith(PackDirectory) == false) @@ -18,6 +18,43 @@ public class PackEffectTexture : IPackRule string assetName = Path.GetFileName(assetPath).ToLower(); string firstChar = assetName.Substring(0, 1); - return $"{PackDirectory}effect_texture_{firstChar}"; + string bundleName = $"{PackDirectory}effect_texture_{firstChar}"; + var packRuleResult = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension); + return packRuleResult; + } + + bool IPackRule.IsRawFilePackRule() + { + return false; + } +} + +[DisplayName("打包视频(自定义)")] +public class PackVideo : IPackRule +{ + public PackRuleResult GetPackRuleResult(PackRuleData data) + { + string bundleName = RemoveExtension(data.AssetPath); + string fileExtension = Path.GetExtension(data.AssetPath); + fileExtension = fileExtension.Remove(0, 1); + PackRuleResult result = new PackRuleResult(bundleName, fileExtension); + return result; + } + + bool IPackRule.IsRawFilePackRule() + { + return true; + } + + private string RemoveExtension(string str) + { + if (string.IsNullOrEmpty(str)) + return str; + + int index = str.LastIndexOf("."); + if (index == -1) + return str; + else + return str.Remove(index); //"assets/config/test.unity3d" --> "assets/config/test" } } \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchCompareWindow.cs b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageCompareWindow.cs similarity index 63% rename from Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchCompareWindow.cs rename to Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageCompareWindow.cs index a56d8e0..2cea177 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchCompareWindow.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageCompareWindow.cs @@ -6,25 +6,25 @@ using UnityEditor; namespace YooAsset.Editor { - public class PatchCompareWindow : EditorWindow + public class PackageCompareWindow : EditorWindow { - static PatchCompareWindow _thisInstance; + static PackageCompareWindow _thisInstance; [MenuItem("YooAsset/补丁包比对工具", false, 302)] static void ShowWindow() { if (_thisInstance == null) { - _thisInstance = EditorWindow.GetWindow(typeof(PatchCompareWindow), false, "补丁包比对工具", true) as PatchCompareWindow; + _thisInstance = EditorWindow.GetWindow(typeof(PackageCompareWindow), false, "补丁包比对工具", true) as PackageCompareWindow; _thisInstance.minSize = new Vector2(800, 600); } _thisInstance.Show(); } - private string _patchManifestPath1 = string.Empty; - private string _patchManifestPath2 = string.Empty; - private readonly List _changeList = new List(); - private readonly List _newList = new List(); + private string _manifestPath1 = string.Empty; + private string _manifestPath2 = string.Empty; + private readonly List _changeList = new List(); + private readonly List _newList = new List(); private Vector2 _scrollPos1; private Vector2 _scrollPos2; @@ -37,9 +37,9 @@ namespace YooAsset.Editor string resultPath = EditorUtility.OpenFilePanel("Find", "Assets/", "bytes"); if (string.IsNullOrEmpty(resultPath)) return; - _patchManifestPath1 = resultPath; + _manifestPath1 = resultPath; } - EditorGUILayout.LabelField(_patchManifestPath1); + EditorGUILayout.LabelField(_manifestPath1); EditorGUILayout.EndHorizontal(); GUILayout.Space(10); @@ -49,16 +49,16 @@ namespace YooAsset.Editor string resultPath = EditorUtility.OpenFilePanel("Find", "Assets/", "bytes"); if (string.IsNullOrEmpty(resultPath)) return; - _patchManifestPath2 = resultPath; + _manifestPath2 = resultPath; } - EditorGUILayout.LabelField(_patchManifestPath2); + EditorGUILayout.LabelField(_manifestPath2); EditorGUILayout.EndHorizontal(); - if (string.IsNullOrEmpty(_patchManifestPath1) == false && string.IsNullOrEmpty(_patchManifestPath2) == false) + if (string.IsNullOrEmpty(_manifestPath1) == false && string.IsNullOrEmpty(_manifestPath2) == false) { if (GUILayout.Button("比对差异", GUILayout.MaxWidth(150))) { - ComparePatch(_changeList, _newList); + ComparePackage(_changeList, _newList); } } @@ -99,32 +99,32 @@ namespace YooAsset.Editor } } - private void ComparePatch(List changeList, List newList) + private void ComparePackage(List changeList, List newList) { changeList.Clear(); newList.Clear(); // 加载补丁清单1 - byte[] bytesData1 = FileUtility.ReadAllBytes(_patchManifestPath1); - PatchManifest patchManifest1 = PatchManifestTools.DeserializeFromBinary(bytesData1); + byte[] bytesData1 = FileUtility.ReadAllBytes(_manifestPath1); + PackageManifest manifest1 = ManifestTools.DeserializeFromBinary(bytesData1); // 加载补丁清单1 - byte[] bytesData2 = FileUtility.ReadAllBytes(_patchManifestPath2); - PatchManifest patchManifest2 = PatchManifestTools.DeserializeFromBinary(bytesData2); + byte[] bytesData2 = FileUtility.ReadAllBytes(_manifestPath2); + PackageManifest manifest2 = ManifestTools.DeserializeFromBinary(bytesData2); // 拷贝文件列表 - foreach (var patchBundle2 in patchManifest2.BundleList) + foreach (var bundle2 in manifest2.BundleList) { - if (patchManifest1.TryGetPatchBundle(patchBundle2.BundleName, out PatchBundle patchBundle1)) + if (manifest1.TryGetPackageBundle(bundle2.BundleName, out PackageBundle bundle1)) { - if (patchBundle2.FileHash != patchBundle1.FileHash) + if (bundle2.FileHash != bundle1.FileHash) { - changeList.Add(patchBundle2); + changeList.Add(bundle2); } } else { - newList.Add(patchBundle2); + newList.Add(bundle2); } } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchCompareWindow.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageCompareWindow.cs.meta similarity index 100% rename from Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchCompareWindow.cs.meta rename to Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageCompareWindow.cs.meta diff --git a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchImportWindow.cs b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageImportWindow.cs similarity index 65% rename from Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchImportWindow.cs rename to Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageImportWindow.cs index c1c5007..67ea091 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchImportWindow.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageImportWindow.cs @@ -4,22 +4,22 @@ using UnityEditor; namespace YooAsset.Editor { - public class PatchImportWindow : EditorWindow + public class PackageImportWindow : EditorWindow { - static PatchImportWindow _thisInstance; + static PackageImportWindow _thisInstance; [MenuItem("YooAsset/补丁包导入工具", false, 301)] static void ShowWindow() { if (_thisInstance == null) { - _thisInstance = EditorWindow.GetWindow(typeof(PatchImportWindow), false, "补丁包导入工具", true) as PatchImportWindow; + _thisInstance = EditorWindow.GetWindow(typeof(PackageImportWindow), false, "补丁包导入工具", true) as PackageImportWindow; _thisInstance.minSize = new Vector2(800, 600); } _thisInstance.Show(); } - private string _patchManifestPath = string.Empty; + private string _manifestPath = string.Empty; private void OnGUI() { @@ -30,29 +30,29 @@ namespace YooAsset.Editor string resultPath = EditorUtility.OpenFilePanel("Find", "Assets/", "bytes"); if (string.IsNullOrEmpty(resultPath)) return; - _patchManifestPath = resultPath; + _manifestPath = resultPath; } - EditorGUILayout.LabelField(_patchManifestPath); + EditorGUILayout.LabelField(_manifestPath); EditorGUILayout.EndHorizontal(); - if (string.IsNullOrEmpty(_patchManifestPath) == false) + if (string.IsNullOrEmpty(_manifestPath) == false) { if (GUILayout.Button("导入补丁包(全部文件)", GUILayout.MaxWidth(150))) { AssetBundleBuilderHelper.ClearStreamingAssetsFolder(); - CopyPatchFiles(_patchManifestPath); + CopyPackageFiles(_manifestPath); } } } - private void CopyPatchFiles(string patchManifestFilePath) + private void CopyPackageFiles(string manifestFilePath) { - string manifestFileName = Path.GetFileNameWithoutExtension(patchManifestFilePath); - string outputDirectory = Path.GetDirectoryName(patchManifestFilePath); + string manifestFileName = Path.GetFileNameWithoutExtension(manifestFilePath); + string outputDirectory = Path.GetDirectoryName(manifestFilePath); // 加载补丁清单 - byte[] bytesData = FileUtility.ReadAllBytes(patchManifestFilePath); - PatchManifest patchManifest = PatchManifestTools.DeserializeFromBinary(bytesData); + byte[] bytesData = FileUtility.ReadAllBytes(manifestFilePath); + PackageManifest manifest = ManifestTools.DeserializeFromBinary(bytesData); // 拷贝核心文件 { @@ -66,7 +66,7 @@ namespace YooAsset.Editor EditorTools.CopyFile(sourcePath, destPath, true); } { - string fileName = YooAssetSettingsData.GetPackageVersionFileName(patchManifest.PackageName); + string fileName = YooAssetSettingsData.GetPackageVersionFileName(manifest.PackageName); string sourcePath = $"{outputDirectory}/{fileName}"; string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{fileName}"; EditorTools.CopyFile(sourcePath, destPath, true); @@ -74,11 +74,11 @@ namespace YooAsset.Editor // 拷贝文件列表 int fileCount = 0; - foreach (var patchBundle in patchManifest.BundleList) + foreach (var packageBundle in manifest.BundleList) { fileCount++; - string sourcePath = $"{outputDirectory}/{patchBundle.FileName}"; - string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{patchBundle.FileName}"; + string sourcePath = $"{outputDirectory}/{packageBundle.FileName}"; + string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{packageBundle.FileName}"; EditorTools.CopyFile(sourcePath, destPath, true); } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchImportWindow.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageImportWindow.cs.meta similarity index 100% rename from Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PatchImportWindow.cs.meta rename to Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/PackageImportWindow.cs.meta diff --git a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/YooAsset.EditorExtension.asmdef b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/YooAsset.EditorExtension.asmdef deleted file mode 100644 index 9bb9ef0..0000000 --- a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/YooAsset.EditorExtension.asmdef +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "YooAsset.EditorExtension", - "rootNamespace": "", - "references": [ - "YooAsset", - "YooAsset.Editor" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/YooAsset.EditorExtension.asmdef.meta b/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/YooAsset.EditorExtension.asmdef.meta deleted file mode 100644 index 1a047d4..0000000 --- a/Assets/YooAsset/Samples~/Extension Sample/Scripts/Editor/YooAsset.EditorExtension.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: b58fede96e820534dabca12032b68135 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleBuilderSetting.asset b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleBuilderSetting.asset index 33dfe48..0e5d053 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleBuilderSetting.asset +++ b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleBuilderSetting.asset @@ -16,7 +16,7 @@ MonoBehaviour: BuildMode: 0 BuildPackage: DefaultPackage CompressOption: 2 - OutputNameStyle: 4 + OutputNameStyle: 1 CopyBuildinFileOption: 1 CopyBuildinFileTags: EncyptionClassName: FileStreamEncryption diff --git a/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorConfig.xml b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorConfig.xml new file mode 100644 index 0000000..dbac721 --- /dev/null +++ b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorConfig.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/package.json.meta b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorConfig.xml.meta similarity index 75% rename from Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/package.json.meta rename to Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorConfig.xml.meta index 2fc92bf..3ae38d6 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/package.json.meta +++ b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorConfig.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 08dafaa194a7143109cbe1c6403a2ec5 +guid: 218816e46e4f6304eaecd6fdc3a99f4d TextScriptImporter: externalObjects: {} userData: diff --git a/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorSetting.asset b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorSetting.asset index f867a50..7d010a2 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorSetting.asset +++ b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/AssetBundleCollectorSetting.asset @@ -21,7 +21,7 @@ MonoBehaviour: PackageDesc: Groups: - GroupName: battle - GroupDesc: + GroupDesc: "\u6218\u6597" AssetTags: ActiveRuleName: EnableGroup Collectors: @@ -46,8 +46,9 @@ MonoBehaviour: PackRuleName: PackDirectory FilterRuleName: CollectAll AssetTags: + UserData: - GroupName: shader - GroupDesc: + GroupDesc: "\u7740\u8272\u5668" AssetTags: ActiveRuleName: EnableGroup Collectors: @@ -58,8 +59,9 @@ MonoBehaviour: PackRuleName: PackShaderVariants FilterRuleName: CollectShaderVariants AssetTags: + UserData: - GroupName: scene - GroupDesc: + GroupDesc: "\u573A\u666F" AssetTags: ActiveRuleName: EnableGroup Collectors: @@ -70,8 +72,9 @@ MonoBehaviour: PackRuleName: PackSeparately FilterRuleName: CollectAll AssetTags: + UserData: - GroupName: ugui - GroupDesc: + GroupDesc: "\u9762\u677F" AssetTags: ActiveRuleName: EnableGroup Collectors: @@ -96,3 +99,17 @@ MonoBehaviour: PackRuleName: PackTopDirectory FilterRuleName: CollectAll AssetTags: + UserData: + - GroupName: config + GroupDesc: "\u914D\u7F6E\u8868" + AssetTags: + ActiveRuleName: EnableGroup + Collectors: + - CollectPath: Assets/Samples/Space Shooter/GameRes/Config + CollectorGUID: 1894d23646ddbf8479e579cc03261dde + CollectorType: 0 + AddressRuleName: AddressByFileName + PackRuleName: PackRawFile + FilterRuleName: CollectAll + AssetTags: + UserData: diff --git a/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/ShaderVariantCollectorSetting.asset b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/ShaderVariantCollectorSetting.asset index 6b26c7f..4bfcb9c 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/ShaderVariantCollectorSetting.asset +++ b/Assets/YooAsset/Samples~/Space Shooter/AssetSetting/ShaderVariantCollectorSetting.asset @@ -12,4 +12,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 44454e58a49818040a1aef5799e71b30, type: 3} m_Name: ShaderVariantCollectorSetting m_EditorClassIdentifier: - SavePath: Assets/Samples/BassicSample/GameArt/ShaderVariants/MyShaderVariants.shadervariants + SavePath: Assets/ShaderVariants/MyShaderVariants.shadervariants + CollectPackage: DefaultPackage + ProcessCapacity: 1000 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameArt/ShaderVariants/MyShaderVariants.json b/Assets/YooAsset/Samples~/Space Shooter/GameArt/ShaderVariants/MyShaderVariants.json index 8060666..57085a5 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameArt/ShaderVariants/MyShaderVariants.json +++ b/Assets/YooAsset/Samples~/Space Shooter/GameArt/ShaderVariants/MyShaderVariants.json @@ -1,6 +1,6 @@ { - "ShaderTotalCount": 12, - "VariantTotalCount": 16, + "ShaderTotalCount": 13, + "VariantTotalCount": 24, "ShaderVariantInfos": [ { "AssetPath": "Resources/unity_builtin_extra", @@ -14,6 +14,109 @@ } ] }, + { + "AssetPath": "Resources/unity_builtin_extra", + "ShaderName": "Standard", + "ShaderVariantElements": [ + { + "PassType": 4, + "Keywords": [ + "DIRECTIONAL", + "LIGHTPROBE_SH", + "SHADOWS_SCREEN", + "SHADOWS_SPLIT_SPHERES" + ] + }, + { + "PassType": 4, + "Keywords": [ + "DIRECTIONAL", + "LIGHTPROBE_SH", + "SHADOWS_SCREEN", + "SHADOWS_SPLIT_SPHERES", + "_EMISSION" + ] + }, + { + "PassType": 4, + "Keywords": [ + "DIRECTIONAL", + "LIGHTPROBE_SH", + "SHADOWS_SCREEN", + "SHADOWS_SPLIT_SPHERES", + "_NORMALMAP" + ] + }, + { + "PassType": 4, + "Keywords": [ + "DIRECTIONAL", + "LIGHTPROBE_SH", + "SHADOWS_SCREEN", + "SHADOWS_SPLIT_SPHERES", + "_EMISSION", + "_NORMALMAP" + ] + }, + { + "PassType": 8, + "Keywords": [ + "" + ] + }, + { + "PassType": 8, + "Keywords": [ + "SHADOWS_DEPTH", + "SHADOWS_SPLIT_SPHERES" + ] + }, + { + "PassType": 8, + "Keywords": [ + "_EMISSION" + ] + }, + { + "PassType": 8, + "Keywords": [ + "SHADOWS_DEPTH", + "SHADOWS_SPLIT_SPHERES", + "_EMISSION" + ] + }, + { + "PassType": 8, + "Keywords": [ + "_NORMALMAP" + ] + }, + { + "PassType": 8, + "Keywords": [ + "SHADOWS_DEPTH", + "SHADOWS_SPLIT_SPHERES", + "_NORMALMAP" + ] + }, + { + "PassType": 8, + "Keywords": [ + "_EMISSION", + "_NORMALMAP" + ] + }, + { + "PassType": 8, + "Keywords": [ + "SHADOWS_DEPTH", + "SHADOWS_SPLIT_SPHERES", + "_EMISSION", + "_NORMALMAP" + ] + } + ] + }, { "AssetPath": "Resources/unity_builtin_extra", "ShaderName": "Skybox/Procedural", @@ -21,12 +124,23 @@ { "PassType": 0, "Keywords": [ - "BILLBOARD_FACE_CAMERA_POS", "_SUNDISK_SIMPLE" ] } ] }, + { + "AssetPath": "Resources/unity_builtin_extra", + "ShaderName": "Legacy Shaders/Particles/Additive", + "ShaderVariantElements": [ + { + "PassType": 0, + "Keywords": [ + "" + ] + } + ] + }, { "AssetPath": "Resources/unity_builtin_extra", "ShaderName": "Hidden/Internal-GUITextureClip", @@ -87,18 +201,6 @@ } ] }, - { - "AssetPath": "Resources/unity_builtin_extra", - "ShaderName": "Hidden/Internal-GUIRoundedRectWithColorPerBorder", - "ShaderVariantElements": [ - { - "PassType": 0, - "Keywords": [ - "" - ] - } - ] - }, { "AssetPath": "Resources/unity_builtin_extra", "ShaderName": "Hidden/Internal-UIRAtlasBlitCopy", @@ -113,80 +215,37 @@ }, { "AssetPath": "Resources/unity_builtin_extra", - "ShaderName": "Hidden/UIElements/EditorUIE", + "ShaderName": "Hidden/Internal-GUIRoundedRectWithColorPerBorder", "ShaderVariantElements": [ { "PassType": 0, "Keywords": [ - "BILLBOARD_FACE_CAMERA_POS" + "" ] } ] }, { "AssetPath": "Resources/unity_builtin_extra", - "ShaderName": "Mobile/Diffuse", + "ShaderName": "Mobile/Particles/Additive", "ShaderVariantElements": [ { - "PassType": 4, - "Keywords": [ - "BILLBOARD_FACE_CAMERA_POS", - "DIRECTIONAL", - "LIGHTPROBE_SH", - "SHADOWS_SCREEN", - "SHADOWS_SOFT", - "SHADOWS_SPLIT_SPHERES" - ] - }, - { - "PassType": 8, + "PassType": 0, "Keywords": [ "" ] - }, - { - "PassType": 8, - "Keywords": [ - "SHADOWS_DEPTH", - "SHADOWS_SOFT", - "SHADOWS_SPLIT_SPHERES" - ] } ] }, { - "AssetPath": "Assets/Samples/Basic Sample/GameArt/Shaders/StandardMobile.shader", - "ShaderName": "Mobile/Standard", + "AssetPath": "Resources/unity_builtin_extra", + "ShaderName": "Unlit/Texture", "ShaderVariantElements": [ { - "PassType": 1, + "PassType": 0, "Keywords": [ - "BILLBOARD_FACE_CAMERA_POS", "SHADOWS_SCREEN", - "SHADOWS_SOFT", - "SHADOWS_SPLIT_SPHERES", - "_EMISSION", - "_METALLICGLOSSMAP", - "_NORMALMAP" - ] - }, - { - "PassType": 8, - "Keywords": [ - "_EMISSION", - "_METALLICGLOSSMAP", - "_NORMALMAP" - ] - }, - { - "PassType": 8, - "Keywords": [ - "SHADOWS_DEPTH", - "SHADOWS_SOFT", - "SHADOWS_SPLIT_SPHERES", - "_EMISSION", - "_METALLICGLOSSMAP", - "_NORMALMAP" + "SHADOWS_SPLIT_SPHERES" ] } ] diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameArt/ShaderVariants/MyShaderVariants.shadervariants b/Assets/YooAsset/Samples~/Space Shooter/GameArt/ShaderVariants/MyShaderVariants.shadervariants index 814708a..8db2ed6 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameArt/ShaderVariants/MyShaderVariants.shadervariants +++ b/Assets/YooAsset/Samples~/Space Shooter/GameArt/ShaderVariants/MyShaderVariants.shadervariants @@ -13,10 +13,45 @@ ShaderVariantCollection: variants: - keywords: passType: 0 + - first: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + second: + variants: + - keywords: DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN SHADOWS_SPLIT_SPHERES + passType: 4 + - keywords: DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN SHADOWS_SPLIT_SPHERES + _EMISSION + passType: 4 + - keywords: DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN SHADOWS_SPLIT_SPHERES + _NORMALMAP + passType: 4 + - keywords: DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN SHADOWS_SPLIT_SPHERES + _EMISSION _NORMALMAP + passType: 4 + - keywords: + passType: 8 + - keywords: SHADOWS_DEPTH SHADOWS_SPLIT_SPHERES + passType: 8 + - keywords: _EMISSION + passType: 8 + - keywords: SHADOWS_DEPTH SHADOWS_SPLIT_SPHERES _EMISSION + passType: 8 + - keywords: _NORMALMAP + passType: 8 + - keywords: SHADOWS_DEPTH SHADOWS_SPLIT_SPHERES _NORMALMAP + passType: 8 + - keywords: _EMISSION _NORMALMAP + passType: 8 + - keywords: SHADOWS_DEPTH SHADOWS_SPLIT_SPHERES _EMISSION _NORMALMAP + passType: 8 - first: {fileID: 106, guid: 0000000000000000f000000000000000, type: 0} second: variants: - - keywords: BILLBOARD_FACE_CAMERA_POS _SUNDISK_SIMPLE + - keywords: _SUNDISK_SIMPLE + passType: 0 + - first: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0} + second: + variants: + - keywords: passType: 0 - first: {fileID: 9000, guid: 0000000000000000f000000000000000, type: 0} second: @@ -43,39 +78,23 @@ ShaderVariantCollection: variants: - keywords: passType: 0 + - first: {fileID: 9006, guid: 0000000000000000f000000000000000, type: 0} + second: + variants: + - keywords: + passType: 0 - first: {fileID: 9007, guid: 0000000000000000f000000000000000, type: 0} second: variants: - keywords: passType: 0 - - first: {fileID: 9101, guid: 0000000000000000f000000000000000, type: 0} + - first: {fileID: 10720, guid: 0000000000000000f000000000000000, type: 0} second: variants: - keywords: passType: 0 - - first: {fileID: 9103, guid: 0000000000000000f000000000000000, type: 0} + - first: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} second: variants: - - keywords: BILLBOARD_FACE_CAMERA_POS + - keywords: SHADOWS_SCREEN SHADOWS_SPLIT_SPHERES passType: 0 - - first: {fileID: 10703, guid: 0000000000000000f000000000000000, type: 0} - second: - variants: - - keywords: BILLBOARD_FACE_CAMERA_POS DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN - SHADOWS_SOFT SHADOWS_SPLIT_SPHERES - passType: 4 - - keywords: - passType: 8 - - keywords: SHADOWS_DEPTH SHADOWS_SOFT SHADOWS_SPLIT_SPHERES - passType: 8 - - first: {fileID: 4800000, guid: ba67c8b1d5e59dc428ad9fc9270f8353, type: 3} - second: - variants: - - keywords: BILLBOARD_FACE_CAMERA_POS SHADOWS_SCREEN SHADOWS_SOFT SHADOWS_SPLIT_SPHERES - _EMISSION _METALLICGLOSSMAP _NORMALMAP - passType: 1 - - keywords: _EMISSION _METALLICGLOSSMAP _NORMALMAP - passType: 8 - - keywords: SHADOWS_DEPTH SHADOWS_SOFT SHADOWS_SPLIT_SPHERES _EMISSION _METALLICGLOSSMAP - _NORMALMAP - passType: 8 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Config.meta b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Config.meta new file mode 100644 index 0000000..2df7e53 --- /dev/null +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1894d23646ddbf8479e579cc03261dde +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Config/about.txt b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Config/about.txt new file mode 100644 index 0000000..338f656 --- /dev/null +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Config/about.txt @@ -0,0 +1 @@ +Powered by YooAsset @tuyoogame \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/README.md.meta b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Config/about.txt.meta similarity index 75% rename from Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/README.md.meta rename to Assets/YooAsset/Samples~/Space Shooter/GameRes/Config/about.txt.meta index 2cbd9ac..2863db9 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/ThirdParty/BetterStreamingAssets/README.md.meta +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Config/about.txt.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c59a049ac5cdb4a48996edcefd9ac9c7 +guid: 66ce1e032fc66694bb3fce32961d78d5 TextScriptImporter: externalObjects: {} userData: diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid01.prefab b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid01.prefab index 0bf0c2c..f0843c1 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid01.prefab +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid01.prefab @@ -14,7 +14,7 @@ GameObject: - component: {fileID: 8153114547710269446} m_Layer: 0 m_Name: asteroid01 - m_TagString: Asteroid + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid02.prefab b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid02.prefab index fc1428e..24e4bc6 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid02.prefab +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid02.prefab @@ -93,7 +93,7 @@ GameObject: - component: {fileID: 6609967452740485438} m_Layer: 0 m_Name: asteroid02 - m_TagString: Asteroid + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid03.prefab b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid03.prefab index ba87ae4..7ce52f1 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid03.prefab +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/asteroid03.prefab @@ -93,7 +93,7 @@ GameObject: - component: {fileID: 4093119317317235419} m_Layer: 0 m_Name: asteroid03 - m_TagString: Asteroid + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/enemy_bullet.prefab b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/enemy_bullet.prefab index 0f4c048..4dac0c1 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/enemy_bullet.prefab +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/enemy_bullet.prefab @@ -14,7 +14,7 @@ GameObject: - component: {fileID: 7168776728617073029} m_Layer: 0 m_Name: enemy_bullet - m_TagString: EnemyBullet + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/enemy_ship.prefab b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/enemy_ship.prefab index 5da204b..b1638a0 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/enemy_ship.prefab +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/enemy_ship.prefab @@ -4714,7 +4714,7 @@ GameObject: - component: {fileID: 8046716069608073559} m_Layer: 0 m_Name: enemy_ship - m_TagString: Enemy + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/player_bullet.prefab b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/player_bullet.prefab index f04fabe..76c943b 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/player_bullet.prefab +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/player_bullet.prefab @@ -14,7 +14,7 @@ GameObject: - component: {fileID: 2296800368016434796} m_Layer: 0 m_Name: player_bullet - m_TagString: PlayerBullet + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/player_ship.prefab b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/player_ship.prefab index ca549e8..951800b 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/player_ship.prefab +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Entity/player_ship.prefab @@ -9481,7 +9481,7 @@ GameObject: - component: {fileID: 5342208951388308754} m_Layer: 0 m_Name: player_ship - m_TagString: Player + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Scene/scene_battle.unity b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Scene/scene_battle.unity index 0ee24e7..f7f063b 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/Scene/scene_battle.unity +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/Scene/scene_battle.unity @@ -129,7 +129,7 @@ GameObject: - component: {fileID: 37} m_Layer: 0 m_Name: Boundary - m_TagString: Boundary + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 @@ -10999,7 +10999,7 @@ GameObject: - component: {fileID: 1691764579} m_Layer: 0 m_Name: BoundaryWorld - m_TagString: Boundary + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameRes/UIPanel/UIAbout.prefab b/Assets/YooAsset/Samples~/Space Shooter/GameRes/UIPanel/UIAbout.prefab index 5a88831..bd2ce45 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameRes/UIPanel/UIAbout.prefab +++ b/Assets/YooAsset/Samples~/Space Shooter/GameRes/UIPanel/UIAbout.prefab @@ -66,7 +66,7 @@ MonoBehaviour: m_Calls: [] m_FontData: m_Font: {fileID: 12800000, guid: 8297a2bf97dbbba468bd2518d003a876, type: 3} - m_FontSize: 28 + m_FontSize: 22 m_FontStyle: 0 m_BestFit: 0 m_MinSize: 2 @@ -77,7 +77,7 @@ MonoBehaviour: m_HorizontalOverflow: 0 m_VerticalOverflow: 0 m_LineSpacing: 1 - m_Text: Powered by YooAsset + m_Text: --- !u!1 &4142826567245113227 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Editor/Encryption.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Editor/Encryption.cs index b69a63f..1e3ca41 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Editor/Encryption.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Editor/Encryption.cs @@ -3,21 +3,11 @@ using System.IO; using System.Text; using YooAsset; -public class EncryptionNone : IEncryptionServices -{ - public EncryptResult Encrypt(EncryptFileInfo fileInfo) - { - EncryptResult result = new EncryptResult(); - result.LoadMethod = EBundleLoadMethod.Normal; - return result; - } -} - public class FileOffsetEncryption : IEncryptionServices { public EncryptResult Encrypt(EncryptFileInfo fileInfo) { - if(fileInfo.BundleName.Contains("gameres_music")) + if (fileInfo.BundleName.Contains("_gameres_audio")) { int offset = 32; byte[] fileData = File.ReadAllBytes(fileInfo.FilePath); @@ -42,7 +32,8 @@ public class FileStreamEncryption : IEncryptionServices { public EncryptResult Encrypt(EncryptFileInfo fileInfo) { - if (fileInfo.BundleName.Contains("gameres_music")) + // LoadFromStream + if (fileInfo.BundleName.Contains("_gameres_audio")) { var fileData = File.ReadAllBytes(fileInfo.FilePath); for (int i = 0; i < fileData.Length; i++) @@ -55,7 +46,22 @@ public class FileStreamEncryption : IEncryptionServices result.EncryptedData = fileData; return result; } - else + + // LoadFromFileOffset + if (fileInfo.BundleName.Contains("_gameres_uiimage")) + { + var fileData = File.ReadAllBytes(fileInfo.FilePath); + int offset = 32; + var temper = new byte[fileData.Length + offset]; + Buffer.BlockCopy(fileData, 0, temper, offset, fileData.Length); + + EncryptResult result = new EncryptResult(); + result.LoadMethod = EBundleLoadMethod.LoadFromFileOffset; + result.EncryptedData = temper; + return result; + } + + // Normal { EncryptResult result = new EncryptResult(); result.LoadMethod = EBundleLoadMethod.Normal; diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityAsteroid.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityAsteroid.cs index 8e4d8e6..289c30f 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityAsteroid.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityAsteroid.cs @@ -25,7 +25,8 @@ public class EntityAsteroid : MonoBehaviour } void OnTriggerEnter(Collider other) { - if (other.CompareTag("PlayerBullet")) + var name = other.gameObject.name; + if (name.StartsWith("player")) { BattleEventDefine.AsteroidExplosion.SendEventMessage(this.transform.position, this.transform.rotation); _handle.Restore(); @@ -34,7 +35,8 @@ public class EntityAsteroid : MonoBehaviour } void OnTriggerExit(Collider other) { - if (other.CompareTag("Boundary")) + var name = other.gameObject.name; + if (name.StartsWith("Boundary")) { _handle.Restore(); _handle = null; diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityBullet.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityBullet.cs index dc68fec..d94babe 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityBullet.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityBullet.cs @@ -19,25 +19,27 @@ public class EntityBullet : MonoBehaviour void Awake() { - _rigidbody = this.transform.GetComponent(); + _rigidbody = this.transform.GetComponent(); } void OnTriggerEnter(Collider other) { - if (other.CompareTag("Boundary")) + var name = other.gameObject.name; + if (name.StartsWith("Boundary")) return; - if (this.gameObject.CompareTag("EnemyBullet")) + var goName = this.gameObject.name; + if (goName.StartsWith("enemy_bullet")) { - if (other.CompareTag("Enemy") == false) + if (name.StartsWith("enemy") == false) { _handle.Restore(); _handle = null; } } - if (this.gameObject.CompareTag("PlayerBullet")) + if (goName.StartsWith("player_bullet")) { - if (other.CompareTag("Player") == false) + if (name.StartsWith("player") == false) { _handle.Restore(); _handle = null; @@ -46,7 +48,8 @@ public class EntityBullet : MonoBehaviour } void OnTriggerExit(Collider other) { - if (other.CompareTag("Boundary")) + var name = other.gameObject.name; + if (name.StartsWith("Boundary")) { _handle.Restore(); _handle = null; diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityEnemy.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityEnemy.cs index 3f72f74..c617f5f 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityEnemy.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityEnemy.cs @@ -68,7 +68,8 @@ public class EntityEnemy : MonoBehaviour } void OnTriggerEnter(Collider other) { - if (other.CompareTag("PlayerBullet")) + var name = other.gameObject.name; + if (name.StartsWith("player")) { BattleEventDefine.EnemyDead.SendEventMessage(this.transform.position, this.transform.rotation); _handle.Restore(); @@ -77,7 +78,8 @@ public class EntityEnemy : MonoBehaviour } void OnTriggerExit(Collider other) { - if (other.CompareTag("Boundary")) + var name = other.gameObject.name; + if (name.StartsWith("Boundary")) { _handle.Restore(); _handle = null; diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityPlayer.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityPlayer.cs index 716218e..209f5cd 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityPlayer.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/Entity/EntityPlayer.cs @@ -54,7 +54,8 @@ public class EntityPlayer : MonoBehaviour } void OnTriggerEnter(Collider other) { - if (other.CompareTag("Enemy") || other.CompareTag("EnemyBullet") || other.CompareTag("Asteroid")) + var name = other.gameObject.name; + if (name.StartsWith("enemy") || name.StartsWith("asteroid")) { BattleEventDefine.PlayerDead.SendEventMessage(this.transform.position, this.transform.rotation); _handle.Restore(); diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/Boot.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/Boot.cs index 8733aa5..1a69192 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/Boot.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/Boot.cs @@ -1,6 +1,6 @@ using UnityEngine; using UniFramework.Event; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; public class Boot : MonoBehaviour @@ -18,14 +18,11 @@ public class Boot : MonoBehaviour } void Start() { - // 初始化BetterStreaming - BetterStreamingAssets.Initialize(); //TODO wht ref 不是必要的 - // 初始化事件系统 UniEvent.Initalize(); //TODO wht ref 不是必要的 - // 初始化管理系统 - UniModule.Initialize(); //TODO wht ref 不是必要的 + // 初始化单例系统 + UniSingleton.Initialize(); //TODO wht ref 不是必要的 // 初始化资源系统 YooAssets.Initialize(); //TODO wht real 拿 @@ -34,7 +31,7 @@ public class Boot : MonoBehaviour // TODO wht ref 上面 都要有 // 创建补丁管理器 - UniModule.CreateModule(); //TODO wht ref 不是必要的 + UniSingleton.CreateSingleton(); //TODO wht ref 不是必要的 // 开始补丁更新流程 PatchManager.Instance.Run(PlayMode); //TODo wht ref 不是必要的 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmInitGame.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmInitGame.cs index 493dd5e..c4e87e3 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmInitGame.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmInitGame.cs @@ -4,7 +4,7 @@ using UnityEngine; using UniFramework.Pooling; using UniFramework.Window; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; internal class FsmInitGame : IStateNode @@ -17,7 +17,7 @@ internal class FsmInitGame : IStateNode } void IStateNode.OnEnter() { - UniModule.StartCoroutine(Prepare()); + UniSingleton.StartCoroutine(Prepare()); } void IStateNode.OnUpdate() { diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmSceneBattle.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmSceneBattle.cs index 8dc0864..df1486e 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmSceneBattle.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmSceneBattle.cs @@ -5,7 +5,7 @@ using UnityEngine; using UniFramework.Window; using UniFramework.Event; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; internal class FsmSceneBattle : IStateNode @@ -17,7 +17,7 @@ internal class FsmSceneBattle : IStateNode } void IStateNode.OnEnter() { - UniModule.StartCoroutine(Prepare()); + UniSingleton.StartCoroutine(Prepare()); } void IStateNode.OnUpdate() { @@ -35,13 +35,13 @@ internal class FsmSceneBattle : IStateNode private IEnumerator Prepare() { - yield return UniWindow.OpenWindowAsync("UILoading"); yield return YooAssets.LoadSceneAsync("scene_battle"); _battleRoom = new BattleRoom(); yield return _battleRoom.LoadRoom(); - // 等所有数据准备完毕后,关闭加载界面。 - UniWindow.CloseWindow(); + // 释放资源 + var package = YooAssets.GetPackage("DefaultPackage"); + package.UnloadUnusedAssets(); } } \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmSceneHome.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmSceneHome.cs index d22f22e..df6e8d9 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmSceneHome.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/FsmNode/FsmSceneHome.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; using UniFramework.Window; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; internal class FsmSceneHome : IStateNode @@ -16,7 +16,7 @@ internal class FsmSceneHome : IStateNode } void IStateNode.OnEnter() { - UniModule.StartCoroutine(Prepare()); + UniSingleton.StartCoroutine(Prepare()); } void IStateNode.OnUpdate() { @@ -28,17 +28,11 @@ internal class FsmSceneHome : IStateNode private IEnumerator Prepare() { - if (_machine.PreviousNode != typeof(FsmInitGame).FullName) - yield return UniWindow.OpenWindowAsync("UILoading"); - - yield return YooAssets.LoadSceneAsync("scene_home"); - //TODO wht ref 参考;关闭Enable Addressable,使用全路径 - // yield return YooAssets.LoadSceneAsync("Assets/YooAsset/Assets/YooAsset/Samples/Space Shooter/GameRes/Scene/scene_home.unity"); - + yield return YooAssets.LoadSceneAsync("scene_home"); yield return UniWindow.OpenWindowAsync("UIHome"); - yield return new WaitForSeconds(0.5f); - - // 等所有数据准备完毕后,关闭加载界面。 - UniWindow.CloseWindow(); + + // 释放资源 + var package = YooAssets.GetPackage("DefaultPackage"); + package.UnloadUnusedAssets(); } } \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/GameManager.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/GameManager.cs index 1625773..13e81ae 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/GameManager.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/GameManager.cs @@ -3,22 +3,22 @@ using System.Collections.Generic; using UnityEngine; using UniFramework.Event; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; -public class GameManager : ModuleSingleton, IModule +public class GameManager : SingletonInstance, ISingleton { private bool _isRun = false; private EventGroup _eventGroup = new EventGroup(); private StateMachine _machine; - void IModule.OnCreate(object createParam) + void ISingleton.OnCreate(object createParam) { } - void IModule.OnDestroy() + void ISingleton.OnDestroy() { _eventGroup.RemoveAllListener(); } - void IModule.OnUpdate() + void ISingleton.OnUpdate() { if (_machine != null) _machine.Update(); diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmClearCache.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmClearCache.cs index a6fc786..a1c03ce 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmClearCache.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmClearCache.cs @@ -18,7 +18,7 @@ internal class FsmClearCache : IStateNode { PatchEventDefine.PatchStatesChange.SendEventMessage("清理未使用的缓存文件!"); //TODO wht real 拿,但是不开 - var package = YooAsset.YooAssets.GetAssetsPackage("DefaultPackage"); + var package = YooAsset.YooAssets.GetPackage("DefaultPackage"); var operation = package.ClearUnusedCacheFilesAsync(); operation.Completed += Operation_Completed; } diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmCreateDownloader.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmCreateDownloader.cs index 0b094ab..9609a9f 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmCreateDownloader.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmCreateDownloader.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; /// @@ -19,7 +19,7 @@ public class FsmCreateDownloader : IStateNode void IStateNode.OnEnter() { PatchEventDefine.PatchStatesChange.SendEventMessage("创建补丁下载器!"); - UniModule.StartCoroutine(CreateDownloader()); + UniSingleton.StartCoroutine(CreateDownloader()); } void IStateNode.OnUpdate() { @@ -35,7 +35,7 @@ public class FsmCreateDownloader : IStateNode //TODO wht real 以下代码全拿 int downloadingMaxNum = 10; int failedTryAgain = 3; - var downloader = YooAssets.CreatePatchDownloader(downloadingMaxNum, failedTryAgain); + var downloader = YooAssets.CreateResourceDownloader(downloadingMaxNum, failedTryAgain); PatchManager.Instance.Downloader = downloader; if (downloader.TotalDownloadCount == 0) //没有需要下载的资源 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmDownloadFiles.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmDownloadFiles.cs index f894748..c66c6bd 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmDownloadFiles.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmDownloadFiles.cs @@ -1,7 +1,7 @@ using System.Collections; using UnityEngine; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; /// @@ -18,7 +18,7 @@ public class FsmDownloadFiles : IStateNode void IStateNode.OnEnter() { PatchEventDefine.PatchStatesChange.SendEventMessage("开始下载补丁文件!"); - UniModule.StartCoroutine(BeginDownload()); + UniSingleton.StartCoroutine(BeginDownload()); } void IStateNode.OnUpdate() { diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmInitialize.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmInitialize.cs index 0c2552a..c388397 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmInitialize.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmInitialize.cs @@ -4,7 +4,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; /// @@ -21,7 +21,7 @@ internal class FsmInitialize : IStateNode void IStateNode.OnEnter() { PatchEventDefine.PatchStatesChange.SendEventMessage("初始化资源包!"); - UniModule.StartCoroutine(InitPackage()); + UniSingleton.StartCoroutine(InitPackage()); } void IStateNode.OnUpdate() { @@ -40,11 +40,11 @@ internal class FsmInitialize : IStateNode // 创建默认的资源包 string packageName = "DefaultPackage"; - var package = YooAssets.TryGetAssetsPackage(packageName); + var package = YooAssets.TryGetPackage(packageName); if (package == null) { - package = YooAssets.CreateAssetsPackage(packageName); - YooAssets.SetDefaultAssetsPackage(package); + package = YooAssets.CreatePackage(packageName); + YooAssets.SetDefaultPackage(package); } // 编辑器下的模拟模式 @@ -52,7 +52,7 @@ internal class FsmInitialize : IStateNode if (playMode == EPlayMode.EditorSimulateMode) { var createParameters = new EditorSimulateModeParameters(); - createParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild(packageName); + createParameters.SimulateManifestFilePath = EditorSimulateModeHelper.SimulateBuild(packageName); initializationOperation = package.InitializeAsync(createParameters); } @@ -125,9 +125,8 @@ internal class FsmInitialize : IStateNode { public bool QueryStreamingAssets(string fileName) { - // 注意:使用了BetterStreamingAssets插件,使用前需要初始化该插件! string buildinFolderName = YooAssets.GetStreamingAssetBuildinFolderName(); - return BetterStreamingAssets.FileExists($"{buildinFolderName}/{fileName}"); //TODO wht real 有没有其它接口可以替代,不想用BetterStreamingAssets这种第三方 + return StreamingAssetsHelper.FileExists($"{buildinFolderName}/{fileName}"); } } @@ -146,7 +145,7 @@ internal class FsmInitialize : IStateNode throw new NotImplementedException(); } - public FileStream LoadFromStream(DecryptFileInfo fileInfo) + public Stream LoadFromStream(DecryptFileInfo fileInfo) { BundleStream bundleStream = new BundleStream(fileInfo.FilePath, FileMode.Open); return bundleStream; diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmPatchDone.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmPatchDone.cs index 99e0633..df85677 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmPatchDone.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmPatchDone.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; /// /// 流程更新完毕 @@ -17,7 +17,7 @@ internal class FsmPatchDone : IStateNode PatchEventDefine.PatchStatesChange.SendEventMessage("开始游戏!"); // 创建游戏管理器 - UniModule.CreateModule(); + UniSingleton.CreateSingleton(); // 开启游戏流程 GameManager.Instance.Run(); diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmPatchPrepare.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmPatchPrepare.cs index 4f23e72..377b14c 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmPatchPrepare.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmPatchPrepare.cs @@ -4,7 +4,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; /// /// 流程准备工作 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmUpdateManifest.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmUpdateManifest.cs index 4bbc3d2..4e2d2f8 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmUpdateManifest.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmUpdateManifest.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; /// @@ -19,7 +19,7 @@ public class FsmUpdateManifest : IStateNode void IStateNode.OnEnter() { PatchEventDefine.PatchStatesChange.SendEventMessage("更新资源清单!"); - UniModule.StartCoroutine(UpdateManifest()); + UniSingleton.StartCoroutine(UpdateManifest()); } void IStateNode.OnUpdate() { @@ -32,13 +32,14 @@ public class FsmUpdateManifest : IStateNode { yield return new WaitForSecondsRealtime(0.5f); - //TODO wht real 以下代码全拿 - var package = YooAssets.GetAssetsPackage("DefaultPackage"); + //TODO wht real 以下代码全拿 + var package = YooAssets.GetPackage("DefaultPackage"); var operation = package.UpdatePackageManifestAsync(PatchManager.Instance.PackageVersion); yield return operation; if(operation.Status == EOperationStatus.Succeed) { + operation.SavePackageVersion(); _machine.ChangeState(); } else diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmUpdateVersion.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmUpdateVersion.cs index 8a241cb..ef8490e 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmUpdateVersion.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmUpdateVersion.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; /// @@ -19,7 +19,7 @@ internal class FsmUpdateVersion : IStateNode void IStateNode.OnEnter() { PatchEventDefine.PatchStatesChange.SendEventMessage("获取最新的资源版本 !"); - UniModule.StartCoroutine(GetStaticVersion()); + UniSingleton.StartCoroutine(GetStaticVersion()); } void IStateNode.OnUpdate() { @@ -32,8 +32,8 @@ internal class FsmUpdateVersion : IStateNode { yield return new WaitForSecondsRealtime(0.5f); - //TODO wht real 以下代码全拿 - var package = YooAssets.GetAssetsPackage("DefaultPackage"); + //TODO wht real 以下代码全拿 + var package = YooAssets.GetPackage("DefaultPackage"); var operation = package.UpdatePackageVersionAsync(); yield return operation; diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs index 33ccdd6..4e0f425 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs @@ -4,10 +4,10 @@ using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; using UniFramework.Event; -using UniFramework.Module; +using UniFramework.Singleton; using YooAsset; -public class PatchManager : ModuleSingleton, IModule +public class PatchManager : SingletonInstance, ISingleton { /// /// 运行模式 @@ -22,21 +22,21 @@ public class PatchManager : ModuleSingleton, IModule /// /// 下载器 /// - public PatchDownloaderOperation Downloader { set; get; } + public ResourceDownloaderOperation Downloader { set; get; } private bool _isRun = false; private EventGroup _eventGroup = new EventGroup(); private StateMachine _machine; - void IModule.OnCreate(object createParam) + void ISingleton.OnCreate(object createParam) { } - void IModule.OnDestroy() + void ISingleton.OnDestroy() { _eventGroup.RemoveAllListener(); } - void IModule.OnUpdate() + void ISingleton.OnUpdate() { if (_machine != null) _machine.Update(); diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/UIWindow/UIAboutWindow.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/UIWindow/UIAboutWindow.cs index 417867d..1dea2c2 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/UIWindow/UIAboutWindow.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/UIWindow/UIAboutWindow.cs @@ -3,17 +3,26 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UniFramework.Window; +using YooAsset; [WindowAttribute(100, false)] public class UIAboutWindow : UIWindow { + private Text _info; + private RawFileOperationHandle _handle; + public override void OnCreate() { var maskBtn = this.transform.Find("mask").GetComponent