
源码-构建管线分析篇章04-源码深度-编辑器模块阅读时间约 30 分钟前置知识了解 BuildMap 模块一、引言本章将深入解析 YooAsset 构建管线Build Pipeline的源码实现。构建管线是 YooAsset 编辑器端的核心组件负责执行实际的资源打包操作。YooAsset 支持多种构建管线包括内置构建管线和 SBP 构建管线。构建管线是 YooAsset 灵活性的重要体现开发者可以根据需要选择合适的构建管线。本章将从源码层面深入解析构建管线的设计和实现。二、构建管线概述2.1 构建管线的概念构建管线是 YooAsset 编辑器端的核心组件定义构建管线是一组按照特定顺序执行的构建任务集合。每个任务负责一个具体的构建操作。作用执行资源打包处理资源依赖生成 Bundle 文件生成构建报告特点可扩展支持自定义构建管线可配置支持多种配置选项可观察支持进度跟踪和日志输出2.2 构建管线的类型YooAsset 支持以下构建管线内置构建管线基于 Unity 内置 AssetBundle 构建 API 的构建管线。简单、稳定。SBP 构建管线基于 Unity Scriptable Build Pipeline 的构建管线。功能强大、性能优秀。编辑器模拟构建管线在编辑器中模拟构建过程不实际生成 Bundle 文件。用于开发阶段。自定义构建管线开发者可以自定义构建管线实现特定的构建逻辑。2.3 构建管线的架构构建管线架构 ├── IBuildPipeline构建管线接口 │ ├── 内置构建管线实现 │ ├── SBP 构建管线实现 │ └── 自定义构建管线实现 ├── BuildTask构建任务 │ ├── BuildTaskCreateManifest │ ├── BuildTaskBuildAssetBundle │ └── BuildTaskGenerateReport └── BuildContext构建上下文 ├── BuildParameters ├── BuildMap └── BuildResultIBuildPipeline 详解IBuildPipeline 是构建管线的接口定义了构建管线的基本行为。BuildTask 详解BuildTask 是构建任务的抽象每个任务负责一个具体的构建操作。BuildContext 详解BuildContext 是构建上下文包含了构建过程中的所有状态。三、内置构建管线3.1 内置构建管线概述内置构建管线是 YooAsset 默认提供的构建管线基于 Unity 内置 AssetBundle 构建 API优势简单实现简单易于理解稳定经过 Unity 官方验证兼容性好兼容所有 Unity 支持的平台劣势性能有限不支持并行构建自定义能力有限受限于 Unity 内置 API3.2 内置构建管线的源码public class BuiltinBuildPipeline : IBuildPipeline { public BuildResult Run(BuildContext context) { // 1. 准备构建参数 BuildAssetBundleOptions options GetBuildOptions(context); // 2. 准备资源路径和资源名 var locations PrepareLocations(context.BuildMap); // 3. 调用 Unity API 执行构建 AssetBundleManifest manifest BuildPipeline.BuildAssetBundles( context.OutputPath, locations, options, context.BuildTarget ); // 4. 处理构建结果 return ProcessResult(manifest, context); } }BuildPipeline.BuildAssetBundles 详解BuildPipeline.BuildAssetBundles 是 Unity 提供的 AssetBundle 构建 API。参数详解context.OutputPath构建输出路径locations资源位置数组options构建选项context.BuildTarget构建目标平台3.3 构建选项配置构建选项决定了构建的行为private BuildAssetBundleOptions GetBuildOptions(BuildContext context) { BuildAssetBundleOptions options BuildAssetBundleOptions.None; if (context.Parameters.CompressOption ECompressOption.LZMA) { options | BuildAssetBundleOptions.ChunkBasedCompression; } else if (context.Parameters.CompressOption ECompressOption.LZ4) { options | BuildAssetBundleOptions.ChunkBasedCompression; } if (context.Parameters.DeterministicAssetBundle) { options | BuildAssetBundleOptions.DeterministicAssetBundle; } return options; }压缩选项详解LZMA高压缩率适合网络传输LZ4低压缩率适合运行时加载None不压缩速度最快确定性打包详解DeterministicAssetBundle 确保 Bundle 的 Hash 是确定的便于版本管理。3.4 内置构建管线的优缺点优点简单易用稳定性高兼容性好缺点性能有限自定义能力有限不支持增量构建四、SBP 构建管线4.1 SBP 构建管线概述SBPScriptable Build Pipeline是 Unity 提供的高级构建管线优势性能强支持并行构建自定义能力强支持自定义构建任务支持增量构建原生支持增量构建劣势需要安装 SBP 包配置相对复杂4.2 SBP 构建管线的源码public class SBPBuildPipeline : IBuildPipeline { public BuildResult Run(BuildContext context) { // 1. 创建 SBP 构建参数 var buildParameters new BundleBuildParameters( context.BuildTarget, context.BuildTargetGroup, context.OutputPath ); // 2. 创建 SBP 构建内容 var content new BundleBuildContent(contentEntries); // 3. 准备构建任务 var tasks CreateBuildTasks(context); // 4. 执行 SBP 构建 IBundleBuildResults results BuildPipeline.BuildAssetBundles(buildParameters, content, tasks); // 5. 处理构建结果 return ProcessResult(results, context); } }SBP 构建参数详解BundleBuildParameters 是 SBP 的构建参数包含了构建目标、输出路径等。SBP 构建内容详解BundleBuildContent 描述了 SBP 的构建内容包括所有资源的位置和依赖。SBP 构建任务详解SBP 的构建任务是一个任务链每个任务负责一个具体的构建操作。4.3 SBP 任务链SBP 的任务链是构建的核心private ListIBuildTask CreateBuildTasks(BuildContext context) { var tasks new ListIBuildTask(); // 计算资产依赖 if (context.Parameters.ComputeAssetDependency) { tasks.Add(new CalculateAssetDependencyTask()); } // 生成本地 Bundle tasks.Add(new GenerateBundlePackingTask()); // 生成本地资源 tasks.Add(new GenerateBundleBuildTask()); // 写入 Bundle 文件 tasks.Add(new WriteSerializedFilesTask()); // 打包 tasks.Add(new ArchiveOutputFolderTask()); return tasks; }CalculateAssetDependencyTask 详解计算资源依赖构建依赖图。GenerateBundlePackingTask 详解生成本地 Bundle 的打包方案。GenerateBundleBuildTask 详解生成本地资源的位置。WriteSerializedFilesTask 详解写入序列化文件到本地。ArchiveOutputFolderTask 详解打包到输出文件夹。4.4 SBP 构建管线的优缺点优点性能强自定义能力强支持增量构建缺点需要安装 SBP 包配置复杂学习曲线较陡五、构建任务系统5.1 任务系统的设计YooAsset 的构建采用了任务系统设计任务节点每个构建步骤是一个任务节点。任务依赖任务节点之间可以定义依赖关系。任务执行任务执行器会按依赖顺序执行任务。任务回调任务完成时触发回调通知。5.2 任务接口public interface IBuildTask { EBuildTaskStage Stage { get; } void Run(BuildContext context); void OnComplete(BuildContext context); EBuildTaskStatus Status { get; } }Stage 详解Stage 表示任务的执行阶段用于控制任务的执行顺序。Run 详解Run 是任务的主要执行方法。OnComplete 详解OnComplete 是任务完成后的回调方法。Status 详解Status 表示任务的执行状态。5.3 任务依赖管理public class BuildTaskManager { private ListIBuildTask _tasks new ListIBuildTask(); public void AddTask(IBuildTask task) { _tasks.Add(task); } public void Run() { // 按阶段执行任务 var groupedTasks _tasks.GroupBy(t t.Stage).OrderBy(g g.Key); foreach (var group in groupedTasks) { // 同一阶段的任务可以并行执行 Parallel.ForEach(group, task { task.Run(null); task.OnComplete(null); }); } } }阶段执行详解任务按阶段分组执行。同一阶段的任务可以并行执行不同阶段的任务串行执行。并行执行详解使用 Parallel.ForEach 实现任务的并行执行。六、增量构建实现6.1 增量构建的概念增量构建只重新打包发生变化的资源优势大幅减少构建时间减少资源冗余提高开发效率挑战准确检测资源变化正确处理依赖关系保证构建结果正确6.2 增量构建的实现public class IncrementalBuilder { public BuildResult BuildIncremental(BuildMap newMap, BuildMap oldMap, BuildContext context) { // 1. 对比 BuildMap找出变化的 Bundle var changedBundles DiffBuildMap(newMap, oldMap); // 2. 只重新打包变化的 Bundle var newContext context.Clone(); newContext.BuildMap CreatePartialBuildMap(changedBundles, newMap); // 3. 执行构建 return context.Pipeline.Run(newContext); } private ListBuildBundleInfo DiffBuildMap(BuildMap newMap, BuildMap oldMap) { var changed new ListBuildBundleInfo(); foreach (var newBundle in newMap.Bundles) { var oldBundle oldMap.Bundles.FirstOrDefault(b b.BundleName newBundle.BundleName); if (oldBundle null || !IsBundleEqual(oldBundle, newBundle)) { changed.Add(newBundle); } } return changed; } }BuildMap 对比详解对比前后两个 BuildMap找出变化的 Bundle。部分构建详解只构建变化的 Bundle未变化的 Bundle 复用上次的构建结果。6.3 增量构建的局限性增量构建存在以下局限性配置变化时需要全量构建依赖关系变化时需要重新打包相关 Bundle不能完全替代全量构建七、总结本章深入解析了 YooAsset 构建管线Build Pipeline的源码实现包括构建管线概述构建管线的概念、类型、架构内置构建管线基于 Unity 内置 API 的构建管线SBP 构建管线基于 Unity SBP 的构建管线构建任务系统任务的设计、接口、依赖管理增量构建增量构建的概念、实现、局限性构建管线是 YooAsset 灵活性的重要体现通过深入理解构建管线的实现开发者可以根据自己的需求选择和定制构建管线。上一篇构建映射与依赖分析BuildMap下一篇清单与报告