Support fast build mode.

支持快速构建模式,真实的实现EditorPlayMode的运行时环境。
This commit is contained in:
hevinci
2022-05-02 23:15:09 +08:00
parent 8d02406211
commit 665a16fe60
39 changed files with 492 additions and 383 deletions
@@ -28,8 +28,10 @@ namespace YooAsset.Editor
Parameters = parameters;
PipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(parameters.OutputRoot, parameters.BuildTarget);
if (parameters.DryRunBuild)
PipelineOutputDirectory += "_DryRunBuild";
if (parameters.BuildMode == EBuildMode.DryRunBuild)
PipelineOutputDirectory += $"_{EBuildMode.DryRunBuild}";
else if(parameters.BuildMode == EBuildMode.FastRunBuild)
PipelineOutputDirectory += $"_{EBuildMode.FastRunBuild}";
}
/// <summary>
@@ -51,7 +53,12 @@ namespace YooAsset.Editor
BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
opt |= BuildAssetBundleOptions.StrictMode; //Do not allow the build to succeed if any errors are reporting during it.
if (Parameters.DryRunBuild)
if (Parameters.BuildMode == EBuildMode.FastRunBuild)
{
throw new Exception("Should never get here !");
}
if (Parameters.BuildMode == EBuildMode.DryRunBuild)
{
opt |= BuildAssetBundleOptions.DryRunBuild;
return opt;
@@ -62,7 +69,7 @@ namespace YooAsset.Editor
else if (Parameters.CompressOption == ECompressOption.LZ4)
opt |= BuildAssetBundleOptions.ChunkBasedCompression;
if (Parameters.ForceRebuild)
if (Parameters.BuildMode == EBuildMode.ForceRebuild)
opt |= BuildAssetBundleOptions.ForceRebuildAssetBundle; //Force rebuild the asset bundles
if (Parameters.AppendHash)
opt |= BuildAssetBundleOptions.AppendHashToAssetBundleName; //Append the hash to the assetBundle name
@@ -125,11 +132,16 @@ namespace YooAsset.Editor
new TaskCopyBuildinFiles(), //拷贝内置文件
};
if (buildParameters.BuildMode == EBuildMode.FastRunBuild)
BuildRunner.EnableLog = false;
else
BuildRunner.EnableLog = true;
bool succeed = BuildRunner.Run(pipeline, _buildContext);
if (succeed)
Debug.Log($"构建成功!");
Debug.Log($"{buildParameters.BuildMode}模式构建成功!");
else
Debug.LogWarning($"构建失败!");
Debug.LogWarning($"{buildParameters.BuildMode}模式构建失败!");
return succeed;
}
}
@@ -10,6 +10,16 @@ namespace YooAsset.Editor
/// </summary>
public int BuildVersion = 0;
/// <summary>
/// 构建模式
/// </summary>
public EBuildMode BuildMode = EBuildMode.ForceRebuild;
/// <summary>
/// 内置资源标签
/// </summary>
public string BuildTags = string.Empty;
/// <summary>
/// 压缩方式
/// </summary>
@@ -24,20 +34,5 @@ namespace YooAsset.Editor
/// 附加后缀格式
/// </summary>
public bool AppendExtension = false;
/// <summary>
/// 强制构建
/// </summary>
public bool ForceRebuild = false;
/// <summary>
/// 演练构建
/// </summary>
public bool DryRunBuild = false;
/// <summary>
/// 内置标签
/// </summary>
public string BuildTags = string.Empty;
}
}
@@ -22,15 +22,13 @@ namespace YooAsset.Editor
private List<Type> _encryptionServicesClassTypes;
private List<string> _encryptionServicesClassNames;
private TextField _buildOutputTxt;
private TextField _buildOutputField;
private IntegerField _buildVersionField;
private EnumField _compressionField;
private EnumField _buildModeField;
private TextField _buildTagsField;
private PopupField<string> _encryptionField;
private EnumField _compressionField;
private Toggle _appendExtensionToggle;
private Toggle _forceRebuildToggle;
private Toggle _dryRunBuildToggle;
private TextField _buildTagsTxt;
public void CreateGUI()
{
@@ -56,9 +54,9 @@ namespace YooAsset.Editor
// 输出目录
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
string pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(defaultOutputRoot, _buildTarget);
_buildOutputTxt = root.Q<TextField>("BuildOutput");
_buildOutputTxt.SetValueWithoutNotify(pipelineOutputDirectory);
_buildOutputTxt.SetEnabled(false);
_buildOutputField = root.Q<TextField>("BuildOutput");
_buildOutputField.SetValueWithoutNotify(pipelineOutputDirectory);
_buildOutputField.SetEnabled(false);
// 构建版本
_buildVersionField = root.Q<IntegerField>("BuildVersion");
@@ -68,34 +66,33 @@ namespace YooAsset.Editor
AssetBundleBuilderSettingData.Setting.BuildVersion = _buildVersionField.value;
});
// 压缩方式
_compressionField = root.Q<EnumField>("Compression");
_compressionField.Init(AssetBundleBuilderSettingData.Setting.CompressOption);
_compressionField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.CompressOption);
_compressionField.style.width = 300;
_compressionField.SetEnabled(AssetBundleBuilderSettingData.Setting.DryRunBuild == false);
_compressionField.RegisterValueChangedCallback(evt =>
// 构建模式
_buildModeField = root.Q<EnumField>("BuildMode");
_buildModeField.Init(AssetBundleBuilderSettingData.Setting.BuildMode);
_buildModeField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.BuildMode);
_buildModeField.style.width = 300;
_buildModeField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.Setting.CompressOption = (ECompressOption)_compressionField.value;
AssetBundleBuilderSettingData.Setting.BuildMode = (EBuildMode)_buildModeField.value;
RefreshWindow();
});
// 内置资源标签
_buildTagsField = root.Q<TextField>("BuildinTags");
_buildTagsField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.BuildTags);
_buildTagsField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.Setting.BuildTags = _buildTagsField.value;
});
// 加密方法
var encryptionContainer = root.Q("EncryptionContainer");
if (_encryptionServicesClassNames.Count > 0)
{
int defaultIndex = 0;
for (int index = 0; index < _encryptionServicesClassNames.Count; index++)
{
if (_encryptionServicesClassNames[index] == AssetBundleBuilderSettingData.Setting.EncyptionClassName)
{
defaultIndex = index;
break;
}
}
int defaultIndex = GetEncryptionDefaultIndex(AssetBundleBuilderSettingData.Setting.EncyptionClassName);
_encryptionField = new PopupField<string>(_encryptionServicesClassNames, defaultIndex);
_encryptionField.label = "Encryption";
_encryptionField.style.width = 300;
_encryptionField.SetEnabled(AssetBundleBuilderSettingData.Setting.DryRunBuild == false);
_encryptionField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.Setting.EncyptionClassName = _encryptionField.value;
@@ -107,53 +104,32 @@ namespace YooAsset.Editor
_encryptionField = new PopupField<string>();
_encryptionField.label = "Encryption";
_encryptionField.style.width = 300;
_encryptionField.SetEnabled(AssetBundleBuilderSettingData.Setting.DryRunBuild == false);
encryptionContainer.Add(_encryptionField);
}
// 压缩方式
_compressionField = root.Q<EnumField>("Compression");
_compressionField.Init(AssetBundleBuilderSettingData.Setting.CompressOption);
_compressionField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.CompressOption);
_compressionField.style.width = 300;
_compressionField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.Setting.CompressOption = (ECompressOption)_compressionField.value;
});
// 附加后缀格式
_appendExtensionToggle = root.Q<Toggle>("AppendExtension");
_appendExtensionToggle.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.AppendExtension);
_appendExtensionToggle.SetEnabled(AssetBundleBuilderSettingData.Setting.DryRunBuild == false);
_appendExtensionToggle.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.Setting.AppendExtension = _appendExtensionToggle.value;
});
// 强制构建
_forceRebuildToggle = root.Q<Toggle>("ForceRebuild");
_forceRebuildToggle.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.ForceRebuild);
_forceRebuildToggle.SetEnabled(AssetBundleBuilderSettingData.Setting.DryRunBuild == false);
_forceRebuildToggle.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.Setting.ForceRebuild = _forceRebuildToggle.value;
_buildTagsTxt.SetEnabled(_forceRebuildToggle.value);
});
// 演练构建
_dryRunBuildToggle = root.Q<Toggle>("DryRunBuild");
_dryRunBuildToggle.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.DryRunBuild);
_dryRunBuildToggle.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.Setting.DryRunBuild = _dryRunBuildToggle.value;
_compressionField.SetEnabled(_dryRunBuildToggle.value == false);
_encryptionField.SetEnabled(_dryRunBuildToggle.value == false);
_appendExtensionToggle.SetEnabled(_dryRunBuildToggle.value == false);
_forceRebuildToggle.SetEnabled(_dryRunBuildToggle.value == false);
});
// 内置标签
_buildTagsTxt = root.Q<TextField>("BuildinTags");
_buildTagsTxt.SetEnabled(_forceRebuildToggle.value);
_buildTagsTxt.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.BuildTags);
_buildTagsTxt.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.Setting.BuildTags = _buildTagsTxt.value;
});
// 构建按钮
var buildButton = root.Q<Button>("Build");
buildButton.clicked += BuildButton_clicked; ;
RefreshWindow();
}
catch (Exception e)
{
@@ -165,21 +141,18 @@ namespace YooAsset.Editor
AssetBundleBuilderSettingData.SaveFile();
}
private void RefreshWindow()
{
bool enableElement = AssetBundleBuilderSettingData.Setting.BuildMode == EBuildMode.ForceRebuild;
_buildTagsField.SetEnabled(enableElement);
_encryptionField.SetEnabled(enableElement);
_compressionField.SetEnabled(enableElement);
_appendExtensionToggle.SetEnabled(enableElement);
}
private void BuildButton_clicked()
{
string title;
string content;
if (_forceRebuildToggle.value)
{
title = "警告";
content = "确定开始强制构建吗,这样会删除所有已有构建的文件";
}
else
{
title = "提示";
content = "确定开始增量构建吗";
}
if (EditorUtility.DisplayDialog(title, content, "Yes", "No"))
var buildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
if (EditorUtility.DisplayDialog("提示", $"通过构建模式【{buildMode}】来构建!", "Yes", "No"))
{
EditorTools.ClearUnityConsole();
EditorApplication.delayCall += ExecuteBuild;
@@ -197,35 +170,39 @@ namespace YooAsset.Editor
{
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
BuildParameters buildParameters = new BuildParameters();
buildParameters.VerifyBuildingResult = true;
buildParameters.OutputRoot = defaultOutputRoot;
buildParameters.BuildTarget = _buildTarget;
buildParameters.BuildMode = (EBuildMode)_buildModeField.value;
buildParameters.BuildVersion = _buildVersionField.value;
buildParameters.BuildinTags = _buildTagsField.value;
buildParameters.VerifyBuildingResult = true;
buildParameters.EnableAddressable = AssetBundleGrouperSettingData.Setting.EnableAddressable;
buildParameters.CompressOption = (ECompressOption)_compressionField.value;
buildParameters.AppendFileExtension = _appendExtensionToggle.value;
buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.ForceRebuild = _forceRebuildToggle.value;
buildParameters.DryRunBuild = _dryRunBuildToggle.value;
buildParameters.BuildinTags = _buildTagsTxt.value;
buildParameters.CompressOption = (ECompressOption)_compressionField.value;
AssetBundleBuilder builder = new AssetBundleBuilder();
builder.Run(buildParameters);
}
/// <summary>
/// 获取加密类的类型列表
/// </summary>
// 加密类相关
private int GetEncryptionDefaultIndex(string className)
{
for (int index = 0; index < _encryptionServicesClassNames.Count; index++)
{
if (_encryptionServicesClassNames[index] == className)
{
return index;
}
}
return 0;
}
private List<Type> GetEncryptionServicesClassTypes()
{
TypeCache.TypeCollection collection = TypeCache.GetTypesDerivedFrom<IEncryptionServices>();
List<Type> classTypes = collection.ToList();
return classTypes;
}
/// <summary>
/// 创建加密类的实例
/// </summary>
private IEncryptionServices CreateEncryptionServicesInstance()
{
if (_encryptionField.index < 0)
@@ -3,11 +3,10 @@
<ui:VisualElement name="BuildContainer">
<ui:TextField picking-mode="Ignore" label="Build Output" name="BuildOutput" />
<uie:IntegerField label="Build Version" value="0" name="BuildVersion" />
<uie:EnumField label="Compression" value="Center" name="Compression" />
<uie:EnumField label="Build Mode" name="BuildMode" />
<ui:VisualElement name="EncryptionContainer" style="height: 24px;" />
<uie:EnumField label="Compression" value="Center" name="Compression" />
<ui:Toggle label="Append Extension" name="AppendExtension" style="height: 15px;" />
<ui:Toggle label="Force Rebuild" name="ForceRebuild" />
<ui:Toggle label="Dry Run Build" name="DryRunBuild" />
<ui:TextField picking-mode="Ignore" label="Buildin Tags" name="BuildinTags" />
<ui:Button text="构建" display-tooltip-when-elided="true" name="Build" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
</ui:VisualElement>
@@ -0,0 +1,45 @@
using System;
using UnityEditor;
namespace YooAsset.Editor
{
public static class AssetBundleRuntimeBuilder
{
private static string _manifestFilePath = string.Empty;
/// <summary>
/// 快速模式构建
/// </summary>
public static void FastBuild()
{
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
BuildParameters buildParameters = new BuildParameters();
buildParameters.OutputRoot = defaultOutputRoot;
buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
buildParameters.BuildMode = EBuildMode.FastRunBuild;
buildParameters.BuildVersion = AssetBundleBuilderSettingData.Setting.BuildVersion;
buildParameters.BuildinTags = AssetBundleBuilderSettingData.Setting.BuildTags;
buildParameters.EnableAddressable = AssetBundleGrouperSettingData.Setting.EnableAddressable;
AssetBundleBuilder builder = new AssetBundleBuilder();
bool buildResult = builder.Run(buildParameters);
if (buildResult)
{
string pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(buildParameters.OutputRoot, buildParameters.BuildTarget);
_manifestFilePath = $"{pipelineOutputDirectory}_{EBuildMode.FastRunBuild}/{YooAssetSettingsData.GetPatchManifestFileName(buildParameters.BuildVersion)}";
}
else
{
_manifestFilePath = null;
}
}
/// <summary>
/// 获取构建的补丁清单文件路径
/// </summary>
public static string GetPatchManifestFilePath()
{
return _manifestFilePath;
}
}
}
@@ -127,7 +127,7 @@ namespace YooAsset.Editor
}
}
UnityEngine.Debug.Log($"发现未被依赖的资源并自动移除 : {dependAssetPath}");
BuildRunner.Log($"发现未被依赖的资源并自动移除 : {dependAssetPath}");
return true;
}
}
@@ -9,11 +9,6 @@ namespace YooAsset.Editor
/// </summary>
public class BuildParameters
{
/// <summary>
/// 验证构建结果
/// </summary>
public bool VerifyBuildingResult = false;
/// <summary>
/// 输出的根目录
/// </summary>
@@ -24,11 +19,28 @@ namespace YooAsset.Editor
/// </summary>
public BuildTarget BuildTarget;
/// <summary>
/// 构建模式
/// </summary>
public EBuildMode BuildMode;
/// <summary>
/// 构建的版本(资源版本号)
/// </summary>
public int BuildVersion;
/// <summary>
/// 内置资源的标记列表
/// 注意:分号为分隔符
/// </summary>
public string BuildinTags;
/// <summary>
/// 验证构建结果
/// </summary>
public bool VerifyBuildingResult = false;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
@@ -45,32 +57,16 @@ namespace YooAsset.Editor
/// </summary>
public bool AppendFileExtension = false;
/// <summary>
/// 加密类
/// </summary>
public IEncryptionServices EncryptionServices;
/// <summary>
/// 演练构建模式
/// </summary>
public bool DryRunBuild;
/// <summary>
/// 强制重新构建整个项目,如果为FALSE则是增量打包
/// </summary>
public bool ForceRebuild;
/// <summary>
/// 内置资源的标记列表
/// 注意:分号为分隔符
/// </summary>
public string BuildinTags;
public IEncryptionServices EncryptionServices = null;
/// <summary>
/// 压缩选项
/// </summary>
public ECompressOption CompressOption;
public ECompressOption CompressOption = ECompressOption.Uncompressed;
/// <summary>
/// 文件名附加上哈希值
@@ -28,11 +28,21 @@ namespace YooAsset.Editor
/// </summary>
public BuildTarget BuildTarget;
/// <summary>
/// 构建模式
/// </summary>
public EBuildMode BuildMode;
/// <summary>
/// 构建版本
/// </summary>
public int BuildVersion;
/// <summary>
/// 内置资源标签
/// </summary>
public string BuildinTags;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
@@ -64,9 +74,6 @@ namespace YooAsset.Editor
public string EncryptionServicesClassName;
// 构建参数
public bool DryRunBuild;
public bool ForceRebuild;
public string BuildinTags;
public ECompressOption CompressOption;
public bool AppendHash;
public bool DisableWriteTypeTree;
@@ -8,6 +8,8 @@ namespace YooAsset.Editor
{
public class BuildRunner
{
public static bool EnableLog = true;
/// <summary>
/// 执行构建流程
/// </summary>
@@ -26,7 +28,7 @@ namespace YooAsset.Editor
try
{
var taskAttribute = task.GetType().GetCustomAttribute<TaskAttribute>();
Debug.Log($"---------------------------------------->{taskAttribute.Desc}");
Log($"---------------------------------------->{taskAttribute.Desc}");
task.Run(context);
}
catch (Exception e)
@@ -41,5 +43,16 @@ namespace YooAsset.Editor
// 返回运行结果
return succeed;
}
/// <summary>
/// 普通日志输出
/// </summary>
public static void Log(string info)
{
if (EnableLog)
{
UnityEngine.Debug.Log(info);
}
}
}
}
@@ -21,18 +21,23 @@ namespace YooAsset.Editor
var buildParametersContext = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
// 快速构建模式下跳过引擎构建
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.FastRunBuild)
return;
BuildAssetBundleOptions opt = buildParametersContext.GetPipelineBuildOptions();
AssetBundleManifest unityManifest = BuildPipeline.BuildAssetBundles(buildParametersContext.PipelineOutputDirectory, buildMapContext.GetPipelineBuilds(), opt, buildParametersContext.Parameters.BuildTarget);
if (unityManifest == null)
throw new Exception("构建过程中发生错误!");
Debug.Log("Unity引擎打包成功!");
BuildRunner.Log("Unity引擎打包成功!");
UnityManifestContext unityManifestContext = new UnityManifestContext();
unityManifestContext.UnityManifest = unityManifest;
context.SetContextObject(unityManifestContext);
// 拷贝原生文件
if (buildParametersContext.Parameters.DryRunBuild == false)
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
CopyRawBundle(buildMapContext, buildParametersContext);
}
@@ -13,7 +13,7 @@ namespace YooAsset.Editor
{
// 注意:我们只有在强制重建的时候才会拷贝
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
if (buildParameters.Parameters.DryRunBuild == false && buildParameters.Parameters.ForceRebuild)
if (buildParameters.Parameters.BuildMode == EBuildMode.ForceRebuild)
{
// 清空流目录
AssetBundleBuilderHelper.ClearStreamingAssetsFolder();
@@ -62,7 +62,7 @@ namespace YooAsset.Editor
// 刷新目录
AssetDatabase.Refresh();
Debug.Log($"内置文件拷贝完成:{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}");
BuildRunner.Log($"内置文件拷贝完成:{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}");
}
}
}
@@ -34,19 +34,19 @@ namespace YooAsset.Editor
// 创建补丁清单文件
string manifestFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(resourceVersion)}";
UnityEngine.Debug.Log($"创建补丁清单文件:{manifestFilePath}");
BuildRunner.Log($"创建补丁清单文件:{manifestFilePath}");
PatchManifest.Serialize(manifestFilePath, patchManifest);
// 创建补丁清单哈希文件
string manifestHashFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestHashFileName(resourceVersion)}";
string manifestHash = HashUtility.FileMD5(manifestFilePath);
UnityEngine.Debug.Log($"创建补丁清单哈希文件:{manifestHashFilePath}");
BuildRunner.Log($"创建补丁清单哈希文件:{manifestHashFilePath}");
FileUtility.CreateFile(manifestHashFilePath, manifestHash);
// 创建静态版本文件
string staticVersionFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettings.VersionFileName}";
string staticVersion = resourceVersion.ToString();
UnityEngine.Debug.Log($"创建静态版本文件:{staticVersionFilePath}");
BuildRunner.Log($"创建静态版本文件:{staticVersionFilePath}");
FileUtility.CreateFile(staticVersionFilePath, staticVersion);
}
@@ -61,14 +61,15 @@ namespace YooAsset.Editor
// 内置标记列表
List<string> buildinTags = buildParameters.Parameters.GetBuildinTags();
bool dryRunBuild = buildParameters.Parameters.DryRunBuild;
var buildMode = buildParameters.Parameters.BuildMode;
bool standardBuild = buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild;
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
var bundleName = bundleInfo.BundleName;
string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleName}";
string hash = GetFileHash(filePath, dryRunBuild);
string crc32 = GetFileCRC(filePath, dryRunBuild);
long size = GetFileSize(filePath, dryRunBuild);
string hash = GetFileHash(filePath, standardBuild);
string crc32 = GetFileCRC(filePath, standardBuild);
long size = GetFileSize(filePath, standardBuild);
string[] tags = buildMapContext.GetAssetTags(bundleName);
bool isEncrypted = encryptionContext.IsEncryptFile(bundleName);
bool isBuildin = IsBuildinBundle(tags, buildinTags);
@@ -100,26 +101,26 @@ namespace YooAsset.Editor
}
return false;
}
private string GetFileHash(string filePath, bool dryRunBuild)
private string GetFileHash(string filePath, bool standardBuild)
{
if (dryRunBuild)
return "00000000000000000000000000000000"; //32位
else
if (standardBuild)
return HashUtility.FileMD5(filePath);
}
private string GetFileCRC(string filePath, bool dryRunBuild)
{
if (dryRunBuild)
return "00000000"; //8位
else
return "00000000000000000000000000000000"; //32位
}
private string GetFileCRC(string filePath, bool standardBuild)
{
if (standardBuild)
return HashUtility.FileCRC32(filePath);
}
private long GetFileSize(string filePath, bool dryRunBuild)
{
if (dryRunBuild)
return 0;
else
return "00000000"; //8位
}
private long GetFileSize(string filePath, bool standardBuild)
{
if (standardBuild)
return FileUtility.GetFileSize(filePath);
else
return 0;
}
/// <summary>
@@ -9,7 +9,8 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
if (buildParameters.Parameters.DryRunBuild == false)
var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
CopyPatchFiles(buildParameters);
}
@@ -22,7 +23,7 @@ namespace YooAsset.Editor
{
int resourceVersion = buildParameters.Parameters.BuildVersion;
string packageDirectory = buildParameters.GetPackageDirectory();
UnityEngine.Debug.Log($"开始拷贝补丁文件到补丁包目录:{packageDirectory}");
BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageDirectory}");
// 拷贝Report文件
{
@@ -26,7 +26,9 @@ namespace YooAsset.Editor
buildReport.Summary.BuildTime = DateTime.Now.ToString();
buildReport.Summary.BuildSeconds = buildParameters.GetBuildingSeconds();
buildReport.Summary.BuildTarget = buildParameters.Parameters.BuildTarget;
buildReport.Summary.BuildMode = buildParameters.Parameters.BuildMode;
buildReport.Summary.BuildVersion = buildParameters.Parameters.BuildVersion;
buildReport.Summary.BuildinTags = buildParameters.Parameters.BuildinTags;
buildReport.Summary.EnableAddressable = buildParameters.Parameters.EnableAddressable;
buildReport.Summary.EnableAutoCollect = buildParameters.Parameters.EnableAutoCollect;
buildReport.Summary.AppendFileExtension = buildParameters.Parameters.AppendFileExtension;
@@ -36,9 +38,6 @@ namespace YooAsset.Editor
"null" : buildParameters.Parameters.EncryptionServices.GetType().FullName;
// 构建参数
buildReport.Summary.DryRunBuild = buildParameters.Parameters.DryRunBuild;
buildReport.Summary.ForceRebuild = buildParameters.Parameters.ForceRebuild;
buildReport.Summary.BuildinTags = buildParameters.Parameters.BuildinTags;
buildReport.Summary.CompressOption = buildParameters.Parameters.CompressOption;
buildReport.Summary.AppendHash = buildParameters.Parameters.AppendHash;
buildReport.Summary.DisableWriteTypeTree = buildParameters.Parameters.DisableWriteTypeTree;
@@ -91,7 +90,7 @@ namespace YooAsset.Editor
// 序列化文件
BuildReport.Serialize(filePath, buildReport);
UnityEngine.Debug.Log($"资源构建报告文件创建完成:{filePath}");
BuildRunner.Log($"资源构建报告文件创建完成:{filePath}");
}
/// <summary>
@@ -27,16 +27,17 @@ namespace YooAsset.Editor
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
if (buildParameters.Parameters.DryRunBuild)
var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
EncryptionContext encryptionContext = new EncryptionContext();
encryptionContext.EncryptList = new List<string>();
encryptionContext.EncryptList = EncryptFiles(buildParameters, buildMapContext);
context.SetContextObject(encryptionContext);
}
else
{
EncryptionContext encryptionContext = new EncryptionContext();
encryptionContext.EncryptList = EncryptFiles(buildParameters, buildMapContext);
encryptionContext.EncryptList = new List<string>();
context.SetContextObject(encryptionContext);
}
}
@@ -75,7 +76,7 @@ namespace YooAsset.Editor
{
byte[] bytes = encryptionServices.Encrypt(fileData);
File.WriteAllBytes(filePath, bytes);
UnityEngine.Debug.Log($"文件加密完成:{filePath}");
BuildRunner.Log($"文件加密完成:{filePath}");
}
}
@@ -14,7 +14,7 @@ namespace YooAsset.Editor
{
var buildMapContext = BuildMapCreater.CreateBuildMap();
context.SetContextObject(buildMapContext);
UnityEngine.Debug.Log("构建内容准备完毕!");
BuildRunner.Log("构建内容准备完毕!");
// 检测构建结果
CheckBuildMapContent(buildMapContext);
@@ -27,7 +27,8 @@ namespace YooAsset.Editor
throw new Exception("输出目录不能为空");
// 增量更新时候的必要检测
if (buildParameters.Parameters.DryRunBuild == false && buildParameters.Parameters.ForceRebuild == false)
var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode == EBuildMode.IncrementalBuild)
{
// 检测历史版本是否存在
if (AssetBundleBuilderHelper.HasAnyPackageVersion(buildParameters.Parameters.BuildTarget, buildParameters.Parameters.OutputRoot) == false)
@@ -50,20 +51,20 @@ namespace YooAsset.Editor
}
// 如果是强制重建
if (buildParameters.Parameters.DryRunBuild == false && buildParameters.Parameters.ForceRebuild)
if (buildMode == EBuildMode.ForceRebuild)
{
// 删除平台总目录
string platformDirectory = $"{buildParameters.Parameters.OutputRoot}/{buildParameters.Parameters.BuildTarget}";
if (EditorTools.DeleteDirectory(platformDirectory))
{
UnityEngine.Debug.Log($"删除平台总目录:{platformDirectory}");
BuildRunner.Log($"删除平台总目录:{platformDirectory}");
}
}
// 如果输出目录不存在
if (EditorTools.CreateDirectory(buildParameters.PipelineOutputDirectory))
{
UnityEngine.Debug.Log($"创建输出目录:{buildParameters.PipelineOutputDirectory}");
BuildRunner.Log($"创建输出目录:{buildParameters.PipelineOutputDirectory}");
}
}
}
@@ -14,11 +14,15 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
var unityManifestContext = context.GetContextObject<TaskBuilding.UnityManifestContext>();
// 快速构建模式下跳过验证
if (buildParametersContext.Parameters.BuildMode == EBuildMode.FastRunBuild)
return;
// 验证构建结果
if (buildParametersContext.Parameters.VerifyBuildingResult)
{
var unityManifestContext = context.GetContextObject<TaskBuilding.UnityManifestContext>();
VerifyingBuildingResult(context, unityManifestContext.UnityManifest);
}
}
@@ -80,7 +84,8 @@ namespace YooAsset.Editor
}
// 5. 验证Asset
if(buildParameters.Parameters.DryRunBuild == false)
var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
int progressValue = 0;
foreach (var buildedBundle in buildedBundles)
@@ -133,7 +138,7 @@ namespace YooAsset.Editor
}
// 卸载所有加载的Bundle
Debug.Log("构建结果验证成功!");
BuildRunner.Log("构建结果验证成功!");
}
/// <summary>
@@ -0,0 +1,29 @@
namespace YooAsset.Editor
{
/// <summary>
/// 资源包流水线的构建模式
/// </summary>
public enum EBuildMode
{
/// <summary>
/// 强制重建模式
/// </summary>
ForceRebuild,
/// <summary>
/// 增量构建模式
/// </summary>
IncrementalBuild,
/// <summary>
/// 快速构建模式
/// </summary>
FastRunBuild,
/// <summary>
/// 演练构建模式
/// </summary>
DryRunBuild,
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0b6f2523a865e454d8fa3f48a2852d5a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -96,6 +96,9 @@ namespace YooAsset.Editor
if (isRawAsset && CollectorType != ECollectorType.MainAssetCollector)
throw new Exception($"The raw file must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}");
if (string.IsNullOrEmpty(CollectPath))
throw new Exception($"The collect path is null or empty in grouper : {grouper.GrouperName}");
// 收集打包资源
if (AssetDatabase.IsValidFolder(CollectPath))
{
@@ -1,99 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using UnityEditor;
namespace YooAsset.Editor
{
/// <summary>
/// 编辑器下运行时支持
/// </summary>
public static class AssetBundleGrouperRuntimeSupport
{
private static readonly Dictionary<string, CollectAssetInfo> _locationDic = new Dictionary<string, CollectAssetInfo>(1000);
public static void InitEditorPlayMode(bool enableAddressable)
{
_locationDic.Clear();
if (enableAddressable)
{
var collectAssetList = AssetBundleGrouperSettingData.Setting.GetAllCollectAssets();
foreach (var collectAsset in collectAssetList)
{
if(collectAsset.CollectorType == ECollectorType.MainAssetCollector)
{
string address = collectAsset.Address;
if (_locationDic.ContainsKey(address))
throw new Exception($"The address is existed : {address} in grouper setting.");
else
_locationDic.Add(address, collectAsset);
}
}
}
else
{
var collectAssetList = AssetBundleGrouperSettingData.Setting.GetAllCollectAssets();
foreach (var collectAsset in collectAssetList)
{
if (collectAsset.CollectorType == ECollectorType.MainAssetCollector)
{
// 添加原始路径
// 注意:我们不允许原始路径存在重名
string assetPath = collectAsset.AssetPath;
if (_locationDic.ContainsKey(assetPath))
throw new Exception($"Asset path have existed : {assetPath}");
else
_locationDic.Add(assetPath, collectAsset);
// 添加去掉后缀名的路径
if (Path.HasExtension(assetPath))
{
string assetPathWithoutExtension = StringUtility.RemoveExtension(assetPath);
if (_locationDic.ContainsKey(assetPathWithoutExtension))
UnityEngine.Debug.LogWarning($"Asset path have existed : {assetPathWithoutExtension}");
else
_locationDic.Add(assetPathWithoutExtension, collectAsset);
}
}
}
}
}
public static string ConvertLocationToAssetPath(string location)
{
// 检测地址合法性
CheckLocation(location);
if (_locationDic.ContainsKey(location))
{
return _locationDic[location].AssetPath;
}
else
{
UnityEngine.Debug.LogWarning($"Not found asset in grouper setting : {location}");
return string.Empty;
}
}
private static void CheckLocation(string location)
{
if (string.IsNullOrEmpty(location))
{
UnityEngine.Debug.LogError("location param is null or empty!");
}
else
{
// 检查路径末尾是否有空格
int index = location.LastIndexOf(" ");
if (index != -1)
{
if (location.Length == index + 1)
UnityEngine.Debug.LogWarning($"Found blank character in location : \"{location}\"");
}
if (location.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
UnityEngine.Debug.LogWarning($"Found illegal character in location : \"{location}\"");
}
}
}
}
@@ -310,7 +310,7 @@ namespace YooAsset.Editor
{
var objectField = new ObjectField();
objectField.name = "ObjectField1";
objectField.label = "Collecter";
objectField.label = "Collector";
objectField.objectType = typeof(UnityEngine.Object);
objectField.style.unityTextAlign = TextAnchor.MiddleLeft;
objectField.style.flexGrow = 1f;
@@ -66,7 +66,10 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper("构建时间", buildReport.Summary.BuildTime));
_items.Add(new ItemWrapper("构建耗时", $"{buildReport.Summary.BuildSeconds}秒"));
_items.Add(new ItemWrapper("构建平台", $"{buildReport.Summary.BuildTarget}"));
_items.Add(new ItemWrapper("构建模式", $"{buildReport.Summary.BuildMode}"));
_items.Add(new ItemWrapper("构建版本", $"{buildReport.Summary.BuildVersion}"));
_items.Add(new ItemWrapper("内置资源标签", $"{buildReport.Summary.BuildinTags}"));
_items.Add(new ItemWrapper("启用可寻址资源定位", $"{buildReport.Summary.EnableAddressable}"));
_items.Add(new ItemWrapper("启用自动分包机制", $"{buildReport.Summary.EnableAutoCollect}"));
_items.Add(new ItemWrapper("追加文件扩展名", $"{buildReport.Summary.AppendFileExtension}"));
@@ -76,9 +79,6 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper(string.Empty, 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("BuildinTags", $"{buildReport.Summary.BuildinTags}"));
_items.Add(new ItemWrapper("CompressOption", $"{buildReport.Summary.CompressOption}"));
_items.Add(new ItemWrapper("AppendHash", $"{buildReport.Summary.AppendHash}"));
_items.Add(new ItemWrapper("DisableWriteTypeTree", $"{buildReport.Summary.DisableWriteTypeTree}"));