04-05-YooAsset源码-Unity清单生成与构建报告

📅 2026/7/13 15:40:47 👁️ 阅读次数 📝 编程学习
04-05-YooAsset源码-Unity清单生成与构建报告

源码-清单与报告

篇章:04-源码深度-编辑器模块
阅读时间:约 25 分钟
前置知识:了解构建管线分析


一、引言

本章将深入解析 YooAsset 清单(Manifest)与报告(Report)的源码实现。PackageManifest 是 YooAsset Editor 端和 Runtime 端之间的数据桥梁,记录了所有 Bundle 的信息;BuildReport 记录了构建的详细信息,是开发者分析构建结果的重要依据。

本章将从源码层面深入解析 PackageManifest 和 BuildReport 的设计与实现。


二、PackageManifest 概述

2.1 PackageManifest 的作用

PackageManifest 是 YooAsset 的资源清单,在整个资源管理流程中起到核心作用:

数据桥梁

PackageManifest 是 Editor 端和 Runtime 端之间的数据桥梁。Editor 端生成 PackageManifest,Runtime 端读取 PackageManifest。

资源定位

PackageManifest 记录了所有资源地址到 Bundle 的映射关系,运行时通过 PackageManifest 定位资源。

依赖管理

PackageManifest 记录了 Bundle 之间的依赖关系,运行时可以根据依赖关系加载 Bundle。

版本管理

PackageManifest 包含版本信息,支持热更新时的版本比较。

加密信息

PackageManifest 包含加密信息,运行时根据加密信息解密资源。

2.2 PackageManifest 的核心字段

[Serializable] public class PackageManifest { // 包名 public string PackageName; // 包版本 public string PackageVersion; // 包描述 public string PackageDesc; // 资源版本(用于热更新) public string ResourceVersion; // 构建时间 public long BuildTime; // 构建引擎版本 public string BuildEngineVersion; // 资源清单 public AssetList AssetList = new AssetList(); // Bundle 列表 public BundleList BundleList = new BundleList(); } [Serializable] public class AssetList { public List<PackageAsset> Assets = new List<PackageAsset>(); } [Serializable] public class PackageAsset { public string Address; // 资源地址 public string AssetPath; // 资源路径 public string AssetGUID; // 资源 GUID public int BundleID; // 所属 Bundle ID public int DependIDs; // 依赖的 Bundle ID 列表 public string AssetTags; // 资源标签 } [Serializable] public class BundleList { public List<PackageBundle> Bundles = new List<PackageBundle>(); } [Serializable] public class PackageBundle { public int BundleID; // Bundle ID public string BundleName; // Bundle 名称 public string FileName; // Bundle 文件名 public string FileHash; // Bundle 文件 Hash public long FileSize; // Bundle 文件大小 public string FileCRC; // Bundle 文件 CRC public bool Encrypted; // 是否加密 public EBundleType BundleType; // Bundle 类型 public List<int> DependIDs; // 依赖的 Bundle ID 列表 }

PackageName 详解

PackageName 是 Package 的唯一标识符。运行时通过 PackageName 加载 Package。

PackageVersion 详解

PackageVersion 是 Package 的版本号,用于热更新时的版本比较。

ResourceVersion 详解

ResourceVersion 是资源版本号,可以与 PackageVersion 不同。用于更细粒度的版本管理。

AssetList 详解

AssetList 包含了所有资源的信息,包括资源地址、路径、Bundle 等。

BundleList 详解

BundleList 包含了所有 Bundle 的信息,包括 Bundle 名称、文件信息、依赖关系等。

2.3 PackageManifest 的序列化

PackageManifest 使用 JSON 格式序列化:

public class PackageManifest { public string ToJson() { return JsonUtility.ToJson(this, true); } public static PackageManifest FromJson(string json) { return JsonUtility.FromJson<PackageManifest>(json); } public void SaveToFile(string filePath) { string json = ToJson(); File.WriteAllText(filePath, json); } public static PackageManifest LoadFromFile(string filePath) { string json = File.ReadAllText(filePath); return FromJson(json); } }

JSON 序列化详解

使用 Unity 的 JsonUtility 进行 JSON 序列化。JsonUtility 支持 [Serializable] 特性的类。

JSON 文件存储详解

PackageManifest 通常保存为PackageManifest_{PackageVersion}.bytesPackageManifest_{PackageVersion}.json文件。

序列化的兼容性

JsonUtility 的序列化是向前兼容的。新版本可以读取旧版本的 JSON,但旧版本可能无法读取新版本。


三、PackageManifest 生成流程

3.1 生成流程概述

PackageManifest 的生成流程:

PackageManifest 生成流程 1. 收集所有 Bundle 信息 2. 收集所有资源信息 3. 建立资源到 Bundle 的映射 4. 建立 Bundle 依赖关系 5. 计算资源地址 6. 计算 Bundle Hash 和大小 7. 序列化为 JSON 8. 写入输出文件

收集 Bundle 信息详解

从 BuildMap 中收集所有 Bundle 的信息,包括 Bundle 名称、文件、依赖等。

收集资源信息详解

从 BuildMap 中收集所有资源的信息,包括资源地址、路径、Bundle 等。

建立映射详解

建立资源地址到 Bundle 的映射,便于运行时通过资源地址定位 Bundle。

建立依赖关系详解

建立 Bundle 之间的依赖关系,便于运行时加载依赖的 Bundle。

计算 Hash 和大小详解

计算 Bundle 文件的 Hash 和大小,用于版本管理和完整性验证。

3.2 BuildTaskCreateManifest

BuildTaskCreateManifest 是创建 PackageManifest 的构建任务:

public class BuildTaskCreateManifest : IBuildTask { public void Run(BuildContext context) { PackageManifest manifest = new PackageManifest(); // 1. 填充基本信息 manifest.PackageName = context.Parameters.PackageName; manifest.PackageVersion = context.Parameters.PackageVersion; manifest.ResourceVersion = context.Parameters.ResourceVersion; manifest.BuildTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); manifest.BuildEngineVersion = Application.unityVersion; // 2. 创建 Bundle 列表 foreach (var buildBundle in context.BuildMap.Bundles) { var packageBundle = new PackageBundle(); packageBundle.BundleID = manifest.BundleList.Bundles.Count; packageBundle.BundleName = buildBundle.BundleName; packageBundle.FileName = buildBundle.FileName; packageBundle.FileHash = buildBundle.Hash; packageBundle.FileSize = buildBundle.FileSize; packageBundle.FileCRC = buildBundle.CRC; packageBundle.Encrypted = context.Parameters.EnableEncryption; packageBundle.BundleType = buildBundle.BundleType; packageBundle.DependIDs = ConvertDependNamesToIds(buildBundle.Dependencies, manifest); manifest.BundleList.Bundles.Add(packageBundle); } // 3. 创建资源列表 foreach (var assetEntry in context.BuildMap.AssetToBundle) { var packageAsset = new PackageAsset(); packageAsset.Address = assetEntry.Key; packageAsset.AssetPath = assetEntry.Value.AssetPath; packageAsset.AssetGUID = assetEntry.Value.AssetGUID; packageAsset.BundleID = GetBundleId(assetEntry.Value.BundleName, manifest); packageAsset.DependIDs = GetDependIds(assetEntry.Value.Dependencies, manifest); packageAsset.AssetTags = string.Join(",", assetEntry.Value.AssetTags); manifest.AssetList.Assets.Add(packageAsset); } // 4. 保存到文件 manifest.SaveToFile(context.ManifestFilePath); } }

填充基本信息详解

填充 PackageManifest 的基本信息,包括包名、版本、构建时间等。

创建 Bundle 列表详解

将 BuildMap 中的 Bundle 转换为 PackageBundle,并建立 Bundle ID。

创建资源列表详解

将 BuildMap 中的资源转换为 PackageAsset,并设置 Bundle ID。

保存到文件详解

将 PackageManifest 序列化为 JSON 并保存到输出文件。

3.3 资源地址计算

资源地址是 PackageManifest 中的重要字段:

public class AssetAddressCalculator { public string CalculateAddress(string assetPath, AssetBundleCollector collector) { if (collector.AddressRule == EAddressRule.StringAddress) { return CalculateStringAddress(assetPath, collector); } else if (collector.AddressRule == EAddressRule.GUIDAddress) { return AssetDatabase.AssetPathToGUID(assetPath); } else if (collector.AddressRule == EAddressRule.LabelAddress) { return string.Join(",", collector.AssetTags); } return string.Empty; } private string CalculateStringAddress(string assetPath, AssetBundleCollector collector) { if (!string.IsNullOrEmpty(collector.Address)) { return collector.Address + "/" + Path.GetFileNameWithoutExtension(assetPath); } string relativePath = assetPath.Substring(collector.CollectPath.Length); return relativePath.Replace("\\", "/").TrimStart('/').Replace(Path.GetExtension(assetPath), ""); } }

String Address 计算详解

使用 Collector 的 Address 作为前缀,加上文件名生成地址。

GUID Address 计算详解

使用 Unity 的 AssetPathToGUID API 获取资源的 GUID。

Label Address 计算详解

使用 Collector 的 AssetTags 作为地址。


四、BuildReport 概述

4.1 BuildReport 的作用

BuildReport 记录了构建的详细信息:

  • 构建结果(成功/失败)
  • 构建参数
  • 构建时间
  • 资源统计
  • Bundle 统计
  • 错误和警告

4.2 BuildReport 的核心字段

[Serializable] public class BuildReport { public string PackageName; public string PackageVersion; public bool BuildSuccess; public string BuildError; public long BuildStartTime; public long BuildEndTime; public long BuildDuration; public string BuildEngineVersion; public BuildTarget BuildTarget; public int TotalAssetCount; public int TotalBundleCount; public long TotalFileSize; public List<BuildBundleReport> BundleReports = new List<BuildBundleReport>(); public List<string> Warnings = new List<string>(); } [Serializable] public class BuildBundleReport { public string BundleName; public string FileName; public int AssetCount; public long FileSize; public string FileHash; public List<string> Assets = new List<string>(); public List<string> Dependencies = new List<string>(); }

BuildSuccess 详解

BuildSuccess 标识构建是否成功。

BuildError 详解

BuildError 记录构建失败的错误信息。

BuildDuration 详解

BuildDuration 记录构建耗时。

BundleReports 详解

BundleReports 包含了所有 Bundle 的报告。

Warnings 详解

Warnings 记录了构建过程中的警告信息。

4.3 BuildReport 的生成

public class BuildReportGenerator { public BuildReport Generate(BuildContext context) { BuildReport report = new BuildReport(); // 1. 填充基本信息 report.PackageName = context.Parameters.PackageName; report.PackageVersion = context.Parameters.PackageVersion; report.BuildStartTime = context.BuildStartTime; report.BuildEndTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); report.BuildDuration = report.BuildEndTime - report.BuildStartTime; report.BuildEngineVersion = Application.unityVersion; report.BuildTarget = context.BuildTarget; // 2. 统计资源 foreach (var bundle in context.BuildMap.Bundles) { var bundleReport = new BuildBundleReport(); bundleReport.BundleName = bundle.BundleName; bundleReport.FileName = bundle.FileName; bundleReport.AssetCount = bundle.Assets.Count; bundleReport.FileSize = bundle.FileSize; bundleReport.FileHash = bundle.Hash; bundleReport.Assets = bundle.Assets; bundleReport.Dependencies = bundle.Dependencies; report.BundleReports.Add(bundleReport); } // 3. 计算总数 report.TotalBundleCount = report.BundleReports.Count; report.TotalAssetCount = report.BundleReports.Sum(b => b.AssetCount); report.TotalFileSize = report.BundleReports.Sum(b => b.FileSize); // 4. 设置构建结果 report.BuildSuccess = context.BuildSuccess; report.BuildError = context.BuildError; report.Warnings = context.Warnings; return report; } }

填充基本信息详解

填充 BuildReport 的基本信息,包括包名、版本、构建时间、构建平台等。

统计 Bundle 信息详解

为每个 Bundle 生成 BuildBundleReport,包含 Bundle 的详细信息。

计算总数详解

计算所有 Bundle 的资源总数、文件总大小等。

设置构建结果详解

设置构建的成功状态、错误信息、警告信息。

4.4 BuildReport 的展示

BuildReport 提供了多种展示方式:

Editor 内显示

[CustomEditor(typeof(BuildReport))] public class BuildReportEditor : Editor { public override void OnInspectorGUI() { // 显示 BuildReport 的内容 } }

导出为 JSON

public void SaveToJson(string filePath) { string json = JsonUtility.ToJson(this, true); File.WriteAllText(filePath, json); }

导出为 HTML

可以自定义将 BuildReport 导出为 HTML 格式,便于在浏览器中查看。


五、版本管理

5.1 版本号格式

YooAsset 使用语义化版本号(Semantic Versioning):

格式

Major.Minor.Patch(如1.0.0

Major 版本

主版本号,表示重大更新,可能不兼容旧版本。

Minor 版本

次版本号,表示新增功能,向后兼容。

Patch 版本

补丁版本号,表示 bug 修复。

5.2 版本管理实现

public class VersionManager { public bool IsNewerVersion(string newVersion, string oldVersion) { var newVer = new Version(newVersion); var oldVer = new Version(oldVersion); return newVer > oldVer; } public string GenerateNextVersion(string currentVersion, EVersionIncrementType incrementType) { var ver = new Version(currentVersion); switch (incrementType) { case EVersionIncrementType.Major: return $"{ver.Major + 1}.0.0"; case EVersionIncrementType.Minor: return $"{ver.Major}.{ver.Minor + 1}.0"; case EVersionIncrementType.Patch: return $"{ver.Major}.{ver.Minor}.{ver.Build + 1}"; default: return currentVersion; } } }

版本比较详解

使用 .NET 的 Version 类进行版本比较。

版本递增详解

支持 Major、Minor、Patch 三种递增方式。

5.3 版本号的使用

版本号在 YooAsset 中有以下用途:

  • 标识 Package 的版本
  • 标识构建产物的版本
  • 标识热更新的差异
  • 标识缓存的版本

六、总结

本章深入解析了 YooAsset 清单(Manifest)与报告(Report)的源码实现,包括:

  • PackageManifest 概述:PackageManifest 的作用、字段、序列化
  • PackageManifest 生成流程:生成流程、BuildTaskCreateManifest、地址计算
  • BuildReport 概述:BuildReport 的作用、字段、生成
  • BuildReport 展示:Editor 内显示、JSON 导出、HTML 导出
  • 版本管理:版本号格式、版本比较、版本递增

PackageManifest 和 BuildReport 是 YooAsset 编辑器端的重要组成部分,深入理解它们的实现有助于更好地使用和扩展 YooAsset。


上一篇:构建管线分析
下一篇:调试与诊断工具