04-04-源码-构建管线与任务系统

源码-构建管线分析

篇章 :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 构建管线的架构

markdown 复制代码
构建管线架构
├── IBuildPipeline(构建管线接口)
│   ├── 内置构建管线实现
│   ├── SBP 构建管线实现
│   └── 自定义构建管线实现
├── BuildTask(构建任务)
│   ├── BuildTaskCreateManifest
│   ├── BuildTaskBuildAssetBundle
│   └── BuildTaskGenerateReport
└── BuildContext(构建上下文)
    ├── BuildParameters
    ├── BuildMap
    └── BuildResult

IBuildPipeline 详解:

IBuildPipeline 是构建管线的接口,定义了构建管线的基本行为。

BuildTask 详解:

BuildTask 是构建任务的抽象,每个任务负责一个具体的构建操作。

BuildContext 详解:

BuildContext 是构建上下文,包含了构建过程中的所有状态。


三、内置构建管线

3.1 内置构建管线概述

内置构建管线是 YooAsset 默认提供的构建管线,基于 Unity 内置 AssetBundle 构建 API:

优势:

  • 简单:实现简单,易于理解
  • 稳定:经过 Unity 官方验证
  • 兼容性好:兼容所有 Unity 支持的平台

劣势:

  • 性能有限:不支持并行构建
  • 自定义能力有限:受限于 Unity 内置 API

3.2 内置构建管线的源码

csharp 复制代码
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 构建选项配置

构建选项决定了构建的行为:

csharp 复制代码
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 构建管线概述

SBP(Scriptable Build Pipeline)是 Unity 提供的高级构建管线:

优势:

  • 性能强:支持并行构建
  • 自定义能力强:支持自定义构建任务
  • 支持增量构建:原生支持增量构建

劣势:

  • 需要安装 SBP 包
  • 配置相对复杂

4.2 SBP 构建管线的源码

csharp 复制代码
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 的任务链是构建的核心:

csharp 复制代码
private List<IBuildTask> CreateBuildTasks(BuildContext context)
{
    var tasks = new List<IBuildTask>();
    
    // 计算资产依赖
    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 任务接口

csharp 复制代码
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 任务依赖管理

csharp 复制代码
public class BuildTaskManager
{
    private List<IBuildTask> _tasks = new List<IBuildTask>();
    
    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 增量构建的实现

csharp 复制代码
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 List<BuildBundleInfo> DiffBuildMap(BuildMap newMap, BuildMap oldMap)
    {
        var changed = new List<BuildBundleInfo>();
        
        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) 下一篇 :清单与报告

相关推荐
应用市场18 小时前
不用一张图片的像素小游戏:小人是字符串,房间是矩形,平衡靠两千个假玩家
android·kotlin·游戏开发
新的瑞拉公主1 天前
Cocos plist 粒子一键导入 Unity:Editor 工具实现与参数映射
unity·游戏开发·cocos2d-x·粒子系统·editor工具
SmalBox1 天前
04-03-源码-构建映射与依赖分析(BuildMap)
unity3d·游戏开发
甲维斯2 天前
我把“赶 Deadline”和AI做成了一款游戏
人工智能·游戏开发
SmalBox2 天前
04-02-源码-资源收集器(AssetBundleCollector)
unity3d·游戏开发
字节暗面2 天前
客户端上报不可信:游戏服务端数据校验与对局重演设计
c#·游戏开发·服务端校验·反作弊
字节暗面2 天前
游戏服务端如何校验客户端上报数据?四层校验思路详解
游戏开发
甲维斯3 天前
我用AI做了一款「三国吃鸡」,开局孔明灯,落地青龙刀 !
人工智能·游戏·游戏开发
SmalBox3 天前
04-01-源码-编辑器总览
unity3d·游戏开发