Compare commits

...

39 Commits
1.3.1 ... 1.3.3

Author SHA1 Message Date
hevinci
ba4efebbce Update CHANGELOG.md 2022-10-27 19:01:07 +08:00
hevinci
2486287a0e Update package.json 2022-10-27 19:01:04 +08:00
hevinci
2599639aeb Update PatchSystem 2022-10-27 14:20:05 +08:00
hevinci
c1192b37c6 Update Extension Sample 2022-10-26 21:03:19 +08:00
hevinci
1f647163f2 Update Basic Sample 2022-10-26 21:03:10 +08:00
hevinci
cc04efe76b Update runtime code
UpdateStaticVersionOperation.PackageCRC重名为PackageVersion。
AssetPackage.GetHumanReadableVersion()重名为GetPackageVersion()
2022-10-26 21:02:25 +08:00
hevinci
18426d0481 Update AssetBundleBuilder 2022-10-26 20:57:27 +08:00
hevinci
500b469bce Update AssetBundleBuilder
增加PackageVersion构建参数。
2022-10-26 19:51:29 +08:00
hevinci
49c242e7bc Update AssetBundleBuilder
检测输出目录文件路径过长导致的异常。
2022-10-25 19:07:48 +08:00
hevinci
2d72d6dbc9 Update AssetSystem 2022-10-25 15:56:07 +08:00
hevinci
1f3e55ebea Update DownloadSystem
下载错误提示增加HTTP Response Code
2022-10-25 14:33:21 +08:00
hevinci
0ecb37419b Update AssetSystem 2022-10-24 19:09:16 +08:00
hevinci
c758bf6530 Update AssetSystem 2022-10-24 15:39:04 +08:00
hevinci
46d985a720 Update AssetBundleDebugger
调试窗口增加调试信息导出按钮。
2022-10-22 18:23:40 +08:00
hevinci
9404882fc7 Update AssetBundleDebugger
调试窗口增加资源对象的加载耗时统计和显示
2022-10-22 17:47:06 +08:00
hevinci
ec1c3d6070 Update runtime code 2022-10-22 17:46:46 +08:00
hevinci
8eb7816e30 Update AssetBundleDebugger
界面增加了包裹名称显示列。
2022-10-22 15:39:26 +08:00
hevinci
c196e44bc6 Update runtime code 2022-10-22 15:38:51 +08:00
hevinci
989d88f7d3 Update runtime code
修复资源回收无效的问题。
2022-10-22 15:37:53 +08:00
hevinci
cb4ebb6306 Update document 2022-10-22 10:51:14 +08:00
hevinci
92e7ec9682 Update CHANGELOG.md 2022-10-22 10:03:41 +08:00
hevinci
32b7ff1b36 Update package.json 2022-10-22 10:03:16 +08:00
hevinci
5a68ef558f Update YooAssets.cs 2022-10-22 10:03:12 +08:00
hevinci
18d48ae963 update collector window
点击修复按钮后自动刷新界面
2022-10-21 18:46:04 +08:00
hevinci
d61c723933 update basic sample 2022-10-21 18:36:28 +08:00
hevinci
bb64ff7278 update runtime code
移除了ILocationServices接口类。
增加了bool CheckLocationValid(string location)方法。
2022-10-21 18:36:03 +08:00
hevinci
d7760cd34d update diagnostic system 2022-10-21 16:49:58 +08:00
hevinci
f9ecad1cf0 Update download system
增加证书认证方法
2022-10-21 15:18:16 +08:00
hevinci
a6de89ab74 Update runtime code 2022-10-19 19:30:50 +08:00
hevinci
e663dcf83b Update document 2022-10-19 19:12:22 +08:00
hevinci
88e8e5cd54 Update AssetBundleCollector 2022-10-19 19:11:57 +08:00
hevinci
9b43d36793 Update basic sample 2022-10-19 18:57:38 +08:00
hevinci
794314a8e1 Update AssetBundleCollector 2022-10-19 18:57:00 +08:00
hevinci
0a1c40cee5 Update download system
增加SetDownloadSystemClearFileResponseCode()新方法
2022-10-19 18:18:32 +08:00
hevinci
958cdd25a5 Update AssetBundleBuilder 2022-10-19 15:54:59 +08:00
hevinci
2fb77c1bf8 Update ShaderVariantCollector 2022-10-19 15:52:46 +08:00
hevinci
3aa46664f7 Update AssetBundleReporter 2022-10-19 15:52:32 +08:00
hevinci
8389ce5793 Update AssetBundleCollector 2022-10-19 15:52:16 +08:00
hevinci
5199430766 Update document 2022-10-18 19:27:47 +08:00
102 changed files with 1412 additions and 700 deletions

View File

@@ -2,6 +2,91 @@
All notable changes to this package will be documented in this file.
## [1.3.3] - 2022-10-27
### Fixed
- 修复了资源回收方法无效的问题。
### Added
- 新增了PackageVersion构建参数。
````c#
public class BuildParameters
{
/// <summary>
/// 构建的包裹版本
/// </summary>
public string PackageVersion;
}
````
### Changed
- AssetBundleDebugger窗口增加了包裹名称显示列。
- AssetBundleDebugger窗口增加资源对象的加载耗时统计和显示。
- AssetBundleDebugger窗口增加帧调试数据导出功能。
- AssetBundleBuilder构建流程增加输出目录文件路径过长的检测。
- 下载器返回的错误提示增加HTTP Response Code。
- UpdateStaticVersionOperation.PackageCRC重名为UpdateStaticVersionOperation.PackageVersion。
- AssetPackage.GetHumanReadableVersion()重名为AssetPackage.GetPackageVersion()
## [1.3.2] - 2022-10-22
### Fixed
- 修复了AssetBundleCollector界面点击修复按钮界面没有刷新的问题。
### Added
- 新增了自定义证书认证方法。
````c#
public static class YooAssets
{
/// <summary>
/// 设置下载系统参数,自定义的证书认证实例
/// </summary>
public static void SetDownloadSystemCertificateHandler(UnityEngine.Networking.CertificateHandler instance)
}
````
- 新增了下载失败后清理文件的方法。
````c#
public static class YooAssets
{
/// <summary>
/// 设置下载系统参数下载失败后清理文件的HTTP错误码
/// </summary>
public static void SetDownloadSystemClearFileResponseCode(List<long> codes)
}
````
- 新增了检查资源定位地址是否有效的方法。
```c#
public class AssetsPackage
{
/// <summary>
/// 检查资源定位地址是否有效
/// </summary>
/// <param name="location">资源的定位地址</param>
public bool CheckLocationValid(string location)
}
```
### Removed
- 移除了ILocationServices接口类和初始化字段。
- 移除了AssetPackage.GetAssetPath(string location)方法。
- 移除了BuildParameters.EnableAddressable字段。
### Changed
- AssetBundleCollector配置增加了UniqueBundleName设置用于解决不同包裹之间Bundle名称冲突的问题。
## [1.3.1] - 2022-10-18
### Fixed

View File

@@ -86,7 +86,6 @@ namespace YooAsset.Editor
var buildResult = BuildRunner.Run(pipeline, _buildContext);
if (buildResult.Success)
{
buildResult.OutputPackageCRC = buildParametersContext.OutputPackageCRC;
buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory();
Debug.Log($"{buildParameters.BuildMode} pipeline build succeed !");
}

View File

@@ -75,9 +75,9 @@ namespace YooAsset.Editor
/// <summary>
/// 加载补丁清单文件
/// </summary>
internal static PatchManifest LoadPatchManifestFile(string fileDirectory, string packageName, string packageCRC)
internal static PatchManifest LoadPatchManifestFile(string fileDirectory, string packageName, string packageVersion)
{
string filePath = $"{fileDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC)}";
string filePath = $"{fileDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(packageName, packageVersion)}";
if (File.Exists(filePath) == false)
{
throw new System.Exception($"Not found patch manifest file : {filePath}");

View File

@@ -255,9 +255,9 @@ namespace YooAsset.Editor
buildParameters.BuildTarget = _buildTarget;
buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
buildParameters.BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
buildParameters.BuildPackage = AssetBundleBuilderSettingData.Setting.BuildPackage;
buildParameters.PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage;
buildParameters.PackageVersion = GetDefaultPackageVersion();
buildParameters.VerifyBuildingResult = true;
buildParameters.EnableAddressable = AssetBundleCollectorSettingData.Setting.EnableAddressable;
buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption;
buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle;
@@ -277,6 +277,11 @@ namespace YooAsset.Editor
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
private string GetDefaultPackageVersion()
{
int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
return DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes;
}
// 构建包裹相关
private int GetDefaultPackageIndex(string packageName)

View File

@@ -14,15 +14,15 @@ namespace YooAsset.Editor
buildParameters.OutputRoot = defaultOutputRoot;
buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
buildParameters.BuildMode = EBuildMode.SimulateBuild;
buildParameters.BuildPackage = packageName;
buildParameters.EnableAddressable = AssetBundleCollectorSettingData.Setting.EnableAddressable;
buildParameters.PackageName = packageName;
buildParameters.PackageVersion = "Simulate";
AssetBundleBuilder builder = new AssetBundleBuilder();
var buildResult = builder.Run(buildParameters);
if (buildResult.Success)
{
string pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(buildParameters.OutputRoot, buildParameters.BuildPackage, buildParameters.BuildTarget, buildParameters.BuildMode);
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.BuildPackage, buildResult.OutputPackageCRC);
string pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(buildParameters.OutputRoot, buildParameters.PackageName, buildParameters.BuildTarget, buildParameters.BuildMode);
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string manifestFilePath = $"{pipelineOutputDirectory}/{manifestFileName}";
return manifestFilePath;
}

View File

@@ -166,7 +166,7 @@ namespace YooAsset.Editor
/// <summary>
/// 计算主资源或共享资源的完整包名
/// </summary>
public void CalculateFullBundleName()
public void CalculateFullBundleName(bool uniqueBundleName, string packageName)
{
if (CollectorType == ECollectorType.None)
{
@@ -177,15 +177,22 @@ namespace YooAsset.Editor
{
string shareBundleName = YooAssetSettingsData.GetUnityShadersBundleFullName();
_shareBundleName = EditorTools.GetRegularPath(shareBundleName).ToLower();
return;
}
else
{
if (_referenceBundleNames.Count > 1)
{
IPackRule packRule = PackDirectory.StaticPackRule;
var bundleName = packRule.GetBundleName(new PackRuleData(AssetPath));
var shareBundleName = $"share_{bundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}";
_shareBundleName = EditorTools.GetRegularPath(shareBundleName).ToLower();
}
}
if (_referenceBundleNames.Count > 1)
if (uniqueBundleName)
{
IPackRule packRule = PackDirectory.StaticPackRule;
var bundleName = packRule.GetBundleName(new PackRuleData(AssetPath));
var shareBundleName = $"share_{bundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}";
_shareBundleName = EditorTools.GetRegularPath(shareBundleName).ToLower();
if (string.IsNullOrEmpty(_shareBundleName) == false)
_shareBundleName = $"{packageName.ToLower()}_{_shareBundleName}";
}
}
else

View File

@@ -14,6 +14,16 @@ namespace YooAsset.Editor
/// </summary>
public int AssetFileCount;
/// <summary>
/// 是否启用可寻址资源定位
/// </summary>
public bool EnableAddressable;
/// <summary>
/// 资源包名唯一化
/// </summary>
public bool UniqueBundleName;
/// <summary>
/// 资源包列表
/// </summary>

View File

@@ -19,7 +19,8 @@ namespace YooAsset.Editor
AssetBundleCollectorSettingData.Setting.CheckConfigError();
// 2. 获取所有收集器收集的资源
List<CollectAssetInfo> allCollectAssets = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName);
var buildResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName);
List<CollectAssetInfo> allCollectAssets = buildResult.CollectAssets;
// 3. 剔除未被引用的依赖资源
List<CollectAssetInfo> removeDependList = new List<CollectAssetInfo>();
@@ -72,9 +73,13 @@ namespace YooAsset.Editor
}
}
}
context.AssetFileCount = buildAssetDic.Count;
// 6. 填充主动收集资源的依赖列表
// 6. 记录关键信息
context.AssetFileCount = buildAssetDic.Count;
context.EnableAddressable = buildResult.EnableAddressable;
context.UniqueBundleName = buildResult.UniqueBundleName;
// 7. 填充主动收集资源的依赖列表
foreach (var collectAssetInfo in allCollectAssets)
{
var dependAssetInfos = new List<BuildAssetInfo>(collectAssetInfo.DependAssets.Count);
@@ -88,13 +93,13 @@ namespace YooAsset.Editor
buildAssetDic[collectAssetInfo.AssetPath].SetAllDependAssetInfos(dependAssetInfos);
}
// 7. 计算完整的资源包名
// 8. 计算完整的资源包名
foreach (KeyValuePair<string, BuildAssetInfo> pair in buildAssetDic)
{
pair.Value.CalculateFullBundleName();
pair.Value.CalculateFullBundleName(buildResult.UniqueBundleName, buildResult.PackageName);
}
// 8. 移除不参与构建的资源
// 9. 移除不参与构建的资源
List<BuildAssetInfo> removeBuildList = new List<BuildAssetInfo>();
foreach (KeyValuePair<string, BuildAssetInfo> pair in buildAssetDic)
{
@@ -107,7 +112,7 @@ namespace YooAsset.Editor
buildAssetDic.Remove(removeValue.AssetPath);
}
// 9. 构建资源包
// 10. 构建资源包
var allBuildinAssets = buildAssetDic.Values.ToList();
if (allBuildinAssets.Count == 0)
throw new Exception("构建的资源列表不能为空");

View File

@@ -57,26 +57,21 @@ namespace YooAsset.Editor
public EBuildMode BuildMode;
/// <summary>
/// 构建的Package名称
/// 构建的包裹名称
/// </summary>
public string BuildPackage;
public string PackageName;
/// <summary>
/// 人类可读的版本信息
/// 构建的包裹版本
/// </summary>
public string HumanReadableVersion;
public string PackageVersion;
/// <summary>
/// 验证构建结果
/// </summary>
public bool VerifyBuildingResult = false;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
public bool EnableAddressable = false;
/// <summary>
/// 加密类
/// </summary>

View File

@@ -11,30 +11,12 @@ namespace YooAsset.Editor
private string _pipelineOutputDirectory = string.Empty;
private string _packageOutputDirectory = string.Empty;
private string _outputPackageCRC = string.Empty;
/// <summary>
/// 构建参数
/// </summary>
public BuildParameters Parameters { private set; get; }
/// <summary>
/// 构建输出的包裹清单哈希值
/// </summary>
public string OutputPackageCRC
{
get
{
if (string.IsNullOrEmpty(_outputPackageCRC))
throw new Exception("Output package file CRC32 is empty !");
return _outputPackageCRC;
}
set
{
_outputPackageCRC = value;
}
}
public BuildParametersContext(BuildParameters parameters)
{
@@ -49,7 +31,7 @@ namespace YooAsset.Editor
{
if (string.IsNullOrEmpty(_pipelineOutputDirectory))
{
_pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(Parameters.OutputRoot, Parameters.BuildPackage, Parameters.BuildTarget, Parameters.BuildMode);
_pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(Parameters.OutputRoot, Parameters.PackageName, Parameters.BuildTarget, Parameters.BuildMode);
}
return _pipelineOutputDirectory;
}
@@ -61,7 +43,7 @@ namespace YooAsset.Editor
{
if (string.IsNullOrEmpty(_packageOutputDirectory))
{
_packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.BuildPackage}/{Parameters.BuildTarget}/{OutputPackageCRC}";
_packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.PackageName}/{Parameters.BuildTarget}/{Parameters.PackageVersion}";
}
return _packageOutputDirectory;
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace YooAsset.Editor
@@ -56,6 +57,9 @@ namespace YooAsset.Editor
public static void Serialize(string savePath, BuildReport buildReport)
{
if (File.Exists(savePath))
File.Delete(savePath);
string json = JsonUtility.ToJson(buildReport, true);
FileUtility.CreateFile(savePath, json);
}

View File

@@ -44,15 +44,25 @@ namespace YooAsset.Editor
public EBuildMode BuildMode;
/// <summary>
/// 构建包裹
/// 构建包裹名称
/// </summary>
public string BuildPackage;
public string BuildPackageName;
/// <summary>
/// 构建包裹版本
/// </summary>
public string BuildPackageVersion;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
public bool EnableAddressable;
/// <summary>
/// 资源包名唯一化
/// </summary>
public bool UniqueBundleName;
/// <summary>
/// 加密服务类名称
/// </summary>

View File

@@ -25,10 +25,5 @@ namespace YooAsset.Editor
/// 输出的补丁包目录
/// </summary>
public string OutputPackageDirectory;
/// <summary>
/// 输出的包裹清单哈希值
/// </summary>
public string OutputPackageCRC;
}
}

View File

@@ -26,11 +26,11 @@ namespace YooAsset.Editor
ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
string streamingAssetsDirectory = AssetBundleBuilderHelper.GetStreamingAssetsFolderPath();
string buildPackageName = buildParametersContext.Parameters.BuildPackage;
string outputPackageCRC = buildParametersContext.OutputPackageCRC;
string buildPackageName = buildParametersContext.Parameters.PackageName;
string buildPackageVersion = buildParametersContext.Parameters.PackageVersion;
// 加载补丁清单
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(packageOutputDirectory, buildPackageName, outputPackageCRC);
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(packageOutputDirectory, buildPackageName, buildPackageVersion);
// 清空流目录
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags)
@@ -40,17 +40,25 @@ namespace YooAsset.Editor
// 拷贝补丁清单文件
{
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildPackageName, outputPackageCRC);
string sourcePath = $"{packageOutputDirectory}/{manifestFileName}";
string destPath = $"{streamingAssetsDirectory}/{manifestFileName}";
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildPackageName, buildPackageVersion);
string sourcePath = $"{packageOutputDirectory}/{fileName}";
string destPath = $"{streamingAssetsDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝静态版本文件
// 拷贝补丁清单哈希文件
{
string versionFileName = YooAssetSettingsData.GetStaticVersionFileName(buildPackageName);
string sourcePath = $"{packageOutputDirectory}/{versionFileName}";
string destPath = $"{streamingAssetsDirectory}/{versionFileName}";
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildPackageName, buildPackageVersion);
string sourcePath = $"{packageOutputDirectory}/{fileName}";
string destPath = $"{streamingAssetsDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝补丁清单版本文件
{
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildPackageName);
string sourcePath = $"{packageOutputDirectory}/{fileName}";
string destPath = $"{streamingAssetsDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}

View File

@@ -21,6 +21,7 @@ namespace YooAsset.Editor
/// </summary>
private void CreatePatchManifestFile(BuildContext context)
{
var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
@@ -28,42 +29,48 @@ namespace YooAsset.Editor
// 创建新补丁清单
PatchManifest patchManifest = new PatchManifest();
patchManifest.FileVersion = YooAssetSettings.PatchManifestFileVersion;
patchManifest.EnableAddressable = buildParameters.EnableAddressable;
patchManifest.EnableAddressable = buildMapContext.EnableAddressable;
patchManifest.OutputNameStyle = (int)buildParameters.OutputNameStyle;
patchManifest.PackageName = buildParameters.BuildPackage;
patchManifest.HumanReadableVersion = buildParameters.HumanReadableVersion;
patchManifest.PackageName = buildParameters.PackageName;
patchManifest.PackageVersion = buildParameters.PackageVersion;
patchManifest.BundleList = GetAllPatchBundle(context);
patchManifest.AssetList = GetAllPatchAsset(context, patchManifest);
// 更新Unity内置资源包的引用关系
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
if(buildParameters.BuildMode == EBuildMode.IncrementalBuild)
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
{
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results);
}
}
// 创建补丁清单文件
string manifestFileTempName = YooAssetSettingsData.GetPatchManifestTempFileName(buildParameters.BuildPackage);
string manifestFileTempPath = $"{pipelineOutputDirectory}/{manifestFileTempName}";
BuildRunner.Log($"创建补丁清单文件:{manifestFileTempPath}");
PatchManifest.Serialize(manifestFileTempPath, patchManifest);
string packageHash = string.Empty;
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{pipelineOutputDirectory}/{fileName}";
PatchManifest.Serialize(filePath, patchManifest);
packageHash = HashUtility.FileMD5(filePath);
BuildRunner.Log($"创建补丁清单文件:{filePath}");
}
// 计算补丁清单文件的CRC32
buildParametersContext.OutputPackageCRC = HashUtility.FileCRC32(manifestFileTempPath);
// 创建补丁清单哈希文件
{
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{pipelineOutputDirectory}/{fileName}";
FileUtility.CreateFile(filePath, packageHash);
BuildRunner.Log($"创建补丁清单哈希文件:{filePath}");
}
// 补丁清单文件重命名
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
string manifestFilePath = $"{pipelineOutputDirectory}/{manifestFileName}";
EditorTools.FileMoveTo(manifestFileTempPath, manifestFilePath);
// 创建静态版本文件
string staticVersionFileName = YooAssetSettingsData.GetStaticVersionFileName(buildParameters.BuildPackage);
string staticVersionFilePath = $"{pipelineOutputDirectory}/{staticVersionFileName}";
BuildRunner.Log($"创建静态版本文件:{staticVersionFilePath}");
FileUtility.CreateFile(staticVersionFilePath, buildParametersContext.OutputPackageCRC);
// 创建补丁清单版本文件
{
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildParameters.PackageName);
string filePath = $"{pipelineOutputDirectory}/{fileName}";
FileUtility.CreateFile(filePath, buildParameters.PackageVersion);
BuildRunner.Log($"创建补丁清单版本文件:{filePath}");
}
}
/// <summary>
@@ -71,17 +78,22 @@ namespace YooAsset.Editor
/// </summary>
private List<PatchBundle> GetAllPatchBundle(BuildContext context)
{
var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
var encryptionContext = context.GetContextObject<TaskEncryption.EncryptionContext>();
List<PatchBundle> result = new List<PatchBundle>(1000);
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
// NOTE检测路径长度不要超过260字符。
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
if (filePath.Length >= 260)
throw new Exception($"The output bundle name is too long {filePath.Length} chars : {filePath}");
var bundleName = bundleInfo.BundleName;
string fileHash = GetBundleFileHash(bundleInfo, buildParameters);
string fileCRC = GetBundleFileCRC(bundleInfo, buildParameters);
long fileSize = GetBundleFileSize(bundleInfo, buildParameters);
string fileHash = GetBundleFileHash(bundleInfo, buildParametersContext);
string fileCRC = GetBundleFileCRC(bundleInfo, buildParametersContext);
long fileSize = GetBundleFileSize(bundleInfo, buildParametersContext);
string[] tags = buildMapContext.GetBundleTags(bundleName);
bool isEncrypted = encryptionContext.IsEncryptFile(bundleName);
bool isRawFile = bundleInfo.IsRawFile;
@@ -125,7 +137,6 @@ namespace YooAsset.Editor
/// </summary>
private List<PatchAsset> GetAllPatchAsset(BuildContext context, PatchManifest patchManifest)
{
var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
List<PatchAsset> result = new List<PatchAsset>(1000);
@@ -135,7 +146,7 @@ namespace YooAsset.Editor
foreach (var assetInfo in assetInfos)
{
PatchAsset patchAsset = new PatchAsset();
if (buildParameters.Parameters.EnableAddressable)
if (buildMapContext.EnableAddressable)
patchAsset.Address = assetInfo.Address;
else
patchAsset.Address = string.Empty;

View File

@@ -28,25 +28,33 @@ namespace YooAsset.Editor
// 拷贝Report文件
{
string reportFileName = YooAssetSettingsData.GetReportFileName(buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
string sourcePath = $"{pipelineOutputDirectory}/{reportFileName}";
string destPath = $"{packageOutputDirectory}/{reportFileName}";
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string sourcePath = $"{pipelineOutputDirectory}/{fileName}";
string destPath = $"{packageOutputDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝补丁清单文件
{
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
string sourcePath = $"{pipelineOutputDirectory}/{manifestFileName}";
string destPath = $"{packageOutputDirectory}/{manifestFileName}";
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string sourcePath = $"{pipelineOutputDirectory}/{fileName}";
string destPath = $"{packageOutputDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝静态版本文件
// 拷贝补丁清单哈希文件
{
string versionFileName = YooAssetSettingsData.GetStaticVersionFileName(buildParameters.BuildPackage);
string sourcePath = $"{pipelineOutputDirectory}/{versionFileName}";
string destPath = $"{packageOutputDirectory}/{versionFileName}";
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string sourcePath = $"{pipelineOutputDirectory}/{fileName}";
string destPath = $"{packageOutputDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝补丁清单版本文件
{
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildParameters.PackageName);
string sourcePath = $"{pipelineOutputDirectory}/{fileName}";
string destPath = $"{packageOutputDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
@@ -86,7 +94,7 @@ namespace YooAsset.Editor
// 拷贝所有补丁文件
int progressValue = 0;
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildParameters.PackageName, buildParameters.PackageVersion);
int patchFileTotalCount = patchManifest.BundleList.Count;
foreach (var patchBundle in patchManifest.BundleList)
{

View File

@@ -29,7 +29,7 @@ namespace YooAsset.Editor
var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildParameters.PackageName, buildParameters.PackageVersion);
BuildReport buildReport = new BuildReport();
// 概述信息
@@ -45,8 +45,11 @@ namespace YooAsset.Editor
buildReport.Summary.BuildTarget = buildParameters.BuildTarget;
buildReport.Summary.BuildPipeline = buildParameters.BuildPipeline;
buildReport.Summary.BuildMode = buildParameters.BuildMode;
buildReport.Summary.BuildPackage = buildParameters.BuildPackage;
buildReport.Summary.EnableAddressable = buildParameters.EnableAddressable;
buildReport.Summary.BuildPackageName = buildParameters.PackageName;
buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion;
buildReport.Summary.EnableAddressable = buildMapContext.EnableAddressable;
buildReport.Summary.UniqueBundleName = buildMapContext.UniqueBundleName;
buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ?
"null" : buildParameters.EncryptionServices.GetType().FullName;
@@ -99,13 +102,9 @@ namespace YooAsset.Editor
buildReport.BundleInfos.Add(reportBundleInfo);
}
// 删除旧文件
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
string filePath = $"{pipelineOutputDirectory}/{fileName}";
if (File.Exists(filePath))
File.Delete(filePath);
// 序列化文件
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{pipelineOutputDirectory}/{fileName}";
BuildReport.Serialize(filePath, buildReport);
BuildRunner.Log($"资源构建报告文件创建完成:{filePath}");
}

View File

@@ -13,7 +13,7 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = BuildMapCreater.CreateBuildMap(buildParametersContext.Parameters.BuildMode, buildParametersContext.Parameters.BuildPackage);
var buildMapContext = BuildMapCreater.CreateBuildMap(buildParametersContext.Parameters.BuildMode, buildParametersContext.Parameters.PackageName);
context.SetContextObject(buildMapContext);
BuildRunner.Log("构建内容准备完毕!");

View File

@@ -19,8 +19,10 @@ namespace YooAsset.Editor
// 检测构建参数合法性
if (buildParameters.BuildTarget == BuildTarget.NoTarget)
throw new Exception("请选择目标平台");
if (string.IsNullOrEmpty(buildParameters.BuildPackage))
if (string.IsNullOrEmpty(buildParameters.PackageName))
throw new Exception("包裹名称不能为空");
if(string.IsNullOrEmpty(buildParameters.PackageVersion))
throw new Exception("包裹版本不能为空");
if (buildParameters.BuildMode != EBuildMode.SimulateBuild)
{
@@ -40,6 +42,11 @@ namespace YooAsset.Editor
throw new Exception("首包资源标签不能为空!");
}
// 检测包裹输出目录是否存在
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
if (Directory.Exists(packageOutputDirectory))
throw new Exception($"本次构建的补丁目录已经存在:{packageOutputDirectory}");
// 保存改动的资源
AssetDatabase.SaveAssets();
}
@@ -47,7 +54,7 @@ namespace YooAsset.Editor
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
{
// 删除平台总目录
string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.BuildPackage}/{buildParameters.BuildTarget}";
string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.PackageName}/{buildParameters.BuildTarget}";
if (EditorTools.DeleteDirectory(platformDirectory))
{
BuildRunner.Log($"删除平台总目录:{platformDirectory}");

View File

@@ -62,6 +62,7 @@ namespace YooAsset.Editor
}
// 4. 验证Asset
/*
bool isPass = true;
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
@@ -98,6 +99,7 @@ namespace YooAsset.Editor
throw new Exception("构建结果验证没有通过,请参考警告日志!");
}
}
*/
BuildRunner.Log("构建结果验证成功!");
}

View File

@@ -132,10 +132,10 @@ namespace YooAsset.Editor
/// <summary>
/// 获取打包收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, bool enableAddressable, AssetBundleCollectorGroup group)
public List<CollectAssetInfo> GetAllCollectAssets(CollectCommand command, AssetBundleCollectorGroup group)
{
// 注意:模拟构建模式下只收集主资源
if (buildMode == EBuildMode.SimulateBuild)
if (command.BuildMode == EBuildMode.SimulateBuild)
{
if (CollectorType != ECollectorType.MainAssetCollector)
return new List<CollectAssetInfo>();
@@ -162,7 +162,7 @@ namespace YooAsset.Editor
{
if (result.ContainsKey(assetPath) == false)
{
var collectAssetInfo = CreateCollectAssetInfo(buildMode, group, assetPath, isRawAsset);
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset);
result.Add(assetPath, collectAssetInfo);
}
else
@@ -177,7 +177,7 @@ namespace YooAsset.Editor
string assetPath = CollectPath;
if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath))
{
var collectAssetInfo = CreateCollectAssetInfo(buildMode, group, assetPath, isRawAsset);
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset);
result.Add(assetPath, collectAssetInfo);
}
else
@@ -187,7 +187,7 @@ namespace YooAsset.Editor
}
// 检测可寻址地址是否重复
if (enableAddressable)
if (command.EnableAddressable)
{
HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result)
@@ -207,7 +207,7 @@ namespace YooAsset.Editor
return result.Values.ToList();
}
private CollectAssetInfo CreateCollectAssetInfo(EBuildMode buildMode, AssetBundleCollectorGroup group, string assetPath, bool isRawAsset)
private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawAsset)
{
string address = GetAddress(group, assetPath);
string bundleName = GetBundleName(group, assetPath);
@@ -215,7 +215,7 @@ namespace YooAsset.Editor
CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, assetTags, isRawAsset);
// 注意:模拟构建模式下不需要收集依赖资源
if (buildMode == EBuildMode.SimulateBuild)
if (command.BuildMode == EBuildMode.SimulateBuild)
collectAssetInfo.DependAssets = new List<string>();
else
collectAssetInfo.DependAssets = GetAllDependencies(assetPath);

View File

@@ -10,11 +10,12 @@ namespace YooAsset.Editor
{
public class AssetBundleCollectorConfig
{
public const string ConfigVersion = "2.0";
public const string ConfigVersion = "2.1";
public const string XmlVersion = "Version";
public const string XmlCommon = "Common";
public const string XmlEnableAddressable = "AutoAddressable";
public const string XmlUniqueBundleName = "UniqueBundleName";
public const string XmlShowPackageView = "ShowPackageView";
public const string XmlPackage = "Package";
@@ -62,6 +63,7 @@ namespace YooAsset.Editor
// 读取公共配置
bool enableAddressable = false;
bool uniqueBundleName = false;
bool showPackageView = false;
var commonNodeList = root.GetElementsByTagName(XmlCommon);
if (commonNodeList.Count > 0)
@@ -69,10 +71,13 @@ namespace YooAsset.Editor
XmlElement commonElement = commonNodeList[0] as XmlElement;
if (commonElement.HasAttribute(XmlEnableAddressable) == false)
throw new Exception($"Not found attribute {XmlEnableAddressable} in {XmlCommon}");
if (commonElement.HasAttribute(XmlUniqueBundleName) == false)
throw new Exception($"Not found attribute {XmlUniqueBundleName} in {XmlCommon}");
if (commonElement.HasAttribute(XmlShowPackageView) == false)
throw new Exception($"Not found attribute {XmlShowPackageView} in {XmlCommon}");
enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false;
uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false;
showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false;
}
@@ -146,6 +151,7 @@ namespace YooAsset.Editor
// 保存配置数据
AssetBundleCollectorSettingData.ClearAll();
AssetBundleCollectorSettingData.Setting.EnableAddressable = enableAddressable;
AssetBundleCollectorSettingData.Setting.UniqueBundleName = uniqueBundleName;
AssetBundleCollectorSettingData.Setting.ShowPackageView = showPackageView;
AssetBundleCollectorSettingData.Setting.Packages.AddRange(packages);
AssetBundleCollectorSettingData.SaveFile();
@@ -175,6 +181,7 @@ namespace YooAsset.Editor
// 设置公共配置
var commonElement = xmlDoc.CreateElement(XmlCommon);
commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.ToString());
commonElement.SetAttribute(XmlUniqueBundleName, AssetBundleCollectorSettingData.Setting.UniqueBundleName.ToString());
commonElement.SetAttribute(XmlShowPackageView, AssetBundleCollectorSettingData.Setting.ShowPackageView.ToString());
root.AppendChild(commonElement);
@@ -269,7 +276,23 @@ namespace YooAsset.Editor
// 更新版本
root.SetAttribute(XmlVersion, "2.0");
return UpdateXmlConfig(xmlDoc);
}
// 2.0 -> 2.1
if (configVersion == "2.0")
{
// 添加公共元素属性
var commonNodeList = root.GetElementsByTagName(XmlCommon);
if (commonNodeList.Count > 0)
{
XmlElement commonElement = commonNodeList[0] as XmlElement;
if (commonElement.HasAttribute(XmlUniqueBundleName) == false)
commonElement.SetAttribute(XmlUniqueBundleName, "False");
}
// 更新版本
root.SetAttribute(XmlVersion, "2.1");
return UpdateXmlConfig(xmlDoc);
}

View File

@@ -69,7 +69,7 @@ namespace YooAsset.Editor
/// <summary>
/// 获取打包收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, bool enableAddressable)
public List<CollectAssetInfo> GetAllCollectAssets(CollectCommand command)
{
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(10000);
@@ -83,7 +83,7 @@ namespace YooAsset.Editor
// 收集打包资源
foreach (var collector in Collectors)
{
var temper = collector.GetAllCollectAssets(buildMode, enableAddressable, this);
var temper = collector.GetAllCollectAssets(command, this);
foreach (var assetInfo in temper)
{
if (result.ContainsKey(assetInfo.AssetPath) == false)
@@ -94,7 +94,7 @@ namespace YooAsset.Editor
}
// 检测可寻址地址是否重复
if (enableAddressable)
if (command.EnableAddressable)
{
HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result)

View File

@@ -56,14 +56,14 @@ namespace YooAsset.Editor
/// <summary>
/// 获取打包收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, bool enableAddressable)
public List<CollectAssetInfo> GetAllCollectAssets(CollectCommand command)
{
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(10000);
// 收集打包资源
foreach (var group in Groups)
{
var temper = group.GetAllCollectAssets(buildMode, enableAddressable);
var temper = group.GetAllCollectAssets(command);
foreach (var assetInfo in temper)
{
if (result.ContainsKey(assetInfo.AssetPath) == false)
@@ -74,7 +74,7 @@ namespace YooAsset.Editor
}
// 检测可寻址地址是否重复
if (enableAddressable)
if (command.EnableAddressable)
{
HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result)

View File

@@ -9,7 +9,7 @@ namespace YooAsset.Editor
public class AssetBundleCollectorSetting : ScriptableObject
{
/// <summary>
/// 是否显示包裹视图
/// 是否显示包裹列表视图
/// </summary>
public bool ShowPackageView = false;
@@ -18,6 +18,11 @@ namespace YooAsset.Editor
/// </summary>
public bool EnableAddressable = false;
/// <summary>
/// 资源包名唯一化
/// </summary>
public bool UniqueBundleName = false;
/// <summary>
/// 包裹列表
/// </summary>
@@ -76,37 +81,43 @@ namespace YooAsset.Editor
Debug.LogWarning($"Not found package : {packageName}");
return new List<string>();
}
/// <summary>
/// 获取包裹收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetPackageAssets(EBuildMode buildMode, string packageName)
public CollectResult GetPackageAssets(EBuildMode buildMode, string packageName)
{
if (string.IsNullOrEmpty(packageName))
throw new Exception("Build Package name is null or mepty !");
throw new Exception("Build package name is null or mepty !");
foreach (var package in Packages)
{
if (package.PackageName == packageName)
{
return package.GetAllCollectAssets(buildMode, EnableAddressable);
CollectCommand command = new CollectCommand(buildMode, EnableAddressable);
CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName);
collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
return collectResult;
}
}
throw new Exception($"Not found collector pacakge : {packageName}");
}
/// <summary>
/// 获取所有包裹收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetAllPackageAssets(EBuildMode buildMode)
public List<CollectResult> GetAllPackageAssets(EBuildMode buildMode)
{
List<CollectAssetInfo> result = new List<CollectAssetInfo>(1000);
List<CollectResult> collectResultList = new List<CollectResult>(1000);
foreach (var package in Packages)
{
var temper = package.GetAllCollectAssets(buildMode, EnableAddressable);
result.AddRange(temper);
CollectCommand command = new CollectCommand(buildMode, EnableAddressable);
CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName);
collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
collectResultList.Add(collectResult);
}
return result;
return collectResultList;
}
}
}

View File

@@ -347,14 +347,20 @@ namespace YooAsset.Editor
Setting.EnableAddressable = enableAddressable;
IsDirty = true;
}
public static void ModifyUniqueBundleName(bool uniqueBundleName)
{
Setting.UniqueBundleName = uniqueBundleName;
IsDirty = true;
}
// 资源包裹编辑相关
public static void CreatePackage(string packageName)
public static AssetBundleCollectorPackage CreatePackage(string packageName)
{
AssetBundleCollectorPackage package = new AssetBundleCollectorPackage();
package.PackageName = packageName;
Setting.Packages.Add(package);
IsDirty = true;
return package;
}
public static void RemovePackage(AssetBundleCollectorPackage package)
{
@@ -376,12 +382,13 @@ namespace YooAsset.Editor
}
// 资源分组编辑相关
public static void CreateGroup(AssetBundleCollectorPackage package, string groupName)
public static AssetBundleCollectorGroup CreateGroup(AssetBundleCollectorPackage package, string groupName)
{
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
group.GroupName = groupName;
package.Groups.Add(group);
IsDirty = true;
return group;
}
public static void RemoveGroup(AssetBundleCollectorPackage package, AssetBundleCollectorGroup group)
{

View File

@@ -27,6 +27,7 @@ namespace YooAsset.Editor
private Toggle _showPackageToogle;
private Toggle _enableAddressableToogle;
private Toggle _uniqueBundleNameToogle;
private VisualElement _packageContainer;
private ListView _packageListView;
@@ -87,6 +88,12 @@ namespace YooAsset.Editor
AssetBundleCollectorSettingData.ModifyAddressable(evt.newValue);
RefreshWindow();
});
_uniqueBundleNameToogle = root.Q<Toggle>("UniqueBundleName");
_uniqueBundleNameToogle.RegisterValueChangedCallback(evt =>
{
AssetBundleCollectorSettingData.ModifyUniqueBundleName(evt.newValue);
RefreshWindow();
});
// 配置修复按钮
var fixBtn = root.Q<Button>("FixButton");
@@ -289,6 +296,7 @@ namespace YooAsset.Editor
private void FixBtn_clicked()
{
AssetBundleCollectorSettingData.FixFile();
RefreshWindow();
}
private void ExportBtn_clicked()
{
@@ -733,8 +741,8 @@ namespace YooAsset.Editor
try
{
bool enableAdressable = AssetBundleCollectorSettingData.Setting.EnableAddressable;
collectAssetInfos = collector.GetAllCollectAssets(EBuildMode.DryRunBuild, enableAdressable, group);
CollectCommand command = new CollectCommand(EBuildMode.DryRunBuild, _enableAddressableToogle.value);
collectAssetInfos = collector.GetAllCollectAssets(command, group);
}
catch (System.Exception e)
{

View File

@@ -8,6 +8,7 @@
<ui:VisualElement name="PublicContainer" style="height: 30px; background-color: rgb(67, 67, 67); flex-direction: row; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:Toggle label="Show Packages" name="ShowPackages" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Unique Bundle Name" name="UniqueBundleName" style="width: 196px; -unity-text-align: middle-left;" />
</ui:VisualElement>
<ui:VisualElement name="ContentContainer" style="flex-grow: 1; flex-direction: row;">
<ui:VisualElement name="PackageContainer" style="width: 200px; flex-grow: 0; background-color: rgb(67, 67, 67); border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">

View File

@@ -50,5 +50,13 @@ namespace YooAsset.Editor
AssetTags = assetTags;
IsRawAsset = isRawAsset;
}
/// <summary>
/// 资源包名称追加包裹名
/// </summary>
public void BundleNameAppendPackageName(string packageName)
{
BundleName = $"{packageName.ToLower()}_{BundleName}";
}
}
}

View File

@@ -0,0 +1,22 @@

namespace YooAsset.Editor
{
public class CollectCommand
{
/// <summary>
/// 构建模式
/// </summary>
public EBuildMode BuildMode { private set; get; }
/// <summary>
/// 是否启用可寻址资源定位
/// </summary>
public bool EnableAddressable { private set; get; }
public CollectCommand(EBuildMode buildMode, bool enableAddressable)
{
BuildMode = buildMode;
EnableAddressable = enableAddressable;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a8d6592eded144142afcf85c79cf1ce4
guid: b1741e85d76b28d41a4da3cd0e3e6f20
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,49 @@
using System.Collections;
using System.Collections.Generic;
namespace YooAsset.Editor
{
public class CollectResult
{
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 是否启用可寻址资源定位
/// </summary>
public bool EnableAddressable { private set; get; }
/// <summary>
/// 资源包名唯一化
/// </summary>
public bool UniqueBundleName { private set; get; }
/// <summary>
/// 收集的资源信息列表
/// </summary>
public List<CollectAssetInfo> CollectAssets { private set; get; }
public CollectResult(string packageName, bool enableAddressable, bool uniqueBundleName)
{
PackageName = packageName;
EnableAddressable = enableAddressable;
UniqueBundleName = uniqueBundleName;
}
public void SetCollectAssets(List<CollectAssetInfo> collectAssets)
{
CollectAssets = collectAssets;
if (UniqueBundleName)
{
foreach (var collectAsset in CollectAssets)
{
collectAsset.BundleNameAppendPackageName(PackageName);
}
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8d996937ba73c9b4bb942b8ba6f43398
guid: dbbd465f929ee33408441b62d19c7d10
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -73,6 +73,10 @@ namespace YooAsset.Editor
var sampleBtn = root.Q<Button>("SampleButton");
sampleBtn.clicked += SampleBtn_onClick;
// 导出按钮
var exportBtn = root.Q<Button>("ExportButton");
exportBtn.clicked += ExportBtn_clicked;
// 用户列表菜单
_playerName = root.Q<Label>("PlayerName");
_playerName.text = "Editor player";
@@ -251,6 +255,32 @@ namespace YooAsset.Editor
EditorConnection.instance.Send(RemoteDebuggerDefine.kMsgSendEditorToPlayer, data);
RemoteDebuggerInRuntime.EditorRequestDebugReport();
}
private void ExportBtn_clicked()
{
if (_currentReport == null)
{
Debug.LogWarning("Debug report is null.");
return;
}
string resultPath = EditorTools.OpenFolderPanel("Export JSON", "Assets/");
if (resultPath != null)
{
// 注意:排序保证生成配置的稳定性
foreach (var packageData in _currentReport.PackageDatas)
{
packageData.ProviderInfos.Sort();
foreach (var providerInfo in packageData.ProviderInfos)
{
providerInfo.DependBundleInfos.Sort();
}
}
string filePath = $"{resultPath}/{nameof(DebugReport)}_{_currentReport.FrameCount}.json";
string fileContent = JsonUtility.ToJson(_currentReport, true);
FileUtility.CreateFile(filePath, fileContent);
}
}
private void OnSearchKeyWordChange(ChangeEvent<string> e)
{
_searchKeyWord = e.newValue;

View File

@@ -4,6 +4,7 @@
<uie:ToolbarMenu display-tooltip-when-elided="true" name="ViewModeMenu" text="ViewMode" style="width: 100px; flex-grow: 0;" />
<uie:ToolbarSearchField focusable="true" name="SearchField" style="flex-grow: 1;" />
<uie:ToolbarButton text="刷新" display-tooltip-when-elided="true" name="SampleButton" style="width: 70px; background-color: rgb(15, 118, 31); -unity-text-align: middle-center; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-left-width: 1px; border-right-width: 1px;" />
<uie:ToolbarButton text="导出" display-tooltip-when-elided="true" name="ExportButton" style="width: 70px; background-color: rgb(15, 118, 31); -unity-text-align: middle-center; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-left-width: 1px; border-right-width: 1px;" />
</uie:Toolbar>
<uie:Toolbar name="FrameToolbar">
<ui:SliderInt picking-mode="Ignore" label="Frame:" value="42" high-value="100" name="FrameSlider" style="flex-grow: 1;" />

View File

@@ -27,7 +27,7 @@ namespace YooAsset.Editor
_visualAsset = EditorHelper.LoadWindowUXML<DebuggerAssetListViewer>();
if (_visualAsset == null)
return;
_root = _visualAsset.CloneTree();
_root.style.flexGrow = 1f;
@@ -72,15 +72,24 @@ namespace YooAsset.Editor
}
private List<DebugProviderInfo> FilterViewItems(DebugReport debugReport, string searchKeyWord)
{
var result = new List<DebugProviderInfo>(debugReport.ProviderInfos.Count);
foreach (var providerInfo in debugReport.ProviderInfos)
List<DebugProviderInfo> result = new List<DebugProviderInfo>(1000);
foreach (var packageData in debugReport.PackageDatas)
{
if (string.IsNullOrEmpty(searchKeyWord) == false)
var tempList = new List<DebugProviderInfo>(packageData.ProviderInfos.Count);
foreach (var providerInfo in packageData.ProviderInfos)
{
if (providerInfo.AssetPath.Contains(searchKeyWord) == false)
continue;
if (string.IsNullOrEmpty(searchKeyWord) == false)
{
if (providerInfo.AssetPath.Contains(searchKeyWord) == false)
continue;
}
providerInfo.PackageName = packageData.PackageName;
tempList.Add(providerInfo);
}
result.Add(providerInfo);
tempList.Sort();
result.AddRange(tempList);
}
return result;
}
@@ -102,12 +111,22 @@ namespace YooAsset.Editor
}
// 资源列表相关
// 顶部列表相关
private VisualElement MakeAssetListViewItem()
{
VisualElement element = new VisualElement();
element.style.flexDirection = FlexDirection.Row;
{
var label = new Label();
label.name = "Label0";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
//label.style.flexGrow = 1f;
label.style.width = 150;
element.Add(label);
}
{
var label = new Label();
label.name = "Label1";
@@ -144,7 +163,7 @@ namespace YooAsset.Editor
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
//label.style.flexGrow = 1f;
label.style.width = 100;
label.style.width = 150;
element.Add(label);
}
@@ -154,6 +173,16 @@ namespace YooAsset.Editor
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
//label.style.flexGrow = 1f;
label.style.width = 100;
element.Add(label);
}
{
var label = new Label();
label.name = "Label6";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
//label.style.flexGrow = 1f;
label.style.width = 120;
element.Add(label);
}
@@ -165,6 +194,10 @@ namespace YooAsset.Editor
var sourceData = _assetListView.itemsSource as List<DebugProviderInfo>;
var providerInfo = sourceData[index];
// Package Name
var label0 = element.Q<Label>("Label0");
label0.text = providerInfo.PackageName;
// Asset Path
var label1 = element.Q<Label>("Label1");
label1.text = providerInfo.AssetPath;
@@ -177,9 +210,13 @@ namespace YooAsset.Editor
var label3 = element.Q<Label>("Label3");
label3.text = providerInfo.SpawnTime;
// Ref Count
// Loading Time
var label4 = element.Q<Label>("Label4");
label4.text = providerInfo.RefCount.ToString();
label4.text = providerInfo.LoadingTime.ToString();
// Ref Count
var label5 = element.Q<Label>("Label5");
label5.text = providerInfo.RefCount.ToString();
// Status
StyleColor textColor;
@@ -187,9 +224,9 @@ namespace YooAsset.Editor
textColor = new StyleColor(Color.yellow);
else
textColor = label1.style.color;
var label5 = element.Q<Label>("Label5");
label5.text = providerInfo.Status.ToString();
label5.style.color = textColor;
var label6 = element.Q<Label>("Label6");
label6.text = providerInfo.Status.ToString();
label6.style.color = textColor;
}
private void AssetListView_onSelectionChange(IEnumerable<object> objs)
{
@@ -200,7 +237,7 @@ namespace YooAsset.Editor
}
}
// 依赖列表相关
// 底部列表相关
private VisualElement MakeDependListViewItem()
{
VisualElement element = new VisualElement();
@@ -255,11 +292,11 @@ namespace YooAsset.Editor
var label4 = element.Q<Label>("Label4");
label4.text = bundleInfo.Status.ToString();
}
private void FillDependListView(DebugProviderInfo providerInfo)
private void FillDependListView(DebugProviderInfo selectedProviderInfo)
{
_dependListView.Clear();
_dependListView.ClearSelection();
_dependListView.itemsSource = providerInfo.DependBundleInfos;
_dependListView.itemsSource = selectedProviderInfo.DependBundleInfos;
_dependListView.Rebuild();
}
}

View File

@@ -1,11 +1,13 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
<uie:ToolbarButton text="Package Name" display-tooltip-when-elided="true" name="TopBar0" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="Asset Path" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
<uie:ToolbarButton text="Spawn Scene" display-tooltip-when-elided="true" name="TopBar2" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="Spawn Time" display-tooltip-when-elided="true" name="TopBar3" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="Ref Count" display-tooltip-when-elided="true" name="TopBar4" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="Status" display-tooltip-when-elided="true" name="TopBar5" style="width: 120px; -unity-text-align: middle-left;" />
<uie:ToolbarButton text="Loading Time (ms)" display-tooltip-when-elided="true" name="TopBar4" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="Ref Count" display-tooltip-when-elided="true" name="TopBar5" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="Status" display-tooltip-when-elided="true" name="TopBar6" style="width: 120px; -unity-text-align: middle-left;" />
</uie:Toolbar>
<ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
</ui:VisualElement>

View File

@@ -27,14 +27,14 @@ namespace YooAsset.Editor
_visualAsset = EditorHelper.LoadWindowUXML<DebuggerBundleListViewer>();
if (_visualAsset == null)
return;
_root = _visualAsset.CloneTree();
_root.style.flexGrow = 1f;
// 资源包列表
_bundleListView = _root.Q<ListView>("TopListView");
_bundleListView.makeItem = MakeAssetListViewItem;
_bundleListView.bindItem = BindAssetListViewItem;
_bundleListView.makeItem = MakeBundleListViewItem;
_bundleListView.bindItem = BindBundleListViewItem;
#if UNITY_2020_1_OR_NEWER
_bundleListView.onSelectionChange += BundleListView_onSelectionChange;
#else
@@ -46,7 +46,7 @@ namespace YooAsset.Editor
_usingListView.makeItem = MakeIncludeListViewItem;
_usingListView.bindItem = BindIncludeListViewItem;
}
/// <summary>
/// 清空页面
/// </summary>
@@ -72,21 +72,33 @@ namespace YooAsset.Editor
}
private List<DebugBundleInfo> FilterViewItems(DebugReport debugReport, string searchKeyWord)
{
Dictionary<string, DebugBundleInfo> result = new Dictionary<string, DebugBundleInfo>(debugReport.ProviderInfos.Count);
foreach (var providerInfo in debugReport.ProviderInfos)
List<DebugBundleInfo> result = new List<DebugBundleInfo>(1000);
foreach (var pakcageData in debugReport.PackageDatas)
{
foreach (var bundleInfo in providerInfo.DependBundleInfos)
Dictionary<string, DebugBundleInfo> tempDic = new Dictionary<string, DebugBundleInfo>(1000);
foreach (var providerInfo in pakcageData.ProviderInfos)
{
if (string.IsNullOrEmpty(searchKeyWord) == false)
foreach (var bundleInfo in providerInfo.DependBundleInfos)
{
if (bundleInfo.BundleName.Contains(searchKeyWord) == false)
continue;
if (string.IsNullOrEmpty(searchKeyWord) == false)
{
if (bundleInfo.BundleName.Contains(searchKeyWord) == false)
continue;
}
if (tempDic.ContainsKey(bundleInfo.BundleName) == false)
{
bundleInfo.PackageName = pakcageData.PackageName;
tempDic.Add(bundleInfo.BundleName, bundleInfo);
}
}
if (result.ContainsKey(bundleInfo.BundleName) == false)
result.Add(bundleInfo.BundleName, bundleInfo);
}
var tempList = tempDic.Values.ToList();
tempList.Sort();
result.AddRange(tempList);
}
return result.Values.ToList();
return result;
}
/// <summary>
@@ -107,11 +119,21 @@ namespace YooAsset.Editor
// 顶部列表相关
private VisualElement MakeAssetListViewItem()
private VisualElement MakeBundleListViewItem()
{
VisualElement element = new VisualElement();
element.style.flexDirection = FlexDirection.Row;
{
var label = new Label();
label.name = "Label0";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
//label.style.flexGrow = 1f;
label.style.width = 150;
element.Add(label);
}
{
var label = new Label();
label.name = "Label1";
@@ -144,11 +166,15 @@ namespace YooAsset.Editor
return element;
}
private void BindAssetListViewItem(VisualElement element, int index)
private void BindBundleListViewItem(VisualElement element, int index)
{
var sourceData = _bundleListView.itemsSource as List<DebugBundleInfo>;
var bundleInfo = sourceData[index];
// Package Name
var label0 = element.Q<Label>("Label0");
label0.text = bundleInfo.PackageName;
// Bundle Name
var label1 = element.Q<Label>("Label1");
label1.text = bundleInfo.BundleName;
@@ -172,7 +198,7 @@ namespace YooAsset.Editor
foreach (var item in objs)
{
DebugBundleInfo bundleInfo = item as DebugBundleInfo;
FillUsingListView(bundleInfo.BundleName);
FillUsingListView(bundleInfo);
}
}
@@ -259,17 +285,23 @@ namespace YooAsset.Editor
var label5 = element.Q<Label>("Label5");
label5.text = providerInfo.Status.ToString();
}
private void FillUsingListView(string bundleName)
{
private void FillUsingListView(DebugBundleInfo selectedBundleInfo)
{
List<DebugProviderInfo> source = new List<DebugProviderInfo>();
foreach (var providerInfo in _debugReport.ProviderInfos)
foreach (var packageData in _debugReport.PackageDatas)
{
foreach (var bundleInfo in providerInfo.DependBundleInfos)
if (packageData.PackageName == selectedBundleInfo.PackageName)
{
if (bundleInfo.BundleName == bundleName)
foreach (var providerInfo in packageData.ProviderInfos)
{
source.Add(providerInfo);
continue;
foreach (var bundleInfo in providerInfo.DependBundleInfos)
{
if (bundleInfo.BundleName == selectedBundleInfo.BundleName)
{
source.Add(providerInfo);
continue;
}
}
}
}
}

View File

@@ -1,6 +1,7 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
<uie:ToolbarButton text="Package Name" display-tooltip-when-elided="true" name="TopBar0" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="Bundle Name" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
<uie:ToolbarButton text="Ref Count" display-tooltip-when-elided="true" name="TopBar3" style="width: 100px; -unity-text-align: middle-left;" />
<uie:ToolbarButton text="Status" display-tooltip-when-elided="true" name="TopBar4" style="width: 120px; -unity-text-align: middle-left;" />

View File

@@ -40,7 +40,7 @@ namespace YooAsset.Editor
_visualAsset = EditorHelper.LoadWindowUXML<ReporterSummaryViewer>();
if (_visualAsset == null)
return;
_root = _visualAsset.CloneTree();
_root.style.flexGrow = 1f;
@@ -56,7 +56,7 @@ namespace YooAsset.Editor
public void FillViewData(BuildReport buildReport)
{
_buildReport = buildReport;
_items.Clear();
_items.Add(new ItemWrapper("YooAsset版本", buildReport.Summary.YooVersion));
@@ -66,9 +66,11 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper("构建平台", $"{buildReport.Summary.BuildTarget}"));
_items.Add(new ItemWrapper("构建管线", $"{buildReport.Summary.BuildPipeline}"));
_items.Add(new ItemWrapper("构建模式", $"{buildReport.Summary.BuildMode}"));
_items.Add(new ItemWrapper("构建包裹", $"{buildReport.Summary.BuildPackage}"));
_items.Add(new ItemWrapper("包裹名称", buildReport.Summary.BuildPackageName));
_items.Add(new ItemWrapper("包裹版本", buildReport.Summary.BuildPackageVersion));
_items.Add(new ItemWrapper("启用可寻址资源定位", $"{buildReport.Summary.EnableAddressable}"));
_items.Add(new ItemWrapper("资源包名唯一化", $"{buildReport.Summary.UniqueBundleName}"));
_items.Add(new ItemWrapper("加密服务类名称", $"{buildReport.Summary.EncryptionServicesClassName}"));
_items.Add(new ItemWrapper(string.Empty, string.Empty));

View File

@@ -52,7 +52,7 @@ namespace YooAsset.Editor
throw new System.Exception("Shader variant file extension is invalid.");
// 注意先删除再保存否则ShaderVariantCollection内容将无法及时刷新
AssetDatabase.DeleteAsset(ShaderVariantCollectorSettingData.Setting.SavePath);
AssetDatabase.DeleteAsset(ShaderVariantCollectorSettingData.Setting.SavePath);
EditorTools.CreateFileDirectory(saveFilePath);
_saveFilePath = saveFilePath;
_completedCallback = completedCallback;
@@ -87,9 +87,14 @@ namespace YooAsset.Editor
List<string> allAssets = new List<string>(1000);
// 获取所有打包的资源
List<CollectAssetInfo> allCollectInfos = AssetBundleCollectorSettingData.Setting.GetAllPackageAssets(EBuildMode.DryRunBuild);
List<string> collectAssets = allCollectInfos.Select(t => t.AssetPath).ToList();
foreach (var assetPath in collectAssets)
List<CollectAssetInfo> allCollectAssetInfos = new List<CollectAssetInfo>();
List<CollectResult> collectResults = AssetBundleCollectorSettingData.Setting.GetAllPackageAssets(EBuildMode.DryRunBuild);
foreach (var collectResult in collectResults)
{
allCollectAssetInfos.AddRange(collectResult.CollectAssets);
}
List<string> allAssetPath = allCollectAssetInfos.Select(t => t.AssetPath).ToList();
foreach (var assetPath in allAssetPath)
{
string[] depends = AssetDatabase.GetDependencies(assetPath, true);
foreach (var depend in depends)
@@ -97,7 +102,7 @@ namespace YooAsset.Editor
if (allAssets.Contains(depend) == false)
allAssets.Add(depend);
}
EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, collectAssets.Count);
EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, allAssetPath.Count);
}
EditorTools.ClearProgressBar();

View File

@@ -131,6 +131,8 @@ namespace YooAsset
}
_loaders.Clear();
_sceneHandles.Clear();
// 注意:调用底层接口释放所有资源
Resources.UnloadUnusedAssets();
}
@@ -142,6 +144,7 @@ namespace YooAsset
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load scene. {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<SceneOperationHandle>();
@@ -190,6 +193,7 @@ namespace YooAsset
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load asset. {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<AssetOperationHandle>();
@@ -216,6 +220,7 @@ namespace YooAsset
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load sub assets. {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<SubAssetsOperationHandle>();
@@ -338,10 +343,10 @@ namespace YooAsset
foreach (var provider in _providers)
{
DebugProviderInfo providerInfo = new DebugProviderInfo();
providerInfo.PackageName = BundleServices.GetPackageName();
providerInfo.AssetPath = provider.MainAssetInfo.AssetPath;
providerInfo.SpawnScene = provider.SpawnScene;
providerInfo.SpawnTime = provider.SpawnTime;
providerInfo.LoadingTime = provider.LoadingTime;
providerInfo.RefCount = provider.RefCount;
providerInfo.Status = (int)provider.Status;
providerInfo.DependBundleInfos = new List<DebugBundleInfo>();

View File

@@ -22,6 +22,8 @@ namespace YooAsset
}
public override void Update()
{
DebugRecording();
if (IsDone)
return;
@@ -66,6 +68,7 @@ namespace YooAsset
throw new System.Exception("Should never get here !");
Status = EStatus.Fail;
LastError = $"The bundle {OwnerBundle.MainBundleInfo.Bundle.BundleName} has been destroyed by unity bugs !";
YooLogger.Error(LastError);
InvokeCompletion();
return;
}

View File

@@ -3,12 +3,12 @@ using System.Collections.Generic;
namespace YooAsset
{
internal abstract class BundledProvider : ProviderBase
{
internal abstract class BundledProvider : ProviderBase
{
protected AssetBundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundleGroup DependBundleGroup { private set; get; }
public BundledProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
public BundledProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
OwnerBundle = impl.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle.Reference();

View File

@@ -32,6 +32,8 @@ namespace YooAsset
}
public override void Update()
{
DebugRecording();
if (IsDone)
return;
@@ -97,7 +99,7 @@ namespace YooAsset
SceneManager.SetActiveScene(SceneObject);
Status = SceneObject.IsValid() ? EStatus.Success : EStatus.Fail;
if(Status == EStatus.Fail)
if (Status == EStatus.Fail)
{
LastError = $"The load scene is invalid : {MainAssetInfo.AssetPath}";
YooLogger.Error(LastError);

View File

@@ -22,6 +22,8 @@ namespace YooAsset
}
public override void Update()
{
DebugRecording();
if (IsDone)
return;

View File

@@ -238,6 +238,15 @@ namespace YooAsset
/// </summary>
public string SpawnTime = string.Empty;
/// <summary>
/// 加载耗时(单位:毫秒)
/// </summary>
public long LoadingTime { protected set; get; }
// 加载耗时统计
private bool _isRecording = false;
private Stopwatch _watch;
[Conditional("DEBUG")]
public void InitSpawnDebugInfo()
{
@@ -251,6 +260,25 @@ namespace YooAsset
float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f);
return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00");
}
[Conditional("DEBUG")]
protected void DebugRecording()
{
if (_isRecording == false)
{
_isRecording = true;
_watch = Stopwatch.StartNew();
}
if (_watch != null)
{
if (IsDone)
{
LoadingTime = _watch.ElapsedMilliseconds;
_watch = null;
}
}
}
#endregion
}
}

View File

@@ -13,7 +13,6 @@ namespace YooAsset
private EOperationStatus _initializeStatus = EOperationStatus.None;
private EPlayMode _playMode;
private IBundleServices _bundleServices;
private ILocationServices _locationServices;
private AssetSystemImpl _assetSystemImpl;
private EditorSimulateModeImpl _editorSimulateModeImpl;
private OfflinePlayModeImpl _offlinePlayModeImpl;
@@ -33,7 +32,7 @@ namespace YooAsset
}
internal AssetsPackage()
private AssetsPackage()
{
}
internal AssetsPackage(string packageName)
@@ -62,7 +61,6 @@ namespace YooAsset
_initializeStatus = EOperationStatus.None;
_bundleServices = null;
_locationServices = null;
_editorSimulateModeImpl = null;
_offlinePlayModeImpl = null;
_hostPlayModeImpl = null;
@@ -72,8 +70,6 @@ namespace YooAsset
_assetSystemImpl.DestroyAll();
_assetSystemImpl = null;
}
YooLogger.Log("YooAssets destroy all !");
}
}
@@ -87,7 +83,6 @@ namespace YooAsset
// 初始化资源系统
InitializationOperation initializeOperation;
_locationServices = parameters.LocationServices;
_assetSystemImpl = new AssetSystemImpl();
if (_playMode == EPlayMode.EditorSimulateMode)
{
@@ -119,7 +114,8 @@ namespace YooAsset
initializeParameters.LocationToLower,
initializeParameters.DefaultHostServer,
initializeParameters.FallbackHostServer,
initializeParameters.QueryServices);
initializeParameters.QueryServices,
PackageName);
}
else
{
@@ -127,6 +123,7 @@ namespace YooAsset
}
// 监听初始化结果
_isInitialize = true;
initializeOperation.Completed += InitializeOperation_Completed;
return initializeOperation;
}
@@ -143,14 +140,11 @@ namespace YooAsset
throw new Exception($"Editor simulate mode only support unity editor.");
#endif
if (parameters.LocationServices == null)
throw new Exception($"{nameof(ILocationServices)} is null.");
if (parameters is EditorSimulateModeParameters)
{
var editorSimulateModeParameters = parameters as EditorSimulateModeParameters;
if (string.IsNullOrEmpty(editorSimulateModeParameters.SimulatePatchManifestPath))
throw new Exception($"${editorSimulateModeParameters.SimulatePatchManifestPath} is null or empty.");
throw new Exception($"{nameof(editorSimulateModeParameters.SimulatePatchManifestPath)} is null or empty.");
}
if (parameters is HostPlayModeParameters)
@@ -219,9 +213,9 @@ namespace YooAsset
/// <summary>
/// 向网络端请求并更新补丁清单
/// </summary>
/// <param name="packageCRC">更新的资源包裹版本</param>
/// <param name="packageVersion">更新的包裹版本</param>
/// <param name="timeout">超时时间默认值60秒</param>
public UpdateManifestOperation UpdateManifestAsync(string packageCRC, int timeout = 60)
public UpdateManifestOperation UpdateManifestAsync(string packageVersion, int timeout = 60)
{
DebugCheckInitialize();
DebugCheckUpdateManifest();
@@ -239,7 +233,7 @@ namespace YooAsset
}
else if (_playMode == EPlayMode.HostPlayMode)
{
return _hostPlayModeImpl.UpdatePatchManifestAsync(PackageName, packageCRC, timeout);
return _hostPlayModeImpl.UpdatePatchManifestAsync(PackageName, packageVersion, timeout);
}
else
{
@@ -251,8 +245,8 @@ namespace YooAsset
/// 弱联网情况下加载补丁清单
/// 注意:当指定版本内容验证失败后会返回失败。
/// </summary>
/// <param name="packageCRC">指定的资源包裹版本</param>
public UpdateManifestOperation WeaklyUpdateManifestAsync(string packageCRC)
/// <param name="packageVersion">指定的包裹版本</param>
public UpdateManifestOperation WeaklyUpdateManifestAsync(string packageVersion)
{
DebugCheckInitialize();
if (_playMode == EPlayMode.EditorSimulateMode)
@@ -269,7 +263,7 @@ namespace YooAsset
}
else if (_playMode == EPlayMode.HostPlayMode)
{
return _hostPlayModeImpl.WeaklyUpdatePatchManifestAsync(PackageName, packageCRC);
return _hostPlayModeImpl.WeaklyUpdatePatchManifestAsync(PackageName, packageVersion);
}
else
{
@@ -278,22 +272,22 @@ namespace YooAsset
}
/// <summary>
/// 获取人类可读的版本信息
/// 获取包裹的版本信息
/// </summary>
public string GetHumanReadableVersion()
public string GetPackageVersion()
{
DebugCheckInitialize();
if (_playMode == EPlayMode.EditorSimulateMode)
{
return _editorSimulateModeImpl.GetHumanReadableVersion();
return _editorSimulateModeImpl.GetPackageVersion();
}
else if (_playMode == EPlayMode.OfflinePlayMode)
{
return _offlinePlayModeImpl.GetHumanReadableVersion();
return _offlinePlayModeImpl.GetPackageVersion();
}
else if (_playMode == EPlayMode.HostPlayMode)
{
return _hostPlayModeImpl.GetHumanReadableVersion();
return _hostPlayModeImpl.GetPackageVersion();
}
else
{
@@ -306,11 +300,9 @@ namespace YooAsset
/// </summary>
public void UnloadUnusedAssets()
{
if (_isInitialize)
{
_assetSystemImpl.Update();
_assetSystemImpl.UnloadUnusedAssets();
}
DebugCheckInitialize();
_assetSystemImpl.Update();
_assetSystemImpl.UnloadUnusedAssets();
}
/// <summary>
@@ -318,10 +310,8 @@ namespace YooAsset
/// </summary>
public void ForceUnloadAllAssets()
{
if (_isInitialize)
{
_assetSystemImpl.ForceUnloadAllAssets();
}
DebugCheckInitialize();
_assetSystemImpl.ForceUnloadAllAssets();
}
@@ -335,7 +325,10 @@ namespace YooAsset
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
if (assetInfo.IsInvalid)
{
YooLogger.Warning(assetInfo.Error);
return false;
}
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
if (bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
@@ -397,14 +390,14 @@ namespace YooAsset
}
/// <summary>
/// 获取资源路径
/// 检查资源定位地址是否有效
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <returns>如果location地址无效则返回空字符串</returns>
public string GetAssetPath(string location)
public bool CheckLocationValid(string location)
{
DebugCheckInitialize();
return _locationServices.ConvertLocationToAssetPath(this, location);
string assetPath = _bundleServices.TryMappingToAssetPath(location);
return string.IsNullOrEmpty(assetPath) == false;
}
#endregion
@@ -429,8 +422,6 @@ namespace YooAsset
public RawFileOperation GetRawFileAsync(AssetInfo assetInfo, string copyPath = null)
{
DebugCheckInitialize();
if (assetInfo.IsInvalid)
YooLogger.Warning(assetInfo.Error);
return GetRawFileInternal(assetInfo, copyPath);
}
@@ -439,6 +430,7 @@ namespace YooAsset
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to get raw file. {assetInfo.Error}");
RawFileOperation operation = new CompletedRawFileOperation(assetInfo.Error, copyPath);
OperationSystem.StartOperation(operation);
return operation;
@@ -508,8 +500,6 @@ namespace YooAsset
public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
{
DebugCheckInitialize();
if (assetInfo.IsInvalid)
YooLogger.Warning(assetInfo.Error);
var handle = _assetSystemImpl.LoadSceneAsync(assetInfo, sceneMode, activateOnLoad, priority);
return handle;
}
@@ -523,8 +513,6 @@ namespace YooAsset
public AssetOperationHandle LoadAssetSync(AssetInfo assetInfo)
{
DebugCheckInitialize();
if (assetInfo.IsInvalid)
YooLogger.Warning(assetInfo.Error);
return LoadAssetInternal(assetInfo, true);
}
@@ -560,8 +548,6 @@ namespace YooAsset
public AssetOperationHandle LoadAssetAsync(AssetInfo assetInfo)
{
DebugCheckInitialize();
if (assetInfo.IsInvalid)
YooLogger.Warning(assetInfo.Error);
return LoadAssetInternal(assetInfo, false);
}
@@ -593,14 +579,17 @@ namespace YooAsset
private AssetOperationHandle LoadAssetInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
{
#if UNITY_EDITOR
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
if (bundleInfo.Bundle.IsRawFile)
if (assetInfo.IsInvalid == false)
{
string error = $"Cannot load raw file using LoadAsset method !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(error);
return completedProvider.CreateHandle<AssetOperationHandle>();
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
if (bundleInfo.Bundle.IsRawFile)
{
string error = $"Cannot load raw file using LoadAsset method !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(error);
return completedProvider.CreateHandle<AssetOperationHandle>();
}
}
#endif
@@ -619,8 +608,6 @@ namespace YooAsset
public SubAssetsOperationHandle LoadSubAssetsSync(AssetInfo assetInfo)
{
DebugCheckInitialize();
if (assetInfo.IsInvalid)
YooLogger.Warning(assetInfo.Error);
return LoadSubAssetsInternal(assetInfo, true);
}
@@ -656,8 +643,6 @@ namespace YooAsset
public SubAssetsOperationHandle LoadSubAssetsAsync(AssetInfo assetInfo)
{
DebugCheckInitialize();
if (assetInfo.IsInvalid)
YooLogger.Warning(assetInfo.Error);
return LoadSubAssetsInternal(assetInfo, false);
}
@@ -689,14 +674,17 @@ namespace YooAsset
private SubAssetsOperationHandle LoadSubAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
{
#if UNITY_EDITOR
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
if (bundleInfo.Bundle.IsRawFile)
if (assetInfo.IsInvalid == false)
{
string error = $"Cannot load raw file using LoadSubAssets method !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(error);
return completedProvider.CreateHandle<SubAssetsOperationHandle>();
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
if (bundleInfo.Bundle.IsRawFile)
{
string error = $"Cannot load raw file using LoadSubAssets method !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(error);
return completedProvider.CreateHandle<SubAssetsOperationHandle>();
}
}
#endif
@@ -911,9 +899,9 @@ namespace YooAsset
/// <summary>
/// 创建资源包裹下载器,用于下载更新指定资源版本所有的资源包文件
/// </summary>
/// <param name="packageCRC">指定更新的资源包裹版本</param>
/// <param name="packageVersion">指定更新的包裹版本</param>
/// <param name="timeout">超时时间</param>
public UpdatePackageOperation UpdatePackageAsync(string packageCRC, int timeout = 60)
public UpdatePackageOperation UpdatePackageAsync(string packageVersion, int timeout = 60)
{
DebugCheckInitialize();
if (_playMode == EPlayMode.EditorSimulateMode)
@@ -930,7 +918,7 @@ namespace YooAsset
}
else if (_playMode == EPlayMode.HostPlayMode)
{
return _hostPlayModeImpl.UpdatePackageAsync(PackageName, packageCRC, timeout);
return _hostPlayModeImpl.UpdatePackageAsync(PackageName, packageVersion, timeout);
}
else
{
@@ -940,14 +928,6 @@ namespace YooAsset
#endregion
#region
/// <summary>
/// 资源定位地址转换为资源完整路径
/// </summary>
internal string MappingToAssetPath(string location)
{
return _bundleServices.MappingToAssetPath(location);
}
/// <summary>
/// 是否包含资源文件
/// </summary>
@@ -1000,9 +980,12 @@ namespace YooAsset
#endregion
#region
internal List<DebugProviderInfo> GetDebugReportInfos()
internal DebugPackageData GetDebugPackageData()
{
return _assetSystemImpl.GetDebugReportInfos();
DebugPackageData data = new DebugPackageData();
data.PackageName = PackageName;
data.ProviderInfos = _assetSystemImpl.GetDebugReportInfos();
return data;
}
#endregion
@@ -1014,7 +997,7 @@ namespace YooAsset
private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
{
DebugCheckLocation(location);
string assetPath = _locationServices.ConvertLocationToAssetPath(this, location);
string assetPath = _bundleServices.MappingToAssetPath(location);
PatchAsset patchAsset = _bundleServices.TryGetPatchAsset(assetPath);
if (patchAsset != null)
{
@@ -1028,7 +1011,6 @@ namespace YooAsset
error = $"The location is null or empty !";
else
error = $"The location is invalid : {location}";
YooLogger.Error(error);
AssetInfo assetInfo = new AssetInfo(error);
return assetInfo;
}

View File

@@ -1,23 +0,0 @@
using System;
namespace YooAsset
{
[Serializable]
internal class DebugBundleInfo
{
/// <summary>
/// 资源包名称
/// </summary>
public string BundleName;
/// <summary>
/// 引用计数
/// </summary>
public int RefCount;
/// <summary>
/// 加载状态
/// </summary>
public int Status;
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace YooAsset
{
[Serializable]
internal class DebugBundleInfo : IComparer<DebugBundleInfo>, IComparable<DebugBundleInfo>
{
/// <summary>
/// 包裹名
/// </summary>
public string PackageName { set; get; }
/// <summary>
/// 资源包名称
/// </summary>
public string BundleName;
/// <summary>
/// 引用计数
/// </summary>
public int RefCount;
/// <summary>
/// 加载状态
/// </summary>
public int Status;
public int CompareTo(DebugBundleInfo other)
{
return Compare(this, other);
}
public int Compare(DebugBundleInfo a, DebugBundleInfo b)
{
return string.CompareOrdinal(a.BundleName, b.BundleName);
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
namespace YooAsset
{
[Serializable]
internal class DebugPackageData
{
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 调试数据列表
/// </summary>
public List<DebugProviderInfo> ProviderInfos = new List<DebugProviderInfo>(1000);
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cfc81e18e5b5f6f4b821c7427b34d349
guid: 583d0c3e5520c6748b2aeacd209cf8b6
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -8,9 +8,9 @@ namespace YooAsset
internal class DebugProviderInfo : IComparer<DebugProviderInfo>, IComparable<DebugProviderInfo>
{
/// <summary>
/// 所属的资源包裹
/// 包裹
/// </summary>
public string PackageName;
public string PackageName { set; get; }
/// <summary>
/// 资源对象路径
@@ -27,6 +27,11 @@ namespace YooAsset
/// </summary>
public string SpawnTime;
/// <summary>
/// 加载耗时(单位:毫秒)
/// </summary>
public long LoadingTime;
/// <summary>
/// 引用计数
/// </summary>

View File

@@ -12,17 +12,21 @@ namespace YooAsset
[Serializable]
internal class DebugReport
{
public List<DebugProviderInfo> ProviderInfos = new List<DebugProviderInfo>(1000);
/// <summary>
/// 游戏帧
/// </summary>
public int FrameCount;
/// <summary>
/// 调试的包裹数据列表
/// </summary>
public List<DebugPackageData> PackageDatas = new List<DebugPackageData>(10);
/// <summary>
/// 序列化
/// </summary>
public static byte[] Serialize(DebugReport debugReport)
public static byte[] Serialize(DebugReport debugReport)
{
return Encoding.UTF8.GetBytes(JsonUtility.ToJson(debugReport));
}

View File

@@ -2,6 +2,7 @@
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
namespace YooAsset
{
@@ -15,11 +16,22 @@ namespace YooAsset
private static readonly Dictionary<string, DownloaderBase> _downloaderDic = new Dictionary<string, DownloaderBase>();
private static readonly List<string> _removeList = new List<string>(100);
/// <summary>
/// 启用断点续传的文件大小
/// 自定义的证书认证实例
/// </summary>
public static CertificateHandler CertificateHandlerInstance;
/// <summary>
/// 启用断点续传功能文件的最小字节数
/// </summary>
public static int BreakpointResumeFileSize { set; get; } = int.MaxValue;
/// <summary>
/// 下载失败后清理文件的HTTP错误码
/// </summary>
public static List<long> ClearFileResponseCodes { set; get; }
/// <summary>
/// 更新所有下载器
/// </summary>

View File

@@ -24,6 +24,7 @@ namespace YooAsset
protected string _requestURL;
protected string _lastError = string.Empty;
protected long _lastCode = 0;
protected float _downloadProgress = 0f;
protected ulong _downloadedBytes = 0;
@@ -119,7 +120,7 @@ namespace YooAsset
/// </summary>
public string GetLastError()
{
return $"Failed to download : {_requestURL} Error : {_lastError}";
return $"Failed to download : {_requestURL} Error : {_lastError} Code : {_lastCode}";
}
}
}

View File

@@ -89,6 +89,12 @@ namespace YooAsset
_downloadHandle = handler;
#endif
if (DownloadSystem.CertificateHandlerInstance != null)
{
_webRequest.certificateHandler = DownloadSystem.CertificateHandlerInstance;
_webRequest.disposeCertificateHandlerOnDispose = false;
}
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
if (fileLength > 0)
@@ -128,12 +134,14 @@ namespace YooAsset
{
hasError = true;
_lastError = _webRequest.error;
_lastCode = _webRequest.responseCode;
}
#else
if (_webRequest.isNetworkError || _webRequest.isHttpError)
{
hasError = true;
_lastError = _webRequest.error;
_lastCode = _webRequest.responseCode;
}
#endif
@@ -145,6 +153,7 @@ namespace YooAsset
{
hasError = true;
_lastError = $"Verify bundle content failed : {_bundleInfo.Bundle.FileName}";
_lastCode = _webRequest.responseCode;
// 验证失败后删除文件
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
@@ -156,13 +165,26 @@ namespace YooAsset
// 如果下载失败
if (hasError)
{
// 注意:非断点续传下载失败后删除文件
// 注意:非断点续传下载失败后删除文件
if (_breakResume == false)
{
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
if (File.Exists(cacheFilePath))
File.Delete(cacheFilePath);
}
else
{
// 注意:下载断点续传文件发生特殊错误码之后删除文件
if (DownloadSystem.ClearFileResponseCodes != null)
{
if (DownloadSystem.ClearFileResponseCodes.Contains(_webRequest.responseCode))
{
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
if (File.Exists(cacheFilePath))
File.Delete(cacheFilePath);
}
}
}
// 失败后重新尝试
if (_failedTryAgain > 0)
@@ -179,6 +201,7 @@ namespace YooAsset
else
{
_lastError = string.Empty;
_lastCode = 0;
_steps = ESteps.Succeed;
}
@@ -204,6 +227,7 @@ namespace YooAsset
{
_steps = ESteps.Failed;
_lastError = "user abort";
_lastCode = 0;
DisposeWebRequest();
}
}

View File

@@ -33,11 +33,6 @@ namespace YooAsset
/// </summary>
public bool LocationToLower = false;
/// <summary>
/// 资源定位服务接口
/// </summary>
public ILocationServices LocationServices = null;
/// <summary>
/// 文件解密服务接口
/// </summary>

View File

@@ -67,6 +67,7 @@ namespace YooAsset
private enum ESteps
{
None,
QueryPackageVersion,
LoadAppManifest,
InitVerifyingCache,
UpdateVerifyingCache,
@@ -74,15 +75,18 @@ namespace YooAsset
}
private readonly OfflinePlayModeImpl _impl;
private readonly AppManifestLoader _appManifestLoader;
private readonly string _packageName;
private readonly CacheVerifier _patchCacheVerifier;
private readonly AppPackageVersionQuerier _appPackageVersionQuerier;
private AppManifestLoader _appManifestLoader;
private ESteps _steps = ESteps.None;
private float _verifyTime;
internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl, string buildinPackageName)
internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl, string packageName)
{
_impl = impl;
_appManifestLoader = new AppManifestLoader(buildinPackageName);
_packageName = packageName;
_appPackageVersionQuerier = new AppPackageVersionQuerier(packageName);
#if UNITY_WEBGL
_patchCacheVerifier = new CacheVerifierWithoutThread();
@@ -92,21 +96,41 @@ namespace YooAsset
}
internal override void Start()
{
_steps = ESteps.LoadAppManifest;
_steps = ESteps.QueryPackageVersion;
}
internal override void Update()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.QueryPackageVersion)
{
_appPackageVersionQuerier.Update();
if (_appPackageVersionQuerier.IsDone == false)
return;
string error = _appPackageVersionQuerier.Error;
if (string.IsNullOrEmpty(error) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = error;
}
else
{
_appManifestLoader = new AppManifestLoader(_packageName, _appPackageVersionQuerier.Version);
_steps = ESteps.LoadAppManifest;
}
}
if (_steps == ESteps.LoadAppManifest)
{
_appManifestLoader.Update();
Progress = _appManifestLoader.Progress();
if (_appManifestLoader.IsDone() == false)
Progress = _appManifestLoader.Progress;
if (_appManifestLoader.IsDone == false)
return;
if (_appManifestLoader.Result == null)
if (_appManifestLoader.Manifest == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
@@ -115,7 +139,7 @@ namespace YooAsset
else
{
_steps = ESteps.InitVerifyingCache;
_impl.SetAppPatchManifest(_appManifestLoader.Result);
_impl.SetAppPatchManifest(_appManifestLoader.Manifest);
}
}
@@ -146,75 +170,170 @@ namespace YooAsset
/// </summary>
internal sealed class HostPlayModeInitializationOperation : InitializationOperation
{
internal HostPlayModeInitializationOperation()
private enum ESteps
{
None,
QueryPackageVersion,
LoadAppManifest,
CopyAppManifest,
InitVerifyingCache,
UpdateVerifyingCache,
Done,
}
private readonly HostPlayModeImpl _impl;
private readonly string _packageName;
private readonly CacheVerifier _patchCacheVerifier;
private readonly AppPackageVersionQuerier _appPackageVersionQuerier;
private AppManifestCopyer _appManifestCopyer;
private AppManifestLoader _appManifestLoader;
private ESteps _steps = ESteps.None;
private float _verifyTime;
internal HostPlayModeInitializationOperation(HostPlayModeImpl impl, string packageName)
{
_impl = impl;
_packageName = packageName;
_appPackageVersionQuerier = new AppPackageVersionQuerier(packageName);
#if UNITY_WEBGL
_patchCacheVerifier = new CacheVerifierWithoutThread();
#else
_patchCacheVerifier = new CacheVerifierWithThread();
#endif
}
internal override void Start()
{
Status = EOperationStatus.Succeed;
_steps = ESteps.QueryPackageVersion;
}
internal override void Update()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.QueryPackageVersion)
{
_appPackageVersionQuerier.Update();
if (_appPackageVersionQuerier.IsDone == false)
return;
// 注意为了兼容MOD模式初始化动态新增的包裹的时候如果内置清单不存在也不需要报错
string error = _appPackageVersionQuerier.Error;
if (string.IsNullOrEmpty(error) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_appManifestCopyer = new AppManifestCopyer(_packageName, _appPackageVersionQuerier.Version);
_appManifestLoader = new AppManifestLoader(_packageName, _appPackageVersionQuerier.Version);
_steps = ESteps.CopyAppManifest;
}
}
if (_steps == ESteps.CopyAppManifest)
{
_appManifestCopyer.Update();
Progress = _appManifestCopyer.Progress;
if (_appManifestCopyer.IsDone == false)
return;
string error = _appManifestCopyer.Error;
if(string.IsNullOrEmpty(error) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = error;
}
else
{
_steps = ESteps.LoadAppManifest;
}
}
if (_steps == ESteps.LoadAppManifest)
{
_appManifestLoader.Update();
Progress = _appManifestLoader.Progress;
if (_appManifestLoader.IsDone == false)
return;
if (_appManifestLoader.Manifest == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _appManifestLoader.Error;
}
else
{
_steps = ESteps.InitVerifyingCache;
_impl.SetLocalPatchManifest(_appManifestLoader.Manifest);
}
}
if (_steps == ESteps.InitVerifyingCache)
{
var verifyInfos = _impl.GetVerifyInfoList(false);
_patchCacheVerifier.InitVerifier(verifyInfos);
_verifyTime = UnityEngine.Time.realtimeSinceStartup;
_steps = ESteps.UpdateVerifyingCache;
}
if (_steps == ESteps.UpdateVerifyingCache)
{
Progress = _patchCacheVerifier.GetVerifierProgress();
if (_patchCacheVerifier.UpdateVerifier())
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyTime;
YooLogger.Log($"Verify result : Success {_patchCacheVerifier.VerifySuccessList.Count}, Fail {_patchCacheVerifier.VerifyFailList.Count}, Elapsed time {costTime} seconds");
}
}
}
}
/// <summary>
/// 内置补丁清单加载器
/// </summary>
internal class AppManifestLoader
// 内置补丁清单版本查询器
internal class AppPackageVersionQuerier
{
private enum ESteps
{
LoadStaticVersion,
CheckStaticVersion,
LoadAppManifest,
CheckAppManifest,
Done,
}
private string _buildinPackageName;
private readonly string _buildinPackageName;
private ESteps _steps = ESteps.LoadStaticVersion;
private UnityWebDataRequester _downloader1;
private UnityWebDataRequester _downloader2;
private UnityWebDataRequester _downloader;
/// <summary>
/// 内置包裹版本
/// </summary>
public string Version { private set; get; }
/// <summary>
/// 错误日志
/// </summary>
public string Error { private set; get; }
/// <summary>
/// 加载结果
/// </summary>
public PatchManifest Result { private set; get; }
/// <summary>
/// 内置补丁清单CRC
/// </summary>
public string BuildinPackageCRC { private set; get; }
public AppManifestLoader(string buildinPackageName)
{
_buildinPackageName = buildinPackageName;
}
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone()
public bool IsDone
{
return _steps == ESteps.Done;
get
{
return _steps == ESteps.Done;
}
}
/// <summary>
/// 加载进度
/// </summary>
public float Progress()
public AppPackageVersionQuerier(string buildinPackageName)
{
if (_downloader2 == null)
return 0;
return _downloader2.Progress();
_buildinPackageName = buildinPackageName;
}
/// <summary>
@@ -222,73 +341,135 @@ namespace YooAsset
/// </summary>
public void Update()
{
if (IsDone())
if (IsDone)
return;
if (_steps == ESteps.LoadStaticVersion)
{
string fileName = YooAssetSettingsData.GetStaticVersionFileName(_buildinPackageName);
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(_buildinPackageName);
string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath);
_downloader1 = new UnityWebDataRequester();
_downloader1.SendRequest(url);
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(url);
_steps = ESteps.CheckStaticVersion;
YooLogger.Log($"Load static version file : {filePath}");
}
if (_steps == ESteps.CheckStaticVersion)
{
if (_downloader1.IsDone() == false)
if (_downloader.IsDone() == false)
return;
if (_downloader1.HasError())
if (_downloader.HasError())
{
Error = _downloader1.GetError();
_steps = ESteps.Done;
Error = _downloader.GetError();
}
else
{
BuildinPackageCRC = _downloader1.GetText();
_steps = ESteps.LoadAppManifest;
Version = _downloader.GetText();
if (string.IsNullOrEmpty(Version))
Error = $"Buildin package version is empty !";
}
_downloader1.Dispose();
}
if (_steps == ESteps.LoadAppManifest)
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, BuildinPackageCRC);
string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath);
_downloader2 = new UnityWebDataRequester();
_downloader2.SendRequest(url);
_steps = ESteps.CheckAppManifest;
YooLogger.Log($"Load patch manifest file : {filePath}");
}
if (_steps == ESteps.CheckAppManifest)
{
if (_downloader2.IsDone() == false)
return;
if (_downloader2.HasError())
{
Error = _downloader2.GetError();
_steps = ESteps.Done;
}
else
{
// 解析APP里的补丁清单
Result = PatchManifest.Deserialize(_downloader2.GetText());
_steps = ESteps.Done;
}
_downloader2.Dispose();
_steps = ESteps.Done;
_downloader.Dispose();
}
}
}
/// <summary>
/// 内置补丁清单复制器
/// </summary>
// 内置补丁清单加载器
internal class AppManifestLoader
{
private enum ESteps
{
LoadAppManifest,
CheckAppManifest,
Done,
}
private readonly string _buildinPackageName;
private readonly string _buildinPackageVersion;
private ESteps _steps = ESteps.LoadAppManifest;
private UnityWebDataRequester _downloader;
/// <summary>
/// 加载结果
/// </summary>
public PatchManifest Manifest { private set; get; }
/// <summary>
/// 错误日志
/// </summary>
public string Error { private set; get; }
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone
{
get
{
return _steps == ESteps.Done;
}
}
/// <summary>
/// 加载进度
/// </summary>
public float Progress
{
get
{
if (_downloader == null)
return 0;
return _downloader.Progress();
}
}
public AppManifestLoader(string buildinPackageName, string buildinPackageVersion)
{
_buildinPackageName = buildinPackageName;
_buildinPackageVersion = buildinPackageVersion;
}
/// <summary>
/// 更新流程
/// </summary>
public void Update()
{
if (IsDone)
return;
if (_steps == ESteps.LoadAppManifest)
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, _buildinPackageVersion);
string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath);
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(url);
_steps = ESteps.CheckAppManifest;
}
if (_steps == ESteps.CheckAppManifest)
{
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
Error = _downloader.GetError();
}
else
{
// 解析APP里的补丁清单
Manifest = PatchManifest.Deserialize(_downloader.GetText());
}
_steps = ESteps.Done;
_downloader.Dispose();
}
}
}
// 内置补丁清单复制器
internal class AppManifestCopyer
{
private enum ESteps
@@ -298,10 +479,10 @@ namespace YooAsset
Done,
}
private string _buildinPackageName;
private string _buildinPackageCRC;
private readonly string _buildinPackageName;
private readonly string _buildinPackageVersion;
private ESteps _steps = ESteps.CopyAppManifest;
private UnityWebFileRequester _downloader1;
private UnityWebFileRequester _downloader;
/// <summary>
/// 错误日志
@@ -309,15 +490,34 @@ namespace YooAsset
public string Error { private set; get; }
/// <summary>
/// 拷贝结果
/// 是否已经完成
/// </summary>
public bool Result { private set; get; }
public bool IsDone
{
get
{
return _steps == ESteps.Done;
}
}
/// <summary>
/// 加载进度
/// </summary>
public float Progress
{
get
{
if (_downloader == null)
return 0;
return _downloader.Progress();
}
}
public AppManifestCopyer(string buildinPackageName, string buildinPackageCRC)
public AppManifestCopyer(string buildinPackageName, string buildinPackageVersion)
{
_buildinPackageName = buildinPackageName;
_buildinPackageCRC = buildinPackageCRC;
_buildinPackageVersion = buildinPackageVersion;
}
/// <summary>
@@ -325,56 +525,39 @@ namespace YooAsset
/// </summary>
public void Update()
{
if (IsDone())
if (IsDone)
return;
if (_steps == ESteps.CopyAppManifest)
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, _buildinPackageCRC);
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, _buildinPackageVersion);
string destFilePath = PathHelper.MakePersistentLoadPath(fileName);
if (File.Exists(destFilePath))
{
Result = true;
_steps = ESteps.Done;
return;
}
else
{
YooLogger.Log($"Copy application patch manifest.");
string sourceFilePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(sourceFilePath);
_downloader1 = new UnityWebFileRequester();
_downloader1.SendRequest(url, destFilePath);
_downloader = new UnityWebFileRequester();
_downloader.SendRequest(url, destFilePath);
_steps = ESteps.CheckAppManifest;
}
}
if (_steps == ESteps.CheckAppManifest)
{
if (_downloader1.IsDone() == false)
if (_downloader.IsDone() == false)
return;
if (_downloader1.HasError())
if (_downloader.HasError())
{
Result = false;
Error = _downloader1.GetError();
_steps = ESteps.Done;
Error = _downloader.GetError();
}
else
{
Result = true;
_steps = ESteps.Done;
}
_downloader1.Dispose();
_steps = ESteps.Done;
_downloader.Dispose();
}
}
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone()
{
return _steps == ESteps.Done;
}
}
}

View File

@@ -52,7 +52,8 @@ namespace YooAsset
private enum ESteps
{
None,
CheckManifestHash,
LoadWebHash,
CheckWebHash,
LoadWebManifest,
CheckWebManifest,
InitVerifyingCache,
@@ -63,18 +64,19 @@ namespace YooAsset
private static int RequestCount = 0;
private readonly HostPlayModeImpl _impl;
private readonly string _packageName;
private readonly string _packageCRC;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebDataRequester _downloader;
private UnityWebDataRequester _downloader1;
private UnityWebDataRequester _downloader2;
private CacheVerifier _cacheVerifier;
private ESteps _steps = ESteps.None;
private float _verifyTime;
internal HostPlayModeUpdateManifestOperation(HostPlayModeImpl impl, string packageName, string packageCRC, int timeout)
internal HostPlayModeUpdateManifestOperation(HostPlayModeImpl impl, string packageName, string packageVersion, int timeout)
{
_impl = impl;
_packageName = packageName;
_packageCRC = packageCRC;
_packageVersion = packageVersion;
_timeout = timeout;
#if UNITY_WEBGL
@@ -86,59 +88,84 @@ namespace YooAsset
internal override void Start()
{
RequestCount++;
_steps = ESteps.CheckManifestHash;
_steps = ESteps.LoadWebHash;
}
internal override void Update()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckManifestHash)
if (_steps == ESteps.LoadWebHash)
{
string cachedManifestCRC = GetSandboxPatchManifestFileHash(_packageName, _packageCRC);
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(_packageName, _packageVersion);
string webURL = GetPatchManifestRequestURL(fileName);
YooLogger.Log($"Beginning to request patch manifest hash : {webURL}");
_downloader1 = new UnityWebDataRequester();
_downloader1.SendRequest(webURL, _timeout);
_steps = ESteps.CheckWebHash;
}
// 如果补丁清单文件的哈希值相同
if (cachedManifestCRC == _packageCRC)
if (_steps == ESteps.CheckWebHash)
{
if (_downloader1.IsDone() == false)
return;
// Check error
if (_downloader1.HasError())
{
YooLogger.Log($"Patch manifest file hash is not change : {_packageCRC}");
LoadSandboxPatchManifest(_packageName, _packageCRC);
FoundNewManifest = false;
_steps = ESteps.InitVerifyingCache;
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader1.GetError();
}
else
{
YooLogger.Log($"Patch manifest hash is change : {cachedManifestCRC} -> {_packageCRC}");
FoundNewManifest = true;
_steps = ESteps.LoadWebManifest;
string webManifestHash = _downloader1.GetText();
string cachedManifestHash = GetSandboxPatchManifestFileHash(_packageName, _packageVersion);
// 如果补丁清单文件的哈希值相同
if (cachedManifestHash == webManifestHash)
{
YooLogger.Log($"Patch manifest file hash is not change : {webManifestHash}");
LoadSandboxPatchManifest(_packageName, _packageVersion);
FoundNewManifest = false;
_steps = ESteps.InitVerifyingCache;
}
else
{
YooLogger.Log($"Patch manifest hash is change : {cachedManifestHash} -> {webManifestHash}");
FoundNewManifest = true;
_steps = ESteps.LoadWebManifest;
}
}
_downloader1.Dispose();
}
if (_steps == ESteps.LoadWebManifest)
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_packageName, _packageCRC);
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_packageName, _packageVersion);
string webURL = GetPatchManifestRequestURL(fileName);
YooLogger.Log($"Beginning to request patch manifest : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
_downloader2 = new UnityWebDataRequester();
_downloader2.SendRequest(webURL, _timeout);
_steps = ESteps.CheckWebManifest;
}
if (_steps == ESteps.CheckWebManifest)
{
if (_downloader.IsDone() == false)
if (_downloader2.IsDone() == false)
return;
// Check error
if (_downloader.HasError())
if (_downloader2.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
Error = _downloader2.GetError();
}
else
{
// 解析补丁清单
if (ParseAndSaveRemotePatchManifest(_packageName, _packageCRC, _downloader.GetText()))
if (ParseAndSaveRemotePatchManifest(_packageName, _packageVersion, _downloader2.GetText()))
{
_steps = ESteps.InitVerifyingCache;
}
@@ -146,10 +173,10 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"URL : {_downloader.URL} Error : remote patch manifest content is invalid";
Error = $"URL : {_downloader2.URL} Error : remote patch manifest content is invalid";
}
}
_downloader.Dispose();
_downloader2.Dispose();
}
if (_steps == ESteps.InitVerifyingCache)
@@ -188,7 +215,7 @@ namespace YooAsset
/// <summary>
/// 解析并保存远端请求的补丁清单
/// </summary>
private bool ParseAndSaveRemotePatchManifest(string packageName, string packageCRC, string content)
private bool ParseAndSaveRemotePatchManifest(string packageName, string packageVersion, string content)
{
try
{
@@ -196,7 +223,7 @@ namespace YooAsset
_impl.SetLocalPatchManifest(remotePatchManifest);
YooLogger.Log("Save remote patch manifest file.");
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC);
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageVersion);
string savePath = PathHelper.MakePersistentLoadPath(fileName);
PatchManifest.Serialize(savePath, remotePatchManifest);
return true;
@@ -212,10 +239,10 @@ namespace YooAsset
/// 加载沙盒内的补丁清单
/// 注意:在加载本地补丁清单之前,已经验证过文件的哈希值
/// </summary>
private void LoadSandboxPatchManifest(string packageName, string packageCRC)
private void LoadSandboxPatchManifest(string packageName, string packageVersion)
{
YooLogger.Log("Load sandbox patch manifest file.");
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC);
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageVersion);
string filePath = PathHelper.MakePersistentLoadPath(fileName);
string jsonData = File.ReadAllText(filePath);
var sandboxPatchManifest = PatchManifest.Deserialize(jsonData);
@@ -226,12 +253,12 @@ namespace YooAsset
/// 获取沙盒内补丁清单文件的哈希值
/// 注意:如果沙盒内补丁清单文件不存在,返回空字符串
/// </summary>
private string GetSandboxPatchManifestFileHash(string packageName, string packageCRC)
private string GetSandboxPatchManifestFileHash(string packageName, string packageVersion)
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC);
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageVersion);
string filePath = PathHelper.MakePersistentLoadPath(fileName);
if (File.Exists(filePath))
return HashUtility.FileCRC32(filePath);
return HashUtility.FileMD5(filePath);
else
return string.Empty;
}
@@ -253,16 +280,16 @@ namespace YooAsset
private readonly HostPlayModeImpl _impl;
private readonly string _packageName;
private readonly string _packageCRC;
private readonly string _packageVersion;
private ESteps _steps = ESteps.None;
private CacheVerifier _cacheVerifier;
private float _verifyTime;
internal HostPlayModeWeaklyUpdateManifestOperation(HostPlayModeImpl impl, string packageName, string packageCRC)
internal HostPlayModeWeaklyUpdateManifestOperation(HostPlayModeImpl impl, string packageName, string packageVersion)
{
_impl = impl;
_packageName = packageName;
_packageCRC = packageCRC;
_packageVersion = packageVersion;
#if UNITY_WEBGL
_cacheVerifier = new CacheVerifierWithoutThread();
@@ -281,7 +308,7 @@ namespace YooAsset
if (_steps == ESteps.LoadSandboxManifestHash)
{
LoadSandboxPatchManifest(_packageName, _packageCRC);
LoadSandboxPatchManifest(_packageName, _packageVersion);
_steps = ESteps.InitVerifyingCache;
}
@@ -321,7 +348,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The package resource {_packageName}_{_packageCRC} content has verify failed file !";
Error = $"The package resource {_packageName}_{_packageVersion} content has verify failed file !";
}
}
}
@@ -331,9 +358,9 @@ namespace YooAsset
/// 加载沙盒内的补丁清单
/// 注意:在加载本地补丁清单之前,未验证过文件的哈希值
/// </summary>
private void LoadSandboxPatchManifest(string packageName, string packageCRC)
private void LoadSandboxPatchManifest(string packageName, string packageVersion)
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC);
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageVersion);
string filePath = PathHelper.MakePersistentLoadPath(fileName);
if (File.Exists(filePath))
{

View File

@@ -80,17 +80,17 @@ namespace YooAsset
private static int RequestCount = 0;
private readonly HostPlayModeImpl _impl;
private readonly string _packageName;
private readonly string _packageCRC;
private readonly string _packageVersion;
private readonly int _timeout;
private ESteps _steps = ESteps.None;
private UnityWebDataRequester _downloader;
private PatchManifest _remotePatchManifest;
internal HostPlayModeUpdatePackageOperation(HostPlayModeImpl impl, string packageName, string packageCRC, int timeout)
internal HostPlayModeUpdatePackageOperation(HostPlayModeImpl impl, string packageName, string packageVersion, int timeout)
{
_impl = impl;
_packageName = packageName;
_packageCRC = packageCRC;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void Start()
@@ -105,7 +105,7 @@ namespace YooAsset
if (_steps == ESteps.LoadWebManifest)
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_packageName, _packageCRC);
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_packageName, _packageVersion);
string webURL = GetPatchManifestRequestURL(fileName);
YooLogger.Log($"Beginning to request patch manifest : {webURL}");
_downloader = new UnityWebDataRequester();

View File

@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
@@ -9,9 +10,9 @@ namespace YooAsset
public abstract class UpdateStaticVersionOperation : AsyncOperationBase
{
/// <summary>
/// 包裹文件的哈希值
/// 当前最新的包裹版本
/// </summary>
public string PackageCRC { protected set; get; } = string.Empty;
public string PackageVersion { protected set; get; }
}
/// <summary>
@@ -80,8 +81,8 @@ namespace YooAsset
if (_steps == ESteps.LoadStaticVersion)
{
string versionFileName = YooAssetSettingsData.GetStaticVersionFileName(_packageName);
string webURL = GetStaticVersionRequestURL(versionFileName);
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(_packageName);
string webURL = GetStaticVersionRequestURL(fileName);
YooLogger.Log($"Beginning to request static version : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
@@ -102,16 +103,15 @@ namespace YooAsset
}
else
{
string packageCRC = _downloader.GetText();
if(string.IsNullOrEmpty(packageCRC))
PackageVersion = _downloader.GetText();
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"URL : {_downloader.URL} Error : static version content is empty.";
Error = $"Static package version is empty : {_downloader.URL}";
}
else
{
PackageCRC = packageCRC;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}

View File

@@ -33,9 +33,9 @@ namespace YooAsset
public string PackageName;
/// <summary>
/// 人类可读的版本信息
/// 资源包裹的版本信息
/// </summary>
public string HumanReadableVersion;
public string PackageVersion;
/// <summary>
/// 资源列表(主动收集的资源列表)
@@ -147,6 +147,23 @@ namespace YooAsset
}
}
/// <summary>
/// 尝试映射为资源路径
/// </summary>
public string TryMappingToAssetPath(string location)
{
if (string.IsNullOrEmpty(location))
return string.Empty;
if (_locationToLower)
location = location.ToLower();
if (AssetPathMapping.TryGetValue(location, out string assetPath))
return assetPath;
else
return string.Empty;
}
/// <summary>
/// 获取主资源包
/// 注意:传入的资源路径一定合法有效!

View File

@@ -21,13 +21,13 @@ namespace YooAsset
}
/// <summary>
/// 获取人类可读的版本信息
/// 获取包裹的版本信息
/// </summary>
public string GetHumanReadableVersion()
public string GetPackageVersion()
{
if (_simulatePatchManifest == null)
return string.Empty;
return _simulatePatchManifest.HumanReadableVersion;
return _simulatePatchManifest.PackageVersion;
}
internal void SetSimulatePatchManifest(PatchManifest patchManifest)
@@ -66,6 +66,10 @@ namespace YooAsset
{
return _simulatePatchManifest.MappingToAssetPath(location);
}
string IBundleServices.TryMappingToAssetPath(string location)
{
return _simulatePatchManifest.TryMappingToAssetPath(location);
}
string IBundleServices.GetPackageName()
{
return _simulatePatchManifest.PackageName;

View File

@@ -19,26 +19,26 @@ namespace YooAsset
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices)
public InitializationOperation InitializeAsync(bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices, string packageName)
{
_locationToLower = locationToLower;
_defaultHostServer = defaultHostServer;
_fallbackHostServer = fallbackHostServer;
_queryServices = queryServices;
var operation = new HostPlayModeInitializationOperation();
var operation = new HostPlayModeInitializationOperation(this, packageName);
OperationSystem.StartOperation(operation);
return operation;
}
/// <summary>
/// 获取人类可读的版本信息
/// 获取包裹的版本信息
/// </summary>
public string GetHumanReadableVersion()
public string GetPackageVersion()
{
if (LocalPatchManifest == null)
return string.Empty;
return LocalPatchManifest.HumanReadableVersion;
return LocalPatchManifest.PackageVersion;
}
/// <summary>
@@ -54,9 +54,9 @@ namespace YooAsset
/// <summary>
/// 异步更新补丁清单
/// </summary>
public UpdateManifestOperation UpdatePatchManifestAsync(string packageName, string packageCRC, int timeout)
public UpdateManifestOperation UpdatePatchManifestAsync(string packageName, string packageVersion, int timeout)
{
var operation = new HostPlayModeUpdateManifestOperation(this, packageName, packageCRC, timeout);
var operation = new HostPlayModeUpdateManifestOperation(this, packageName, packageVersion, timeout);
OperationSystem.StartOperation(operation);
return operation;
}
@@ -64,9 +64,9 @@ namespace YooAsset
/// <summary>
/// 异步更新补丁清单(弱联网)
/// </summary>
public UpdateManifestOperation WeaklyUpdatePatchManifestAsync(string packageName, string packageCRC)
public UpdateManifestOperation WeaklyUpdatePatchManifestAsync(string packageName, string packageVersion)
{
var operation = new HostPlayModeWeaklyUpdateManifestOperation(this, packageName, packageCRC);
var operation = new HostPlayModeWeaklyUpdateManifestOperation(this, packageName, packageVersion);
OperationSystem.StartOperation(operation);
return operation;
}
@@ -74,9 +74,9 @@ namespace YooAsset
/// <summary>
/// 异步更新资源包裹
/// </summary>
public UpdatePackageOperation UpdatePackageAsync(string packageName, string packageCRC, int timeout)
public UpdatePackageOperation UpdatePackageAsync(string packageName, string packageVersion, int timeout)
{
var operation = new HostPlayModeUpdatePackageOperation(this, packageName, packageCRC, timeout);
var operation = new HostPlayModeUpdatePackageOperation(this, packageName, packageVersion, timeout);
OperationSystem.StartOperation(operation);
return operation;
}
@@ -392,6 +392,10 @@ namespace YooAsset
{
return LocalPatchManifest.MappingToAssetPath(location);
}
string IBundleServices.TryMappingToAssetPath(string location)
{
return LocalPatchManifest.TryMappingToAssetPath(location);
}
string IBundleServices.GetPackageName()
{
return LocalPatchManifest.PackageName;

View File

@@ -13,22 +13,22 @@ namespace YooAsset
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(bool locationToLower, string buildinPackageName)
public InitializationOperation InitializeAsync(bool locationToLower, string packageName)
{
_locationToLower = locationToLower;
var operation = new OfflinePlayModeInitializationOperation(this, buildinPackageName);
var operation = new OfflinePlayModeInitializationOperation(this, packageName);
OperationSystem.StartOperation(operation);
return operation;
}
/// <summary>
/// 获取人类可读的版本信息
/// 获取包裹的版本信息
/// </summary>
public string GetHumanReadableVersion()
public string GetPackageVersion()
{
if (_appPatchManifest == null)
return string.Empty;
return _appPatchManifest.HumanReadableVersion;
return _appPatchManifest.PackageVersion;
}
internal List<VerifyInfo> GetVerifyInfoList()
@@ -117,6 +117,10 @@ namespace YooAsset
{
return _appPatchManifest.MappingToAssetPath(location);
}
string IBundleServices.TryMappingToAssetPath(string location)
{
return _appPatchManifest.TryMappingToAssetPath(location);
}
string IBundleServices.GetPackageName()
{
return _appPatchManifest.PackageName;

View File

@@ -28,6 +28,11 @@ namespace YooAsset
/// </summary>
string MappingToAssetPath(string location);
/// <summary>
/// 尝试映射为资源路径
/// </summary>
string TryMappingToAssetPath(string location);
/// <summary>
/// 获取所属的包裹名
/// </summary>

View File

@@ -1,11 +0,0 @@

namespace YooAsset
{
public interface ILocationServices
{
/// <summary>
/// 定位地址转换为资源路径
/// </summary>
string ConvertLocationToAssetPath(AssetsPackage package, string location);
}
}

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 6e400ee1e8b3556479bfa493ff7fe778
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@

namespace YooAsset
{
public class AddressLocationServices : ILocationServices
{
string ILocationServices.ConvertLocationToAssetPath(AssetsPackage package, string location)
{
return package.MappingToAssetPath(location);
}
}
}

View File

@@ -1,27 +0,0 @@

namespace YooAsset
{
public class DefaultLocationServices : ILocationServices
{
private readonly string _resourceRoot;
public DefaultLocationServices(string resourceRoot)
{
if (string.IsNullOrEmpty(resourceRoot) == false)
_resourceRoot = PathHelper.GetRegularPath(resourceRoot);
}
string ILocationServices.ConvertLocationToAssetPath(AssetsPackage package, string location)
{
if (string.IsNullOrEmpty(_resourceRoot))
{
return package.MappingToAssetPath(location);
}
else
{
string tempLocation = $"{_resourceRoot}/{location}";
return package.MappingToAssetPath(tempLocation);
}
}
}
}

View File

@@ -22,9 +22,9 @@ namespace YooAsset
/// <summary>
/// 补丁清单文件版本
/// 补丁清单文件格式版本
/// </summary>
public const string PatchManifestFileVersion = "1.3.0";
public const string PatchManifestFileVersion = "1.3.3";
/// <summary>
/// 构建输出文件夹名称
@@ -36,11 +36,6 @@ namespace YooAsset
/// </summary>
public const string ReportFileName = "BuildReport";
/// <summary>
/// 静态版本文件
/// </summary>
public const string VersionFileName = "StaticVersion";
/// <summary>
/// Unity着色器资源包名称
/// </summary>

View File

@@ -35,33 +35,33 @@ namespace YooAsset
/// <summary>
/// 获取构建报告文件名
/// </summary>
public static string GetReportFileName(string packageName, string packageCRC)
public static string GetReportFileName(string packageName, string packageVersion)
{
return $"{YooAssetSettings.ReportFileName}_{packageName}_{packageCRC}.json";
return $"{YooAssetSettings.ReportFileName}_{packageName}_{packageVersion}.json";
}
/// <summary>
/// 获取补丁清单文件完整名称
/// </summary>
public static string GetPatchManifestFileName(string packageName, string packageCRC)
public static string GetPatchManifestFileName(string packageName, string packageVersion)
{
return $"{Setting.PatchManifestFileName}_{packageName}_{packageCRC}.bytes";
return $"{Setting.PatchManifestFileName}_{packageName}_{packageVersion}.bytes";
}
/// <summary>
/// 获取补丁清单文件临时名称
/// 获取补丁清单哈希文件完整名称
/// </summary>
public static string GetPatchManifestTempFileName(string packageName)
public static string GetPatchManifestHashFileName(string packageName, string packageVersion)
{
return $"{Setting.PatchManifestFileName}_{packageName}.temp";
return $"{Setting.PatchManifestFileName}_{packageName}_{packageVersion}.hash";
}
/// <summary>
/// 获取静态版本文件名称
/// 获取补丁清单版本文件完整名称
/// </summary>
public static string GetStaticVersionFileName(string packageName)
public static string GetPatchManifestVersionFileName(string packageName)
{
return $"{YooAssetSettings.VersionFileName}_{packageName}.bytes";
return $"{Setting.PatchManifestFileName}_{packageName}.version";
}
/// <summary>

View File

@@ -135,7 +135,7 @@ namespace YooAsset
}
return false;
}
/// <summary>
/// 开启一个异步操作
/// </summary>
@@ -147,7 +147,7 @@ namespace YooAsset
#region
/// <summary>
/// 启用下载系统断点续传功能文件大小
/// 设置下载系统参数,启用断点续传功能文件的最小字节数
/// </summary>
public static void SetDownloadSystemBreakpointResumeFileSize(int fileBytes)
{
@@ -155,7 +155,23 @@ namespace YooAsset
}
/// <summary>
/// 设置异步系统的每帧允许运行的最大时间切片(单位:毫秒)
/// 设置下载系统参数下载失败后清理文件的HTTP错误码
/// </summary>
public static void SetDownloadSystemClearFileResponseCode(List<long> codes)
{
DownloadSystem.ClearFileResponseCodes = codes;
}
/// <summary>
/// 设置下载系统参数,自定义的证书认证实例
/// </summary>
public static void SetDownloadSystemCertificateHandler(UnityEngine.Networking.CertificateHandler instance)
{
DownloadSystem.CertificateHandlerInstance = instance;
}
/// <summary>
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)
/// </summary>
public static void SetOperationSystemMaxTimeSlice(long milliseconds)
{
@@ -168,7 +184,7 @@ namespace YooAsset
}
/// <summary>
/// 设置缓存系统已经缓存文件的校验等级
/// 设置缓存系统参数,已经缓存文件的校验等级
/// </summary>
public static void SetCacheSystemCachedFileVerifyLevel(EVerifyLevel verifyLevel)
{
@@ -220,12 +236,9 @@ namespace YooAsset
foreach (var package in _packages)
{
var result = package.GetDebugReportInfos();
report.ProviderInfos.AddRange(result);
var packageData = package.GetDebugPackageData();
report.PackageDatas.Add(packageData);
}
// 重新排序
report.ProviderInfos.Sort();
return report;
}
#endregion

View File

@@ -70,14 +70,13 @@ namespace YooAsset
}
/// <summary>
/// 获取资源路径
/// 检查资源定位地址是否有效
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <returns>如果location地址无效则返回空字符串</returns>
public static string GetAssetPath(string location)
public static bool CheckLocationValid(string location)
{
DebugCheckDefaultPackageValid();
return _defaultPackage.GetAssetPath(location);
return _defaultPackage.CheckLocationValid(location);
}
#endregion
@@ -370,12 +369,12 @@ namespace YooAsset
/// <summary>
/// 创建资源包裹下载器,用于下载更新指定资源版本所有的资源包文件
/// </summary>
/// <param name="packageCRC">指定更新的资源包裹版本</param>
/// <param name="packageVersion">指定更新的包裹版本</param>
/// <param name="timeout">超时时间</param>
public static UpdatePackageOperation UpdatePackageAsync(string packageCRC, int timeout = 60)
public static UpdatePackageOperation UpdatePackageAsync(string packageVersion, int timeout = 60)
{
DebugCheckDefaultPackageValid();
return _defaultPackage.UpdatePackageAsync(packageCRC, timeout);
return _defaultPackage.UpdatePackageAsync(packageVersion, timeout);
}
#endregion

View File

@@ -53,7 +53,6 @@ public class BootScene : MonoBehaviour
if (PlayMode == EPlayMode.EditorSimulateMode)
{
var createParameters = new EditorSimulateModeParameters();
createParameters.LocationServices = new AddressLocationServices();
createParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild("DefaultPackage");
yield return defaultPackage.InitializeAsync(createParameters);
}
@@ -62,7 +61,6 @@ public class BootScene : MonoBehaviour
if (PlayMode == EPlayMode.OfflinePlayMode)
{
var createParameters = new OfflinePlayModeParameters();
createParameters.LocationServices = new AddressLocationServices();
yield return defaultPackage.InitializeAsync(createParameters);
}
@@ -70,7 +68,6 @@ public class BootScene : MonoBehaviour
if (PlayMode == EPlayMode.HostPlayMode)
{
var createParameters = new HostPlayModeParameters();
createParameters.LocationServices = new AddressLocationServices();
createParameters.QueryServices = new QueryStreamingAssetsFileServices();
createParameters.DefaultHostServer = GetHostServerURL();
createParameters.FallbackHostServer = GetHostServerURL();
@@ -111,7 +108,8 @@ public class BootScene : MonoBehaviour
{
public bool QueryStreamingAssets(string fileName)
{
return BetterStreamingAssets.FileExists($"{YooAssets.GetStreamingAssetBuildinFolderName()}/{fileName}");
string buildinFolderName = YooAssets.GetStreamingAssetBuildinFolderName();
return BetterStreamingAssets.FileExists($"{buildinFolderName}/{fileName}");
}
}
}

View File

@@ -25,7 +25,7 @@ public class FsmUpdateManifest : IFsmNode
// 更新补丁清单
var package = YooAssets.GetAssetsPackage("DefaultPackage");
var operation = package.UpdateManifestAsync(PatchUpdater.PackageCRC, 30);
var operation = package.UpdateManifestAsync(PatchUpdater.PackageVersion, 30);
yield return operation;
if(operation.Status == EOperationStatus.Succeed)

View File

@@ -30,8 +30,8 @@ internal class FsmUpdateStaticVersion : IFsmNode
if (operation.Status == EOperationStatus.Succeed)
{
Debug.Log($"Found static version : {operation.PackageCRC}");
PatchUpdater.PackageCRC = operation.PackageCRC;
Debug.Log($"Found static version : {operation.PackageVersion}");
PatchUpdater.PackageVersion = operation.PackageVersion;
FsmManager.Transition(nameof(FsmUpdateManifest));
}
else

View File

@@ -14,9 +14,9 @@ public static class PatchUpdater
public static PatchDownloaderOperation Downloader { set; get; }
/// <summary>
/// 资源版本
/// 包裹的版本信息
/// </summary>
public static string PackageCRC { set; get; }
public static string PackageVersion { set; get; }
/// <summary>
/// 开启初始化流程

View File

@@ -1,25 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<root Version="2.0">
<Common AutoAddressable="True" ShowPackageView="False" />
<root Version="2.1">
<Common AutoAddressable="True" UniqueBundleName="False" ShowPackageView="False" />
<Package PackageName="DefaultPackage" PackageDesc="">
<Group GroupName="Level" GroupDesc="关卡资源" AssetTags="level">
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/Entity/Level1" CollectGUID="724066efe61192e43a0d7e59166b36a4" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackSeparately" FilterRule="CollectPrefab" AssetTags="level1" />
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/Entity/Level2" CollectGUID="8045c1986f0ae964f8b1ea29e3522388" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackSeparately" FilterRule="CollectPrefab" AssetTags="level2" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/Entity/Level1" CollectGUID="724066efe61192e43a0d7e59166b36a4" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackSeparately" FilterRule="CollectPrefab" AssetTags="level1" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/Entity/Level2" CollectGUID="8045c1986f0ae964f8b1ea29e3522388" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackSeparately" FilterRule="CollectPrefab" AssetTags="level2" />
</Group>
<Group GroupName="Buildin" GroupDesc="首包资源" AssetTags="buildin">
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/Scene" CollectGUID="f75e7d64104fb1a48b849b72b84ade4c" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackSeparately" FilterRule="CollectScene" AssetTags="" />
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/Config" CollectGUID="44774abdee2b91b45b42f9dadf8c17a4" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackRawFile" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/Music" CollectGUID="e05b02ee4d90ae84a99871ce75288ea2" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/Scene" CollectGUID="f75e7d64104fb1a48b849b72b84ade4c" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackSeparately" FilterRule="CollectScene" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/Config" CollectGUID="44774abdee2b91b45b42f9dadf8c17a4" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackRawFile" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/Music" CollectGUID="e05b02ee4d90ae84a99871ce75288ea2" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
</Group>
<Group GroupName="Panel" GroupDesc="面板资源" AssetTags="panel">
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/Texture" CollectGUID="69b046f60ca75f647b2963e0113fd779" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackCollector" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/TpAtlas" CollectGUID="06e38aac2570d2b4a97c6a90223e5344" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/UIPanel" CollectGUID="926d3203fcefdb947881a7491496e039" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameRes/UISprite" CollectGUID="29f27e4abf667c04b88a3996d8cdadfc" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/Texture" CollectGUID="69b046f60ca75f647b2963e0113fd779" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackCollector" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/TpAtlas" CollectGUID="06e38aac2570d2b4a97c6a90223e5344" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/UIPanel" CollectGUID="926d3203fcefdb947881a7491496e039" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameRes/UISprite" CollectGUID="29f27e4abf667c04b88a3996d8cdadfc" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
</Group>
<Group GroupName="Art" GroupDesc="美术资源" AssetTags="">
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameArt/ShaderVariants" CollectGUID="00781758c26692e40a9634ddeac838be" CollectType="StaticAssetCollector" AddressRule="AddressByFileName" PackRule="PackShaderVariants" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/YooAsset/Samples/Basic Sample/GameArt/UIFont" CollectGUID="464727a15e4a7dc4d895346374432399" CollectType="DependAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameArt/ShaderVariants" CollectGUID="00781758c26692e40a9634ddeac838be" CollectType="StaticAssetCollector" AddressRule="AddressByFileName" PackRule="PackShaderVariants" FilterRule="CollectAll" AssetTags="" />
<Collector CollectPath="Assets/Samples/Basic Sample/GameArt/UIFont" CollectGUID="464727a15e4a7dc4d895346374432399" CollectType="DependAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" AssetTags="" />
</Group>
</Package>
</root>

View File

@@ -14,6 +14,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
ShowPackageView: 0
EnableAddressable: 1
UniqueBundleName: 0
Packages:
- PackageName: DefaultPackage
PackageDesc:

View File

@@ -61,7 +61,12 @@ namespace YooAsset.Editor
EditorTools.CopyFile(sourcePath, destPath, true);
}
{
string fileName = YooAssetSettingsData.GetStaticVersionFileName(patchManifest.PackageName);
string sourcePath = $"{outputDirectory}/{manifestFileName}.hash";
string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{manifestFileName}.hash";
EditorTools.CopyFile(sourcePath, destPath, true);
}
{
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(patchManifest.PackageName);
string sourcePath = $"{outputDirectory}/{fileName}";
string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);

View File

@@ -1,7 +1,7 @@
{
"name": "com.tuyoogame.yooasset",
"displayName": "YooAsset",
"version": "1.3.1",
"version": "1.3.3",
"unity": "2019.4",
"description": "unity3d resources management system.",
"author": {

View File

@@ -52,6 +52,20 @@
(4) BundleName_HashName_Extension资源包名+哈希值+后缀名
- **Copy Buildin File Option**
首包资源文件的拷贝方式
(1) None不拷贝任何文件
(2) ClearAndCopyAll先清空已有文件然后拷贝所有文件
(3) ClearAndCopyByTags先清空已有文件然后按照资源标签拷贝文件
(4) OnlyCopyAll不清空已有文件直接拷贝所有文件
(5) OnlyCopyByTags不清空已有文件直接按照资源标签拷贝文件
- **构建**
点击构建按钮会开始构建流程,构建流程分为多个节点顺序执行,如果某个节点发生错误,会导致构建失败。错误信息可以在控制台查看。
@@ -121,11 +135,12 @@ private static void BuildInternal(BuildTarget buildTarget)
buildParameters.BuildPipeline = EBuildPipeline.BuiltinBuildPipeline;
buildParameters.BuildMode = EBuildMode.ForceRebuild;
buildParameters.BuildPackage = "DefaultPackage";
buildParameters.HumanReadableVersion = "v1.0";
buildParameters.VerifyBuildingResult = true;
buildParameters.EnableAddressable = true;
buildParameters.EncryptionServices = new GameEncryption();
buildParameters.CompressOption = ECompressOption.LZ4;
buildParameters.OutputNameStyle = EOutputNameStyle.HashName_Extension;
buildParameters.CopyBuildinFileOption = ECopyBuildinFileOption.None;
// 执行构建
AssetBundleBuilder builder = new AssetBundleBuilder();

View File

@@ -10,9 +10,17 @@
#### 公共设置
- Show Packages
是否展示资源包列表视图。
- Enable Addressable
启用可寻址资源定位系统。
- Unique Bundle Name
资源包名追加PackageName作为前缀。
#### 资源分组

View File

@@ -3,7 +3,14 @@
初始化资源系统
```c#
// 初始化资源系统
YooAssets.Initialize();
// 创建默认的资源包
var defaultPackage = YooAssets.CreateAssetsPackage("DefaultPackage");
// 设置该资源包为默认的资源包可以使用YooAssets相关加载接口加载该资源包内容。
YooAssets.SetDefaultAssetsPackage(defaultPackage);
```
资源系统的运行模式支持三种:编辑器模拟模式,单机运行模式,联机运行模式。
@@ -17,10 +24,9 @@ YooAssets.Initialize();
````c#
private IEnumerator InitializeYooAsset()
{
var initParameters = new YooAssets.EditorSimulateModeParameters();
initParameters.LocationServices = new DefaultLocationServices("Assets/GameRes");
initParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild("DefaultPackage", false);
yield return YooAssets.InitializeAsync(initParameters);
var initParameters = new EditorSimulateModeParameters();
initParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild("DefaultPackage");
yield return defaultPackage.InitializeAsync(initParameters);
}
````
@@ -33,9 +39,8 @@ private IEnumerator InitializeYooAsset()
````c#
private IEnumerator InitializeYooAsset()
{
var initParameters = new YooAssets.OfflinePlayModeParameters();
initParameters.LocationServices = new DefaultLocationServices("Assets/GameRes");
yield return YooAssets.InitializeAsync(initParameters);
var initParameters = new OfflinePlayModeParameters();
yield return defaultPackage.InitializeAsync(initParameters);
}
````
@@ -45,32 +50,24 @@ private IEnumerator InitializeYooAsset()
注意:该模式需要构建资源包
- LocationServices : 资源定位的实例类。
(1) 默认的资源定位服务类DefaultLocationServices
(2) 可寻址的资源定位服务类AddressLocationServices
(3) 开发者自定义的资源定位服务类需要提供实现ILocationServices接口的实例类。
- DecryptionServices : 如果资源包在构建的时候有加密需要提供实现IDecryptionServices接口的实例类。
- QueryServices内置资源查询服务接口。
- DefaultHostServer : 默认的资源服务器IP地址。
- FallbackHostServer : 备用的资源服务器IP地址。
- VerifyLevel : 下载文件校验等级
````c#
private IEnumerator InitializeYooAsset()
{
var initParameters = new YooAssets.HostPlayModeParameters();
var initParameters = new HostPlayModeParameters();
initParameters.LocationServices = new DefaultLocationServices("Assets/GameRes");
initParameters.DecryptionServices = new BundleDecryptionServices();
initParameters.QueryServices = new QueryStreamingAssetsServices();
initParameters.DefaultHostServer = "http://127.0.0.1/CDN1/Android/v1.0";
initParameters.FallbackHostServer = "http://127.0.0.1/CDN2/Android/v1.0";
yield return YooAssets.InitializeAsync(initParameters);
yield return defaultPackage.InitializeAsync(initParameters);
}
// 文件解密服务类
@@ -88,7 +85,8 @@ private class QueryStreamingAssetsServices : IQueryServices
public bool QueryStreamingAssets(string fileName)
{
// 注意使用了BetterStreamingAssets插件
return BetterStreamingAssets.FileExists($"YooAssets/{fileName}");
string buildinFolderName = YooAssets.GetStreamingAssetBuildinFolderName();
return BetterStreamingAssets.FileExists($"{buildinFolderName}/{fileName}");
}
}
````

View File

@@ -9,7 +9,8 @@
````c#
private IEnumerator UpdateStaticVersion()
{
UpdateStaticVersionOperation operation = YooAssets.UpdateStaticVersionAsync();
var package = YooAssets.GetAssetsPackage("DefaultPackage");
UpdateStaticVersionOperation operation = package.UpdateStaticVersionAsync();
yield return operation;
if (operation.Status == EOperationStatus.Succeed)
@@ -33,7 +34,8 @@ private IEnumerator UpdateStaticVersion()
````c#
private IEnumerator UpdatePatchManifest()
{
UpdateManifestOperation operation = YooAssets.UpdateManifestAsync(packageCRC);
var package = YooAssets.GetAssetsPackage("DefaultPackage");
UpdateManifestOperation operation = package.UpdateManifestAsync(packageCRC);
yield return operation;
if (operation.Status == EOperationStatus.Succeed)
@@ -56,15 +58,15 @@ private IEnumerator UpdatePatchManifest()
补丁包下载接口:
- YooAssets.CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain)
- YooAssets.CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout)
用于下载更新当前资源版本所有的资源包文件。
- YooAssets.CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain)
- YooAssets.CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout)
用于下载更新资源标签指定的资源包文件。
- YooAssets.CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain)
- YooAssets.CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout)
用于下载更新指定的资源列表依赖的资源包文件。
@@ -73,7 +75,8 @@ IEnumerator Download()
{
int downloadingMaxNum = 10;
int failedTryAgain = 3;
DownloaderOperation downloader = YooAssets.CreatePatchDownloader(downloadingMaxNum, failedTryAgain);
int timeout = 60;
var downloader = YooAssets.CreatePatchDownloader(downloadingMaxNum, failedTryAgain, timeout);
//没有需要下载的资源
if (downloader.TotalDownloadCount == 0)
@@ -114,7 +117,8 @@ IEnumerator Download()
````c#
private IEnumerator UpdateStaticVersion()
{
UpdateStaticVersionOperation operation = YooAssets.UpdateStaticVersionAsync(10);
var package = YooAssets.GetAssetsPackage("DefaultPackage");
UpdateStaticVersionOperation operation = package.UpdateStaticVersionAsync(10);
yield return operation;
if (operation.Status == EOperationStatus.Succeed)
{
@@ -135,7 +139,7 @@ private IEnumerator UpdateStaticVersion()
}
// 在弱联网情况下更新补丁清单
UpdateManifestOperation operation2 = YooAssets.WeaklyUpdateManifestAsync(packageCRC);
UpdateManifestOperation operation2 = package.WeaklyUpdateManifestAsync(packageCRC);
yield return operation2;
if (operation2.Status == EOperationStatus.Succeed)
{

View File

@@ -2,52 +2,41 @@
**加载方法**
- YooAssets.LoadAssetSync() 同步加载资源对象
- YooAssets.LoadAssetAsync() 异步加载资源对象
- YooAssets.LoadSubAssetsSync() 同步加载子资源对象
- YooAssets.LoadSubAssetsAsync() 异步加载子资源对象
- YooAssets.LoadSceneAsync() 异步加载场景
- YooAssets.GetRawFileAsync() 异步获取原生文件
- LoadAssetSync() 同步加载资源对象
- LoadAssetAsync() 异步加载资源对象
- LoadSubAssetsSync() 同步加载子资源对象
- LoadSubAssetsAsync() 异步加载子资源对象
- LoadSceneAsync() 异步加载场景
- GetRawFileAsync() 异步获取原生文件
**统一约定**
**Location**为资源的定位地址,也是加载资源对象的唯一标识符。
- DefaultLocationServices 默认资源定位服务location代表的是资源对象的相对路径。
- 在未开启可寻址模式下location代表的是资源对象的完整路径。
```c#
// 以工程内的音频文件为例:"Assets/GameRes/Audio/bgMusic.mp3"
// 设定资源路径的根目录为:"Assets/GameRes",后续加载的资源定位地址填写相对路径:"Audio/bgMusic"
var createParameters = new YooAssets.EditorSimulateModeParameters();
createParameters.LocationServices = new DefaultLocationServices("Assets/GameRes");
yield return YooAssets.InitializeAsync(createParameters);
......
YooAssets.LoadAssetAsync<AudioClip>("Audio/bgMusic");
package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic");
```
- AddressLocationServices 可寻址资源定位服务location代表的是资源对象可寻址地址。
- 在开启可寻址模式下location代表的是资源对象可寻址地址。
````c#
// 以工程内的音频文件为例:"Assets/GameRes/Audio/bgMusic.mp3"
// 需要在资源配置界面启用可寻址功能Enable Addressable
// 配置界面的可寻址规则为AddressByFileName那么资源定位地址填写文件名称"bgMusic"
var createParameters = new YooAssets.EditorSimulateModeParameters();
createParameters.LocationServices = new AddressLocationServices();
yield return YooAssets.InitializeAsync(createParameters);
......
YooAssets.LoadAssetAsync<AudioClip>("bgMusic");
package.LoadAssetAsync<AudioClip>("bgMusic");
````
**注意**以下范例执行环境是在DefaultLocationServices下。
**加载路径的匹配方式**
````C#
// 不带扩展名的模糊匹配
YooAssets.LoadAssetAsync<AudioClip>("Audio/bgMusic");
package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic");
// 带扩展名的精准匹配
YooAssets.LoadAssetAsync<AudioClip>("Audio/bgMusic.mp3");
package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
````
**异步加载范例**
@@ -56,7 +45,7 @@ YooAssets.LoadAssetAsync<AudioClip>("Audio/bgMusic.mp3");
// 委托加载方式
void Start()
{
AssetOperationHandle handle = YooAssets.LoadAssetAsync<AudioClip>("Audio/bgMusic.mp3");
AssetOperationHandle handle = package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
handle.Completed += Handle_Completed;
}
void Handle_Completed(AssetOperationHandle handle)
@@ -68,7 +57,7 @@ void Handle_Completed(AssetOperationHandle handle)
// 协程加载方式
IEnumerator Start()
{
AssetOperationHandle handle = YooAssets.LoadAssetAsync<AudioClip>("Audio/bgMusic.mp3");
AssetOperationHandle handle = package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
yield return handle;
AudioClip audioClip = handle.AssetObject as AudioClip;
}
@@ -77,7 +66,7 @@ IEnumerator Start()
// Task加载方式
async void Start()
{
AssetOperationHandle handle = YooAssets.LoadAssetAsync<AudioClip>("Audio/bgMusic.mp3");
AssetOperationHandle handle = package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
await handle.Task;
AudioClip audioClip = handle.AssetObject as AudioClip;
}
@@ -88,7 +77,7 @@ async void Start()
````C#
IEnumerator Start()
{
AssetOperationHandle handle = YooAssets.LoadAssetAsync<AudioClip>("Audio/bgMusic.mp3");
AssetOperationHandle handle = package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
yield return handle;
...
handle.Release();
@@ -104,7 +93,8 @@ IEnumerator Start()
````c#
private void UnloadAssets()
{
YooAssets.UnloadUnusedAssets();
var package = YooAssets.GetAssetsPackage("DefaultPackage");
package.UnloadUnusedAssets();
}
````
@@ -113,7 +103,7 @@ private void UnloadAssets()
````C#
IEnumerator Start()
{
AssetOperationHandle handle = YooAssets.LoadAssetAsync<GameObject>("Panel/login.prefab");
AssetOperationHandle handle = package.LoadAssetAsync<GameObject>("Assets/GameRes/Panel/login.prefab");
yield return handle;
GameObject go = handle.InstantiateSync();
Debug.Log($"Prefab name is {go.name}");
@@ -127,7 +117,7 @@ IEnumerator Start()
````c#
IEnumerator Start()
{
SubAssetsOperationHandle handle = YooAssets.LoadSubAssetsAsync<Sprite>(location);
SubAssetsOperationHandle handle = package.LoadSubAssetsAsync<Sprite>(location);
yield return handle;
var sprite = handle.GetSubAssetObject<Sprite>("spriteName");
Debug.Log($"Sprite name is {sprite.name}");
@@ -141,9 +131,10 @@ IEnumerator Start()
````c#
IEnumerator Start()
{
string location = "Assets/GameRes/Scene/Login";
var sceneMode = UnityEngine.SceneManagement.LoadSceneMode.Single;
bool activateOnLoad = true;
SceneOperationHandle handle = YooAssets.LoadSceneAsync("Scene/Login", sceneMode, activateOnLoad);
SceneOperationHandle handle = package.LoadSceneAsync(location, sceneMode, activateOnLoad);
yield return handle;
Debug.Log($"Scene name is {handle.Scene.name}");
}
@@ -156,9 +147,9 @@ IEnumerator Start()
````c#
IEnumerator Start()
{
string location = "wwise/init.bnk";
string location = "Assets/GameRes/wwise/init.bnk";
string copyPath = $"{Application.persistentDataPath}/Audio/init.bnk";
RawFileOperation operation = YooAssets.GetRawFileAsync(location, copyPath);
RawFileOperation operation = package.GetRawFileAsync(location, copyPath);
yield return operation;
byte[] fileData = operation.GetFileData();
string fileText = operation.GetFileText();
@@ -172,7 +163,7 @@ IEnumerator Start()
````c#
private GetAssetInfosByTag(string tag)
{
AssetInfo[] assetInfos = YooAssets.GetAssetInfos(tag);
AssetInfo[] assetInfos = package.GetAssetInfos(tag);
foreach (var assetInfo in assetInfos)
{
Debug.Log(assetInfo.AssetPath);

View File

@@ -12,8 +12,9 @@ private List<AssetOperationHandle> _handles = new List<AssetOperationHandle>(100
private object LoadFunc(string name, string extension, System.Type type, out DestroyMethod method)
{
method = DestroyMethod.None; //注意这里一定要设置为None
string location = $"FairyRes/{name}{extension}";
var handle = YooAssets.LoadAssetSync(location , type);
string location = $"Assets/FairyRes/{name}{extension}";
var assetPackage = YooAssets.GetAssetsPackage("DefaultPackage");
var handle = assetPackage.LoadAssetSync(location , type);
_handles.Add(handle);
return handle.AssetObject;
}
@@ -43,7 +44,8 @@ private void ReleaseHandles()
代码示例
```csharp
var handle = YooAssets.LoadAssetAsync<GameObject>("Assets/Res/Prefabs/TestImg.prefab");
var assetPackage = YooAssets.GetAssetsPackage("DefaultPackage");
var handle = assetPackage.LoadAssetAsync<GameObject>("Assets/Res/Prefabs/TestImg.prefab");
await handle.ToUniTask();
@@ -65,32 +67,30 @@ go.transform.localScale = Vector3.one;
在运行游戏之前,请保证资源包可以构建成功!
```c#
public static YooAssetPackage AssetPackage;
IEnumerator Start()
{
// 初始化YooAssets资源系统必须代码
YooAssets.Initialize();
// 创建资源包实例
AssetPackage = YooAssets.CreateAssetPackage("DefaultPackage");
var package = YooAssets.CreateAssetPackage("DefaultPackage");
// 初始化资源包
......
yield return AssetPackage.InitializeAsync(createParameters);
yield return package.InitializeAsync(createParameters);
// 更新资源包版本
......
var operation = AssetPackage.UpdateManifestAsync(packageCRC);
var operation = package.UpdateManifestAsync(packageCRC);
yield return operation;
// 下载更新文件
var downloader = AssetPackage.CreatePatchDownloader(downloadingMaxNum, failedTryAgain);
var downloader = package.CreatePatchDownloader(downloadingMaxNum, failedTryAgain);
downloader.BeginDownload();
yield return downloader;
// 加载资源对象
var assetHandle = AssetPackage.LoadAssetAsync("Assets/GameRes/npc.prefab");
var assetHandle = package.LoadAssetAsync("Assets/GameRes/npc.prefab");
yield return assetHandle;
......
}

View File

@@ -17,6 +17,33 @@ windows平台添加命令: **-force-gles**
YooAsset依赖于ScriptBuildPipelineSBP在PackageManager里找到SBP插件安装就可以了。
#### 问题使用FileZilla等FTP上传工具后文件下载总是验证失败
把传输类型修改为二进制就可以了。
#### 问题ClearCacheWhenDirty参数没了吗
不是很必须的一个功能,已经移除了。可以使用以下方法代替:
````c#
// 参考DEMO的代码
internal class FsmClearCache : IFsmNode
{
void IFsmNode.OnEnter()
{
Debug.Log("清理未使用的缓存文件!");
var operation = YooAssets.ClearUnusedCacheFiles();
operation.Completed += Operation_Completed;
}
private void Operation_Completed(YooAsset.AsyncOperationBase obj)
{
Debug.Log("开始游戏!");
......
}
}
````
#### 问题YooAsset支持Unity2018吗
YooAsset分俩部分编辑器代码和运行时代码。因为工具界面是使用UIElements编写的所以在Unity2019以前的版本是使用不了界面化工具。但是这并没有影响我们使用YooAsset以下提供一种解决方案。

Some files were not shown because too many files have changed in this diff Show More