parent
a25fd19bcc
commit
7683746032
|
@ -48,6 +48,12 @@ namespace YooAsset.Editor
|
||||||
BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
|
BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
|
||||||
opt |= BuildAssetBundleOptions.StrictMode; //Do not allow the build to succeed if any errors are reporting during it.
|
opt |= BuildAssetBundleOptions.StrictMode; //Do not allow the build to succeed if any errors are reporting during it.
|
||||||
|
|
||||||
|
if (Parameters.DryRunBuild)
|
||||||
|
{
|
||||||
|
opt |= BuildAssetBundleOptions.DryRunBuild;
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
if (Parameters.CompressOption == ECompressOption.Uncompressed)
|
if (Parameters.CompressOption == ECompressOption.Uncompressed)
|
||||||
opt |= BuildAssetBundleOptions.UncompressedAssetBundle;
|
opt |= BuildAssetBundleOptions.UncompressedAssetBundle;
|
||||||
else if (Parameters.CompressOption == ECompressOption.LZ4)
|
else if (Parameters.CompressOption == ECompressOption.LZ4)
|
||||||
|
@ -107,7 +113,8 @@ namespace YooAsset.Editor
|
||||||
{
|
{
|
||||||
new TaskPrepare(), //前期准备工作
|
new TaskPrepare(), //前期准备工作
|
||||||
new TaskGetBuildMap(), //获取构建列表
|
new TaskGetBuildMap(), //获取构建列表
|
||||||
new TaskBuilding(), //开始执行构建
|
new TaskBuilding(), //开始执行构建
|
||||||
|
new TaskVerifyBuildResult(), //验证构建结果
|
||||||
new TaskEncryption(), //加密资源文件
|
new TaskEncryption(), //加密资源文件
|
||||||
new TaskCreatePatchManifest(), //创建清单文件
|
new TaskCreatePatchManifest(), //创建清单文件
|
||||||
new TaskCreateReport(), //创建报告文件
|
new TaskCreateReport(), //创建报告文件
|
||||||
|
|
|
@ -46,6 +46,11 @@ namespace YooAsset.Editor
|
||||||
public IEncryptionServices EncryptionServices;
|
public IEncryptionServices EncryptionServices;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 演练构建模式
|
||||||
|
/// </summary>
|
||||||
|
public bool DryRunBuild;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 强制重新构建整个项目,如果为FALSE则是增量打包
|
/// 强制重新构建整个项目,如果为FALSE则是增量打包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace YooAsset.Editor
|
||||||
public string EncryptionServicesClassName;
|
public string EncryptionServicesClassName;
|
||||||
|
|
||||||
// 构建参数
|
// 构建参数
|
||||||
|
public bool DryRunBuild;
|
||||||
public bool ForceRebuild;
|
public bool ForceRebuild;
|
||||||
public string BuildinTags;
|
public string BuildinTags;
|
||||||
public ECompressOption CompressOption;
|
public ECompressOption CompressOption;
|
||||||
|
|
|
@ -28,7 +28,8 @@ namespace YooAsset.Editor
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Debug.LogError($"Build task {task.GetType().Name} failed : {e}");
|
Debug.LogError($"Build task {task.GetType().Name} failed !");
|
||||||
|
Debug.LogError($"Detail error : {e}");
|
||||||
succeed = false;
|
succeed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,164 +31,29 @@ namespace YooAsset.Editor
|
||||||
context.SetContextObject(unityManifestContext);
|
context.SetContextObject(unityManifestContext);
|
||||||
|
|
||||||
// 拷贝原生文件
|
// 拷贝原生文件
|
||||||
|
if (buildParametersContext.Parameters.DryRunBuild == false)
|
||||||
|
{
|
||||||
|
CopyRawBundle(buildMapContext, buildParametersContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝原生文件
|
||||||
|
/// </summary>
|
||||||
|
private void CopyRawBundle(BuildMapContext buildMapContext, AssetBundleBuilder.BuildParametersContext buildParametersContext)
|
||||||
|
{
|
||||||
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
||||||
{
|
{
|
||||||
if (bundleInfo.IsRawFile)
|
if (bundleInfo.IsRawFile)
|
||||||
{
|
{
|
||||||
string dest = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
|
string dest = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||||
foreach(var buildAsset in bundleInfo.BuildinAssets)
|
foreach (var buildAsset in bundleInfo.BuildinAssets)
|
||||||
{
|
{
|
||||||
if(buildAsset.IsRawAsset)
|
if (buildAsset.IsRawAsset)
|
||||||
EditorTools.CopyFile(buildAsset.AssetPath, dest, true);
|
EditorTools.CopyFile(buildAsset.AssetPath, dest, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证构建结果
|
|
||||||
if (buildParametersContext.Parameters.VerifyBuildingResult)
|
|
||||||
{
|
|
||||||
VerifyingBuildingResult(context, unityManifest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 验证构建结果
|
|
||||||
/// </summary>
|
|
||||||
private void VerifyingBuildingResult(BuildContext context, AssetBundleManifest unityManifest)
|
|
||||||
{
|
|
||||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
|
||||||
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
|
||||||
string[] buildedBundles = unityManifest.GetAllAssetBundles();
|
|
||||||
|
|
||||||
// 1. 过滤掉原生Bundle
|
|
||||||
List<BuildBundleInfo> expectBundles = new List<BuildBundleInfo>(buildedBundles.Length);
|
|
||||||
foreach(var bundleInfo in buildMapContext.BundleInfos)
|
|
||||||
{
|
|
||||||
if (bundleInfo.IsRawFile == false)
|
|
||||||
expectBundles.Add(bundleInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 验证数量
|
|
||||||
if (buildedBundles.Length != expectBundles.Count)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"构建过程中可能存在无效的资源,导致和预期构建的Bundle数量不一致!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 正向验证Bundle
|
|
||||||
foreach (var bundleName in buildedBundles)
|
|
||||||
{
|
|
||||||
if (buildMapContext.IsContainsBundle(bundleName) == false)
|
|
||||||
{
|
|
||||||
throw new Exception($"Should never get here !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 反向验证Bundle
|
|
||||||
bool isPass = true;
|
|
||||||
foreach (var expectBundle in expectBundles)
|
|
||||||
{
|
|
||||||
bool isMatch = false;
|
|
||||||
foreach (var buildedBundle in buildedBundles)
|
|
||||||
{
|
|
||||||
if (buildedBundle == expectBundle.BundleName)
|
|
||||||
{
|
|
||||||
isMatch = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isMatch == false)
|
|
||||||
{
|
|
||||||
isPass = false;
|
|
||||||
Debug.LogWarning($"没有找到预期构建的Bundle文件 : {expectBundle.BundleName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(isPass == false)
|
|
||||||
{
|
|
||||||
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. 验证Asset
|
|
||||||
int progressValue = 0;
|
|
||||||
foreach (var buildedBundle in buildedBundles)
|
|
||||||
{
|
|
||||||
string filePath = $"{buildParameters.PipelineOutputDirectory}/{buildedBundle}";
|
|
||||||
string[] allBuildinAssetPaths = GetAssetBundleAllAssets(filePath);
|
|
||||||
string[] expectBuildinAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle);
|
|
||||||
if (expectBuildinAssetPaths.Length != allBuildinAssetPaths.Length)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}");
|
|
||||||
isPass = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var buildinAssetPath in allBuildinAssetPaths)
|
|
||||||
{
|
|
||||||
var guid = AssetDatabase.AssetPathToGUID(buildinAssetPath);
|
|
||||||
if (string.IsNullOrEmpty(guid))
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"无效的资源路径,请检查路径是否带有特殊符号或中文:{buildinAssetPath}");
|
|
||||||
isPass = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isMatch = false;
|
|
||||||
foreach (var exceptBuildAssetPath in expectBuildinAssetPaths)
|
|
||||||
{
|
|
||||||
var guidExcept = AssetDatabase.AssetPathToGUID(exceptBuildAssetPath);
|
|
||||||
if (guid == guidExcept)
|
|
||||||
{
|
|
||||||
isMatch = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isMatch == false)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"在构建的Bundle文件里发现了没有匹配的资源对象:{buildinAssetPath}");
|
|
||||||
isPass = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorTools.DisplayProgressBar("验证构建结果", ++progressValue, buildedBundles.Length);
|
|
||||||
}
|
|
||||||
EditorTools.ClearProgressBar();
|
|
||||||
if (isPass == false)
|
|
||||||
{
|
|
||||||
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 卸载所有加载的Bundle
|
|
||||||
Debug.Log("构建结果验证成功!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 解析.manifest文件并获取资源列表
|
|
||||||
/// </summary>
|
|
||||||
private string[] GetAssetBundleAllAssets(string filePath)
|
|
||||||
{
|
|
||||||
string manifestFilePath = $"{filePath}.manifest";
|
|
||||||
List<string> assetLines = new List<string>();
|
|
||||||
using (StreamReader reader = File.OpenText(manifestFilePath))
|
|
||||||
{
|
|
||||||
string content;
|
|
||||||
bool findTarget = false;
|
|
||||||
while (null != (content = reader.ReadLine()))
|
|
||||||
{
|
|
||||||
if (content.StartsWith("Dependencies:"))
|
|
||||||
break;
|
|
||||||
if (findTarget == false && content.StartsWith("Assets:"))
|
|
||||||
findTarget = true;
|
|
||||||
if (findTarget)
|
|
||||||
{
|
|
||||||
if (content.StartsWith("- "))
|
|
||||||
{
|
|
||||||
string assetPath = content.TrimStart("- ".ToCharArray());
|
|
||||||
assetLines.Add(assetPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return assetLines.ToArray();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,7 +15,7 @@ namespace YooAsset.Editor
|
||||||
{
|
{
|
||||||
// 注意:我们只有在强制重建的时候才会拷贝
|
// 注意:我们只有在强制重建的时候才会拷贝
|
||||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||||
if (buildParameters.Parameters.ForceRebuild)
|
if (buildParameters.Parameters.DryRunBuild == false && buildParameters.Parameters.ForceRebuild)
|
||||||
{
|
{
|
||||||
// 清空流目录
|
// 清空流目录
|
||||||
AssetBundleBuilderHelper.ClearStreamingAssetsFolder();
|
AssetBundleBuilderHelper.ClearStreamingAssetsFolder();
|
||||||
|
|
|
@ -62,14 +62,14 @@ namespace YooAsset.Editor
|
||||||
// 内置标记列表
|
// 内置标记列表
|
||||||
List<string> buildinTags = buildParameters.Parameters.GetBuildinTags();
|
List<string> buildinTags = buildParameters.Parameters.GetBuildinTags();
|
||||||
|
|
||||||
|
bool dryRunBuild = buildParameters.Parameters.DryRunBuild;
|
||||||
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
||||||
{
|
{
|
||||||
var bundleName = bundleInfo.BundleName;
|
var bundleName = bundleInfo.BundleName;
|
||||||
string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleName}";
|
string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleName}";
|
||||||
string hash = HashUtility.FileMD5(filePath);
|
string hash = GetFileHash(filePath, dryRunBuild);
|
||||||
string crc32 = HashUtility.FileCRC32(filePath);
|
string crc32 = GetFileCRC(filePath, dryRunBuild);
|
||||||
long size = FileUtility.GetFileSize(filePath);
|
long size = GetFileSize(filePath, dryRunBuild);
|
||||||
int version = buildParameters.Parameters.BuildVersion;
|
|
||||||
string[] tags = buildMapContext.GetAssetTags(bundleName);
|
string[] tags = buildMapContext.GetAssetTags(bundleName);
|
||||||
bool isEncrypted = encryptionContext.IsEncryptFile(bundleName);
|
bool isEncrypted = encryptionContext.IsEncryptFile(bundleName);
|
||||||
bool isBuildin = IsBuildinBundle(tags, buildinTags);
|
bool isBuildin = IsBuildinBundle(tags, buildinTags);
|
||||||
|
@ -101,6 +101,27 @@ namespace YooAsset.Editor
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
private string GetFileHash(string filePath, bool dryRunBuild)
|
||||||
|
{
|
||||||
|
if (dryRunBuild)
|
||||||
|
return "00000000000000000000000000000000"; //32位
|
||||||
|
else
|
||||||
|
return HashUtility.FileMD5(filePath);
|
||||||
|
}
|
||||||
|
private string GetFileCRC(string filePath, bool dryRunBuild)
|
||||||
|
{
|
||||||
|
if (dryRunBuild)
|
||||||
|
return "00000000"; //8位
|
||||||
|
else
|
||||||
|
return HashUtility.FileCRC32(filePath);
|
||||||
|
}
|
||||||
|
private long GetFileSize(string filePath, bool dryRunBuild)
|
||||||
|
{
|
||||||
|
if (dryRunBuild)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return FileUtility.GetFileSize(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取资源列表
|
/// 获取资源列表
|
||||||
|
|
|
@ -11,7 +11,10 @@ namespace YooAsset.Editor
|
||||||
void IBuildTask.Run(BuildContext context)
|
void IBuildTask.Run(BuildContext context)
|
||||||
{
|
{
|
||||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||||
CopyPatchFiles(buildParameters);
|
if (buildParameters.Parameters.DryRunBuild == false)
|
||||||
|
{
|
||||||
|
CopyPatchFiles(buildParameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -35,8 +35,9 @@ namespace YooAsset.Editor
|
||||||
buildReport.Summary.ShadersBundleName = AssetBundleGrouperSettingData.Setting.ShadersBundleName;
|
buildReport.Summary.ShadersBundleName = AssetBundleGrouperSettingData.Setting.ShadersBundleName;
|
||||||
buildReport.Summary.EncryptionServicesClassName = buildParameters.Parameters.EncryptionServices == null ?
|
buildReport.Summary.EncryptionServicesClassName = buildParameters.Parameters.EncryptionServices == null ?
|
||||||
"null" : buildParameters.Parameters.EncryptionServices.GetType().FullName;
|
"null" : buildParameters.Parameters.EncryptionServices.GetType().FullName;
|
||||||
|
|
||||||
// 构建参数
|
// 构建参数
|
||||||
|
buildReport.Summary.DryRunBuild = buildParameters.Parameters.DryRunBuild;
|
||||||
buildReport.Summary.ForceRebuild = buildParameters.Parameters.ForceRebuild;
|
buildReport.Summary.ForceRebuild = buildParameters.Parameters.ForceRebuild;
|
||||||
buildReport.Summary.BuildinTags = buildParameters.Parameters.BuildinTags;
|
buildReport.Summary.BuildinTags = buildParameters.Parameters.BuildinTags;
|
||||||
buildReport.Summary.CompressOption = buildParameters.Parameters.CompressOption;
|
buildReport.Summary.CompressOption = buildParameters.Parameters.CompressOption;
|
||||||
|
|
|
@ -26,9 +26,18 @@ namespace YooAsset.Editor
|
||||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||||
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
|
||||||
EncryptionContext encryptionContext = new EncryptionContext();
|
if (buildParameters.Parameters.DryRunBuild)
|
||||||
encryptionContext.EncryptList = EncryptFiles(buildParameters, buildMapContext);
|
{
|
||||||
context.SetContextObject(encryptionContext);
|
EncryptionContext encryptionContext = new EncryptionContext();
|
||||||
|
encryptionContext.EncryptList = new List<string>();
|
||||||
|
context.SetContextObject(encryptionContext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EncryptionContext encryptionContext = new EncryptionContext();
|
||||||
|
encryptionContext.EncryptList = EncryptFiles(buildParameters, buildMapContext);
|
||||||
|
context.SetContextObject(encryptionContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class TaskVerifyBuildResult : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||||
|
var unityManifestContext = context.GetContextObject<TaskBuilding.UnityManifestContext>();
|
||||||
|
|
||||||
|
// 验证构建结果
|
||||||
|
if (buildParametersContext.Parameters.VerifyBuildingResult)
|
||||||
|
{
|
||||||
|
VerifyingBuildingResult(context, unityManifestContext.UnityManifest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证构建结果
|
||||||
|
/// </summary>
|
||||||
|
private void VerifyingBuildingResult(BuildContext context, AssetBundleManifest unityManifest)
|
||||||
|
{
|
||||||
|
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
string[] buildedBundles = unityManifest.GetAllAssetBundles();
|
||||||
|
|
||||||
|
// 1. 过滤掉原生Bundle
|
||||||
|
List<BuildBundleInfo> expectBundles = new List<BuildBundleInfo>(buildedBundles.Length);
|
||||||
|
foreach(var bundleInfo in buildMapContext.BundleInfos)
|
||||||
|
{
|
||||||
|
if (bundleInfo.IsRawFile == false)
|
||||||
|
expectBundles.Add(bundleInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 验证数量
|
||||||
|
if (buildedBundles.Length != expectBundles.Count)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"构建过程中可能存在无效的资源,导致和预期构建的Bundle数量不一致!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 正向验证Bundle
|
||||||
|
foreach (var bundleName in buildedBundles)
|
||||||
|
{
|
||||||
|
if (buildMapContext.IsContainsBundle(bundleName) == false)
|
||||||
|
{
|
||||||
|
throw new Exception($"Should never get here !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 反向验证Bundle
|
||||||
|
bool isPass = true;
|
||||||
|
foreach (var expectBundle in expectBundles)
|
||||||
|
{
|
||||||
|
bool isMatch = false;
|
||||||
|
foreach (var buildedBundle in buildedBundles)
|
||||||
|
{
|
||||||
|
if (buildedBundle == expectBundle.BundleName)
|
||||||
|
{
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isMatch == false)
|
||||||
|
{
|
||||||
|
isPass = false;
|
||||||
|
Debug.LogWarning($"没有找到预期构建的Bundle文件 : {expectBundle.BundleName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isPass == false)
|
||||||
|
{
|
||||||
|
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 验证Asset
|
||||||
|
if(buildParameters.Parameters.DryRunBuild == false)
|
||||||
|
{
|
||||||
|
int progressValue = 0;
|
||||||
|
foreach (var buildedBundle in buildedBundles)
|
||||||
|
{
|
||||||
|
string filePath = $"{buildParameters.PipelineOutputDirectory}/{buildedBundle}";
|
||||||
|
string[] allBuildinAssetPaths = GetAssetBundleAllAssets(filePath);
|
||||||
|
string[] expectBuildinAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle);
|
||||||
|
if (expectBuildinAssetPaths.Length != allBuildinAssetPaths.Length)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}");
|
||||||
|
isPass = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var buildinAssetPath in allBuildinAssetPaths)
|
||||||
|
{
|
||||||
|
var guid = AssetDatabase.AssetPathToGUID(buildinAssetPath);
|
||||||
|
if (string.IsNullOrEmpty(guid))
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"无效的资源路径,请检查路径是否带有特殊符号或中文:{buildinAssetPath}");
|
||||||
|
isPass = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMatch = false;
|
||||||
|
foreach (var exceptBuildAssetPath in expectBuildinAssetPaths)
|
||||||
|
{
|
||||||
|
var guidExcept = AssetDatabase.AssetPathToGUID(exceptBuildAssetPath);
|
||||||
|
if (guid == guidExcept)
|
||||||
|
{
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isMatch == false)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"在构建的Bundle文件里发现了没有匹配的资源对象:{buildinAssetPath}");
|
||||||
|
isPass = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorTools.DisplayProgressBar("验证构建结果", ++progressValue, buildedBundles.Length);
|
||||||
|
}
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
if (isPass == false)
|
||||||
|
{
|
||||||
|
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 卸载所有加载的Bundle
|
||||||
|
Debug.Log("构建结果验证成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析.manifest文件并获取资源列表
|
||||||
|
/// </summary>
|
||||||
|
private string[] GetAssetBundleAllAssets(string filePath)
|
||||||
|
{
|
||||||
|
string manifestFilePath = $"{filePath}.manifest";
|
||||||
|
List<string> assetLines = new List<string>();
|
||||||
|
using (StreamReader reader = File.OpenText(manifestFilePath))
|
||||||
|
{
|
||||||
|
string content;
|
||||||
|
bool findTarget = false;
|
||||||
|
while (null != (content = reader.ReadLine()))
|
||||||
|
{
|
||||||
|
if (content.StartsWith("Dependencies:"))
|
||||||
|
break;
|
||||||
|
if (findTarget == false && content.StartsWith("Assets:"))
|
||||||
|
findTarget = true;
|
||||||
|
if (findTarget)
|
||||||
|
{
|
||||||
|
if (content.StartsWith("- "))
|
||||||
|
{
|
||||||
|
string assetPath = content.TrimStart("- ".ToCharArray());
|
||||||
|
assetLines.Add(assetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return assetLines.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b883ac0c3c25e8143847a9326e2961cf
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -234,7 +234,7 @@ namespace YooAsset.Editor
|
||||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||||
label.style.marginLeft = 3f;
|
label.style.marginLeft = 3f;
|
||||||
//label.style.flexGrow = 1f;
|
//label.style.flexGrow = 1f;
|
||||||
label.style.width = 250;
|
label.style.width = 280;
|
||||||
element.Add(label);
|
element.Add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||||
<uie:ToolbarButton text="Depend Bundles" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
<uie:ToolbarButton text="Depend Bundles" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||||
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="BottomBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
|
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="BottomBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||||
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="BottomBar3" style="width: 250px; -unity-text-align: middle-left;" />
|
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="BottomBar3" style="width: 280px; -unity-text-align: middle-left;" />
|
||||||
</uie:Toolbar>
|
</uie:Toolbar>
|
||||||
<ui:ListView focusable="true" name="BottomListView" item-height="18" style="flex-grow: 1;" />
|
<ui:ListView focusable="true" name="BottomListView" item-height="18" style="flex-grow: 1;" />
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
|
|
|
@ -145,7 +145,7 @@ namespace YooAsset.Editor
|
||||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||||
label.style.marginLeft = 3f;
|
label.style.marginLeft = 3f;
|
||||||
//label.style.flexGrow = 1f;
|
//label.style.flexGrow = 1f;
|
||||||
label.style.width = 250;
|
label.style.width = 280;
|
||||||
element.Add(label);
|
element.Add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ namespace YooAsset.Editor
|
||||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||||
label.style.marginLeft = 3f;
|
label.style.marginLeft = 3f;
|
||||||
//label.style.flexGrow = 1f;
|
//label.style.flexGrow = 1f;
|
||||||
label.style.width = 250;
|
label.style.width = 280;
|
||||||
element.Add(label);
|
element.Add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||||
<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="Bundle Name" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||||
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="TopBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
|
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="TopBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||||
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="TopBar3" style="width: 250px; -unity-text-align: middle-left;" />
|
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="TopBar3" style="width: 280px; -unity-text-align: middle-left;" />
|
||||||
<uie:ToolbarButton text="Tags" display-tooltip-when-elided="true" name="TopBar5" style="width: 80px; -unity-text-align: middle-left; flex-grow: 1;" />
|
<uie:ToolbarButton text="Tags" display-tooltip-when-elided="true" name="TopBar5" style="width: 80px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||||
</uie:Toolbar>
|
</uie:Toolbar>
|
||||||
<ui:ListView focusable="true" name="TopListView" item-height="18" style="flex-grow: 1;" />
|
<ui:ListView focusable="true" name="TopListView" item-height="18" style="flex-grow: 1;" />
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||||
<uie:ToolbarButton text="Include Assets" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
<uie:ToolbarButton text="Include Assets" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||||
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="BottomBar2" style="width: 100px; -unity-text-align: middle-left;" />
|
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="BottomBar2" style="width: 100px; -unity-text-align: middle-left;" />
|
||||||
<uie:ToolbarButton text="GUID" display-tooltip-when-elided="true" name="BottomBar3" style="width: 250px; -unity-text-align: middle-left;" />
|
<uie:ToolbarButton text="GUID" display-tooltip-when-elided="true" name="BottomBar3" style="width: 280px; -unity-text-align: middle-left;" />
|
||||||
</uie:Toolbar>
|
</uie:Toolbar>
|
||||||
<ui:ListView focusable="true" name="BottomListView" item-height="18" style="flex-grow: 1;" />
|
<ui:ListView focusable="true" name="BottomListView" item-height="18" style="flex-grow: 1;" />
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
|
|
|
@ -76,6 +76,7 @@ namespace YooAsset.Editor
|
||||||
|
|
||||||
_items.Add(new ItemWrapper(string.Empty, string.Empty));
|
_items.Add(new ItemWrapper(string.Empty, string.Empty));
|
||||||
_items.Add(new ItemWrapper("构建参数", string.Empty));
|
_items.Add(new ItemWrapper("构建参数", string.Empty));
|
||||||
|
_items.Add(new ItemWrapper("DryRunBuild", $"{buildReport.Summary.DryRunBuild}"));
|
||||||
_items.Add(new ItemWrapper("ForceRebuild", $"{buildReport.Summary.ForceRebuild}"));
|
_items.Add(new ItemWrapper("ForceRebuild", $"{buildReport.Summary.ForceRebuild}"));
|
||||||
_items.Add(new ItemWrapper("BuildinTags", $"{buildReport.Summary.BuildinTags}"));
|
_items.Add(new ItemWrapper("BuildinTags", $"{buildReport.Summary.BuildinTags}"));
|
||||||
_items.Add(new ItemWrapper("CompressOption", $"{buildReport.Summary.CompressOption}"));
|
_items.Add(new ItemWrapper("CompressOption", $"{buildReport.Summary.CompressOption}"));
|
||||||
|
|
Loading…
Reference in New Issue