/// <summary> /// 开始构建 /// </summary> public void Run(BuildParameters buildParameters) { // 清空旧数据 _buildContext.ClearAllContext(); // 构建参数 var buildParametersContext = new BuildParametersContext(buildParameters.OutputRoot, buildParameters.BuildTarget, buildParameters.BuildVersion); _buildContext.SetContextObject(buildParametersContext); // 构建选项 var buildOptionsContext = new BuildOptionsContext(); buildOptionsContext.CompressOption = buildParameters.CompressOption; buildOptionsContext.IsForceRebuild = buildParameters.IsForceRebuild; buildOptionsContext.IsAppendHash = buildParameters.IsAppendHash; buildOptionsContext.IsDisableWriteTypeTree = buildParameters.IsDisableWriteTypeTree; buildOptionsContext.IsIgnoreTypeTreeChanges = buildParameters.IsIgnoreTypeTreeChanges; _buildContext.SetContextObject(buildOptionsContext); List <IBuildTask> pipeline = new List <IBuildTask> { new TaskPrepare(), //前期准备工作 new TaskGetBuildMap(), //获取构建列表 new TaskBuilding(), //开始构建 new TaskEncryption(), //加密资源文件 new TaskCheckCycle(), //检测循环依赖 new TaskCreatePatchManifest(), //创建补丁文件 new TaskCreateReadme(), //创建说明文件 new TaskCopyUpdateFiles() //复制更新文件 }; BuildRunner.Run(pipeline, _buildContext); BuildLogger.Log($"构建完成!"); }
private void CopyBuildinFilesToStreaming(string pipelineOutputDirectory) { // 加载补丁清单 PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory); // 拷贝文件列表 foreach (var patchBundle in patchManifest.BundleList) { if (patchBundle.IsBuildin == false) { continue; } string sourcePath = $"{pipelineOutputDirectory}/{patchBundle.BundleName}"; string destPath = $"{Application.dataPath}/StreamingAssets/{patchBundle.Hash}"; BuildLogger.Log($"拷贝内置文件到流目录:{patchBundle.BundleName}"); EditorTools.CopyFile(sourcePath, destPath, true); } // 拷贝核心文件 { string sourcePath = $"{pipelineOutputDirectory}/{PatchDefine.PatchManifestFileName}"; string destPath = $"{Application.dataPath}/StreamingAssets/{PatchDefine.PatchManifestFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); } // 刷新目录 AssetDatabase.Refresh(); }
void IBuildTask.Run(BuildContext context) { var buildParameters = context.GetContextObject <AssetBundleBuilder.BuildParametersContext>(); var buildOptions = context.GetContextObject <AssetBundleBuilder.BuildOptionsContext>(); // 检测构建平台是否合法 if (buildParameters.BuildTarget == BuildTarget.NoTarget) { throw new Exception("请选择目标平台"); } // 检测构建版本是否合法 if (EditorTools.IsNumber(buildParameters.BuildVersion.ToString()) == false) { throw new Exception($"版本号格式非法:{buildParameters.BuildVersion}"); } if (buildParameters.BuildVersion < 0) { throw new Exception("请先设置版本号"); } // 检测输出目录是否为空 if (string.IsNullOrEmpty(buildParameters.OutputDirectory)) { throw new Exception("输出目录不能为空"); } // 检测补丁包是否已经存在 string packageDirectory = buildParameters.GetPackageDirectory(); if (Directory.Exists(packageDirectory)) { throw new Exception($"补丁包已经存在:{packageDirectory}"); } // 检测资源收集配置文件 if (AssetBundleCollectorSettingData.GetCollecterCount() == 0) { throw new Exception("配置的资源收集路径为空!"); } // 如果是强制重建 if (buildOptions.IsForceRebuild) { // 删除平台总目录 string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.BuildTarget}"; if (EditorTools.DeleteDirectory(platformDirectory)) { BuildLogger.Log($"删除平台总目录:{platformDirectory}"); } } // 如果输出目录不存在 if (EditorTools.CreateDirectory(buildParameters.OutputDirectory)) { BuildLogger.Log($"创建输出目录:{buildParameters.OutputDirectory}"); } }
/// <summary> /// 复制更新文件到补丁包目录 /// </summary> private void CopyUpdateFiles(AssetBundleBuilder.BuildParametersContext buildParameters) { string packageDirectory = buildParameters.GetPackageDirectory(); BuildLogger.Log($"开始复制更新文件到补丁包目录:{packageDirectory}"); // 复制Readme文件 { string sourcePath = $"{buildParameters.OutputDirectory}/{PatchDefine.ReadmeFileName}"; string destPath = $"{packageDirectory}/{PatchDefine.ReadmeFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); BuildLogger.Log($"复制Readme文件到:{destPath}"); } // 复制PatchManifest文件 { string sourcePath = $"{buildParameters.OutputDirectory}/{PatchDefine.PatchManifestFileName}"; string destPath = $"{packageDirectory}/{PatchDefine.PatchManifestFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); BuildLogger.Log($"复制PatchManifest文件到:{destPath}"); } // 复制UnityManifest文件 { string sourcePath = $"{buildParameters.OutputDirectory}/{PatchDefine.UnityManifestFileName}"; string destPath = $"{packageDirectory}/{PatchDefine.UnityManifestFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); BuildLogger.Log($"复制UnityManifest文件到:{destPath}"); } // 复制Manifest文件 { string sourcePath = $"{buildParameters.OutputDirectory}/{PatchDefine.UnityManifestFileName}.manifest"; string destPath = $"{packageDirectory}/{PatchDefine.UnityManifestFileName}.manifest"; EditorTools.CopyFile(sourcePath, destPath, true); } // 复制所有更新文件 int progressBarCount = 0; PatchManifest patchFile = AssetBundleBuilder.LoadPatchManifestFile(buildParameters); int patchFileTotalCount = patchFile.BundleList.Count; foreach (var patchBundle in patchFile.BundleList) { if (patchBundle.Version == buildParameters.BuildVersion) { string sourcePath = $"{buildParameters.OutputDirectory}/{patchBundle.BundleName}"; string destPath = $"{packageDirectory}/{patchBundle.Hash}"; EditorTools.CopyFile(sourcePath, destPath, true); BuildLogger.Log($"复制更新文件到补丁包:{sourcePath}"); progressBarCount++; EditorUtility.DisplayProgressBar("进度", $"拷贝更新文件 : {sourcePath}", (float)progressBarCount / patchFileTotalCount); } } EditorUtility.ClearProgressBar(); }
/// <summary> /// 拷贝补丁文件到补丁包目录 /// </summary> private void CopyPatchFiles(AssetBundleBuilder.BuildParametersContext buildParameters) { string packageDirectory = buildParameters.GetPackageDirectory(); BuildLogger.Log($"开始拷贝补丁文件到补丁包目录:{packageDirectory}"); // 拷贝Readme文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{PatchDefine.ReadmeFileName}"; string destPath = $"{packageDirectory}/{PatchDefine.ReadmeFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); BuildLogger.Log($"拷贝Readme文件到:{destPath}"); } // 拷贝PatchManifest文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{PatchDefine.PatchManifestFileName}"; string destPath = $"{packageDirectory}/{PatchDefine.PatchManifestFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); BuildLogger.Log($"拷贝PatchManifest文件到:{destPath}"); } // 拷贝UnityManifest序列化文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{PatchDefine.UnityManifestFileName}"; string destPath = $"{packageDirectory}/{PatchDefine.UnityManifestFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); BuildLogger.Log($"拷贝UnityManifest文件到:{destPath}"); } // 拷贝UnityManifest文本文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{PatchDefine.UnityManifestFileName}.manifest"; string destPath = $"{packageDirectory}/{PatchDefine.UnityManifestFileName}.manifest"; EditorTools.CopyFile(sourcePath, destPath, true); } // 拷贝所有补丁文件 // 注意:拷贝的补丁文件都是需要玩家热更新的文件 int progressValue = 0; PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory); int patchFileTotalCount = patchManifest.BundleList.Count; foreach (var patchBundle in patchManifest.BundleList) { if (patchBundle.Version == buildParameters.Parameters.BuildVersion) { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{patchBundle.BundleName}"; string destPath = $"{packageDirectory}/{patchBundle.Hash}"; EditorTools.CopyFile(sourcePath, destPath, true); BuildLogger.Log($"拷贝补丁文件到补丁包:{patchBundle.BundleName}"); EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount); } } EditorTools.ClearProgressBar(); }
private void InitAssetEncrypter() { var types = AssemblyUtility.GetAssignableTypes(AssemblyUtility.UnityDefaultAssemblyEditorName, typeof(IAssetEncrypter)); if (types.Count == 0) { return; } if (types.Count != 1) { throw new Exception($"Found more {nameof(IAssetEncrypter)} types. We only support one."); } BuildLogger.Log($"创建加密类 : {types[0].FullName}"); _encrypter = (IAssetEncrypter)Activator.CreateInstance(types[0]); }
/// <summary> /// 创建补丁清单文件到输出目录 /// </summary> private void CreatePatchManifestFile(AssetBundleBuilder.BuildParametersContext buildParameters, TaskGetBuildMap.BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext, AssetBundleManifest unityManifest) { // 创建新补丁清单 PatchManifest patchManifest = new PatchManifest(); patchManifest.ResourceVersion = buildParameters.BuildVersion; patchManifest.BundleList = GetAllPatchBundle(buildParameters, buildMapContext, encryptionContext, unityManifest); patchManifest.VariantList = GetAllPatchVariant(unityManifest); // 创建新文件 string filePath = $"{buildParameters.OutputDirectory}/{PatchDefine.PatchManifestFileName}"; BuildLogger.Log($"创建补丁清单文件:{filePath}"); PatchManifest.Serialize(filePath, patchManifest); }
void IBuildTask.Run(BuildContext context) { List <AssetInfo> allAssets = GetBuildAssets(); if (allAssets.Count == 0) { throw new Exception("构建的资源列表不能为空"); } BuildLogger.Log($"构建的资源列表里总共有{allAssets.Count}个资源"); BuildMapContext buildMapContext = new BuildMapContext(); foreach (var assetInfo in allAssets) { buildMapContext.PackAsset(assetInfo); } context.SetContextObject(buildMapContext); }
void IBuildTask.Run(BuildContext context) { var buildParameters = context.GetContextObject <AssetBundleBuilder.BuildParametersContext>(); var buildMap = context.GetContextObject <TaskGetBuildMap.BuildMapContext>(); BuildLogger.Log($"开始构建......"); BuildAssetBundleOptions opt = buildParameters.GetPiplineBuildOptions(); AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(buildParameters.PipelineOutputDirectory, buildMap.GetPipelineBuilds(), opt, buildParameters.Parameters.BuildTarget); if (manifest == null) { throw new Exception("构建过程中发生错误!"); } UnityManifestContext unityManifestContext = new UnityManifestContext(); unityManifestContext.Manifest = manifest; context.SetContextObject(unityManifestContext); }
private List <string> EncryptFiles(AssetBundleManifest unityManifest, AssetBundleBuilder.BuildParametersContext buildParameters) { // 加密资源列表 List <string> encryptList = new List <string>(); // 如果没有设置加密类 if (_encrypter == null) { return(encryptList); } BuildLogger.Log($"开始加密资源文件"); int progressBarCount = 0; string[] allAssetBundles = unityManifest.GetAllAssetBundles(); foreach (string assetName in allAssetBundles) { string filePath = $"{buildParameters.OutputDirectory}/{assetName}"; if (_encrypter.Check(filePath)) { encryptList.Add(assetName); // 通过判断文件合法性,规避重复加密一个文件 byte[] fileData = File.ReadAllBytes(filePath); if (EditorTools.CheckBundleFileValid(fileData)) { byte[] bytes = _encrypter.Encrypt(fileData); File.WriteAllBytes(filePath, bytes); BuildLogger.Log($"文件加密完成:{filePath}"); } } // 进度条 progressBarCount++; EditorUtility.DisplayProgressBar("进度", $"加密资源包:{progressBarCount}/{allAssetBundles.Length}", (float)progressBarCount / allAssetBundles.Length); } EditorUtility.ClearProgressBar(); return(encryptList); }
/// <summary> /// 加密文件 /// </summary> private List <string> EncryptFiles(IAssetEncrypter encrypter, AssetBundleManifest unityManifest, AssetBundleBuilder.BuildParametersContext buildParameters) { // 加密资源列表 List <string> encryptList = new List <string>(); // 如果没有设置加密类 if (encrypter == null) { return(encryptList); } BuildLogger.Log($"开始加密资源文件"); string[] allAssetBundles = unityManifest.GetAllAssetBundles(); int progressValue = 0; foreach (string bundleName in allAssetBundles) { string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleName}"; if (encrypter.Check(filePath)) { encryptList.Add(bundleName); // 注意:通过判断文件合法性,规避重复加密一个文件 byte[] fileData = File.ReadAllBytes(filePath); if (EditorTools.CheckBundleFileValid(fileData)) { byte[] bytes = encrypter.Encrypt(fileData); File.WriteAllBytes(filePath, bytes); BuildLogger.Log($"文件加密完成:{filePath}"); } } // 进度条 EditorTools.DisplayProgressBar("加密资源包", ++progressValue, allAssetBundles.Length); } EditorTools.ClearProgressBar(); return(encryptList); }
/// <summary> /// 开始构建 /// </summary> public bool Run(BuildParameters buildParameters) { // 清空旧数据 _buildContext.ClearAllContext(); // 构建参数 var buildParametersContext = new BuildParametersContext(buildParameters); _buildContext.SetContextObject(buildParametersContext); // 执行构建流程 List <IBuildTask> pipeline = new List <IBuildTask> { new TaskPrepare(), //前期准备工作 new TaskGetBuildMap(), //获取构建列表 new TaskBuilding(), //开始执行构建 new TaskCheckCycle(), //检测循环依赖 new TaskEncryption(), //加密资源文件 new TaskCreatePatchManifest(), //创建清单文件 new TaskCreateReadme(), //创建说明文件 new TaskCreatePatchPackage(), //制作补丁包 new TaskCopyBuildinFiles(), //拷贝内置文件 }; bool succeed = BuildRunner.Run(pipeline, _buildContext); if (succeed) { BuildLogger.Log($"构建成功!"); } else { BuildLogger.Warning($"构建失败!"); } return(succeed); }
/// <summary> /// 创建Readme文件到输出目录 /// </summary> private void CreateReadmeFile(AssetBundleBuilder.BuildParametersContext buildParameters, AssetBundleBuilder.BuildOptionsContext buildOptions, AssetBundleManifest unityManifest) { string[] allAssetBundles = unityManifest.GetAllAssetBundles(); // 删除旧文件 string filePath = $"{buildParameters.OutputDirectory}/{PatchDefine.ReadmeFileName}"; if (File.Exists(filePath)) { File.Delete(filePath); } BuildLogger.Log($"创建说明文件:{filePath}"); StringBuilder content = new StringBuilder(); AppendData(content, $"构建平台:{buildParameters.BuildTarget}"); AppendData(content, $"构建版本:{buildParameters.BuildVersion}"); AppendData(content, $"构建时间:{DateTime.Now}"); AppendData(content, ""); AppendData(content, $"--着色器--"); AppendData(content, $"IsCollectAllShaders:{AssetBundleCollectorSettingData.Setting.IsCollectAllShaders}"); AppendData(content, $"ShadersBundleName:{AssetBundleCollectorSettingData.Setting.ShadersBundleName}"); AppendData(content, ""); AppendData(content, $"--配置信息--"); for (int i = 0; i < AssetBundleCollectorSettingData.Setting.Collectors.Count; i++) { AssetBundleCollectorSetting.Collector wrapper = AssetBundleCollectorSettingData.Setting.Collectors[i]; AppendData(content, $"Directory : {wrapper.CollectDirectory} | {wrapper.PackRuleClassName} | {wrapper.FilterRuleClassName}"); } AppendData(content, ""); AppendData(content, $"--构建参数--"); AppendData(content, $"CompressOption:{buildOptions.CompressOption}"); AppendData(content, $"IsForceRebuild:{buildOptions.IsForceRebuild}"); AppendData(content, $"IsDisableWriteTypeTree:{buildOptions.IsDisableWriteTypeTree}"); AppendData(content, $"IsIgnoreTypeTreeChanges:{buildOptions.IsIgnoreTypeTreeChanges}"); AppendData(content, ""); AppendData(content, $"--构建清单--"); for (int i = 0; i < allAssetBundles.Length; i++) { AppendData(content, allAssetBundles[i]); } PatchManifest patchFile = AssetBundleBuilder.LoadPatchManifestFile(buildParameters); { AppendData(content, ""); AppendData(content, $"--更新清单--"); foreach (var patchBundle in patchFile.BundleList) { if (patchBundle.Version == buildParameters.BuildVersion) { AppendData(content, patchBundle.BundleName); } } AppendData(content, ""); AppendData(content, $"--变体列表--"); foreach (var variant in patchFile.VariantList) { AppendData(content, variant.ToString()); } } // 创建新文件 File.WriteAllText(filePath, content.ToString(), Encoding.UTF8); }
void IBuildTask.Run(BuildContext context) { var buildParameters = context.GetContextObject <AssetBundleBuilder.BuildParametersContext>(); // 检测构建平台是否合法 if (buildParameters.Parameters.BuildTarget == BuildTarget.NoTarget) { throw new Exception("请选择目标平台"); } // 检测构建版本是否合法 if (buildParameters.Parameters.BuildVersion <= 0) { throw new Exception("请先设置版本号"); } // 检测输出目录是否为空 if (string.IsNullOrEmpty(buildParameters.PipelineOutputDirectory)) { throw new Exception("输出目录不能为空"); } // 检测资源收集配置文件 if (AssetBundleCollectorSettingData.GetCollecterCount() == 0) { throw new Exception("配置的资源收集路径为空"); } // 增量更新时候的必要检测 if (buildParameters.Parameters.IsForceRebuild == false) { // 检测历史版本是否存在 if (AssetBundleBuilderHelper.HasAnyPackageVersion(buildParameters.Parameters.BuildTarget, buildParameters.Parameters.OutputRoot) == false) { throw new Exception("没有发现任何历史版本,请尝试强制重建"); } // 检测构建版本是否合法 int maxPackageVersion = AssetBundleBuilderHelper.GetMaxPackageVersion(buildParameters.Parameters.BuildTarget, buildParameters.Parameters.OutputRoot); if (buildParameters.Parameters.BuildVersion <= maxPackageVersion) { throw new Exception("构建版本不能小于历史版本"); } // 检测补丁包是否已经存在 string packageDirectory = buildParameters.GetPackageDirectory(); if (Directory.Exists(packageDirectory)) { throw new Exception($"补丁包已经存在:{packageDirectory}"); } // 检测内置资源标记是否一致 PatchManifest oldPatchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory); if (buildParameters.Parameters.BuildinTags != oldPatchManifest.BuildinTags) { throw new Exception($"增量更新时内置资源标记必须一致:{buildParameters.Parameters.BuildinTags} != {oldPatchManifest.BuildinTags}"); } } // 如果是强制重建 if (buildParameters.Parameters.IsForceRebuild) { // 删除平台总目录 string platformDirectory = $"{buildParameters.Parameters.OutputRoot}/{buildParameters.Parameters.BuildTarget}"; if (EditorTools.DeleteDirectory(platformDirectory)) { BuildLogger.Log($"删除平台总目录:{platformDirectory}"); } } // 如果输出目录不存在 if (EditorTools.CreateDirectory(buildParameters.PipelineOutputDirectory)) { BuildLogger.Log($"创建输出目录:{buildParameters.PipelineOutputDirectory}"); } }