10-05-YooAsset实战-Unity资源配置与打包
2026/7/27 7:43:05 网站建设 项目流程

实战-资源配置与打包

篇章:10-实战篇-从零搭建
状态:已完成
阅读时间:约 25 分钟


一、引言

1.1 本章在系列中的定位

资源配置(Collector 配置)和打包(Build)是将 Unity 资源转化为 YooAsset 资源的核心环节。本章将详细讲解:

  • 如何配置 Collector(资源收集器)
  • 如何配置 Group(资源组)
  • 如何执行打包
  • 如何优化打包性能

1.2 本章要解决的核心问题

  • Collector 的工作原理与配置方法
  • Group 的合理划分
  • 打包脚本的编写
  • 打包性能优化

1.3 阅读前置要求

  • 完成 10-01 到 10-04
  • 了解 Unity Editor 扩展基础

二、AssetBundleCollector 详解

2.1 Collector 的概念

AssetBundleCollector是 YooAsset 的资源收集器,负责:

  1. 收集资源:从 Unity Asset 目录中按规则提取
  2. 分类资源:按 Group、Tag 分类
  3. 生成清单:构建 Bundle 划分方案

2.2 Collector 的工作流

[配置 Collectors] │ ▼ [AssetBundleCollector.CollectAssets] │ ├── 遍历 Asset 目录 │ ├── 匹配 Filter 规则 │ └── 应用 Address 规则 │ ├── 应用 PackRule │ ├── ByFile: 每个资源一个 Bundle │ ├── ByFolder: 每个文件夹一个 Bundle │ ├── ByTopLevel: 按顶层文件分 │ └── PackExplicit: 显式指定 │ └── 输出 BuildMap ├── Bundle 列表 ├── 资源列表 └── 依赖关系

2.3 Collector 的配置

2.3.1 创建 Collector
[CreateAssetMenu(fileName = "MainCollector", menuName = "YooAsset/Collector")] public class MainCollector : ScriptableObject { public string CollectorName = "MainCollector"; public List<CollectRule> CollectRules = new(); } [Serializable] public class CollectRule { public string SearchPattern; // 搜索模式 public string[] ExcludePatterns; // 排除模式 public string GroupName; // 目标 Group public string AddressRule; // Address 规则 public EPackRuleType PackRule; // 打包规则 public string[] Tags; // 资源标签 }
2.3.2 常用配置示例

示例 1:按文件类型收集

new CollectRule { SearchPattern = "Assets/Art/**/*.png", GroupName = "TextureGroup", AddressRule = "ByFileName", PackRule = EPackRuleType.PackByFile, Tags = new[] { "texture", "ui" } }

示例 2:按文件夹收集

new CollectRule { SearchPattern = "Assets/Prefabs/UI/**/*.prefab", GroupName = "UIGroup", AddressRule = "ByFolderPath", PackRule = EPackRuleType.PackByFolder }

示例 3:按收集组收集

new CollectRule { SearchPattern = "Assets/Bundles/**/*", GroupName = "SharedGroup", AddressRule = "ByCollectorGroup", PackRule = EPackRuleType.PackByCollectorGroup }

2.4 PackRule 详解

YooAsset 的 PackRule 决定"哪些资源打到一个 Bundle":

PackRule含义适用Bundle 数量
PackByFile每个资源独立打包通用最多
PackByFolder同一文件夹打到一个 BundleUI、Audio中等
PackByCollectorGroup整个 Group 一个 Bundle小型游戏
PackByTopLevel按顶层子目录打包模块化项目中等
PackExplicit显式指定特殊需求自定
2.4.1 PackByFile
Bundle/ ├── bundle_Hero_Assassin ├── bundle_Hero_Mage ├── bundle_Hero_Tank └── ...
2.4.2 PackByFolder
Bundle/ ├── UI/ (整个 UI 文件夹) │ ├── bundle_ui ├── Character/ (整个 Character 文件夹) │ ├── bundle_character └── ...
2.4.3 PackExplicit

通过IPackRule自定义:

public class CustomPackRule : IPackRule { public bool Match(AssetInfo info) => true; public string GetBundleName(AssetInfo info) { // 自定义打包规则:按资源大小 if (info.FileSize > 1024 * 1024) // 大于 1MB return "large_assets"; else return "small_assets"; } }

2.5 Address 规则

AddressRule示例适用
ByFileNameHero_Assassin命名规范的项目
ByFolderPathCharacters/Hero_Assassin路径即语义
ByCollectorGroupdefault/Characters/Hero_Assassin多 Group 项目
ByExplicit自定义完全控制

三、Group 配置

3.1 Group 的作用

Group 是"打包配置的集合",每个 Group 包含:

  • 压缩配置
  • 加密配置
  • 输出路径
  • 资源依赖

3.2 Group 的划分原则

3.2.1 按"更新频率"划分
Group_HotUpdate # 高频更新(活动、商城) ├── CompressOption: LZ4 └── UpdatePolicy: Always Group_Stable # 低频更新(核心玩法) ├── CompressOption: LZ4 └── UpdatePolicy: OnMajor Group_Static # 极少更新(公共资源) ├── CompressOption: LZ4 └── UpdatePolicy: OnMajor
3.2.2 按"加载时机"划分
Group_Startup # 启动时加载 ├── CompressOption: LZ4 └── LoadTime: Synchronous Group_Normal # 运行时加载 ├── CompressOption: LZ4 └── LoadTime: Asynchronous
3.2.3 按"资源类型"划分
Group_Texture Group_Audio Group_Prefab Group_Scene Group_Config

3.3 Group 的配置

[CreateAssetMenu(fileName = "GroupSettings", menuName = "YooAsset/Group")] public class GroupSettings : ScriptableObject { public string GroupName; public ECompressOption CompressOption = ECompressOption.LZ4; public EEncryptionOption EncryptionOption = EEncryptionOption.None; public string EncryptionSecret; public EBundledOutputStyle OutputStyle = EBundledOutputStyle.HashName; public long MaxBundleSize = 10 * 1024 * 1024; // 10MB }

四、Build 流程

4.1 Build 流程总览

[BuildParameters] │ ▼ [ScriptableBuildPipeline.Build] │ ├── 1. AssetBundleCollector.Collect │ └── 输出 BuildMap │ ├── 2. Bundle 划分 │ └── 按 PackRule 分组 │ ├── 3. 依赖分析 │ └── 生成依赖图 │ ├── 4. BuildTaskBuilder │ └── 调用 BuildPipeline.BuildAssetBundles │ ├── 5. BuildTaskManifest │ └── 生成 PackageManifest │ ├── 6. BuildTaskReport │ └── 生成 BuildReport.html │ └── 7. 输出到 OutputPath └── BuildReport + Manifest + Bundles

4.2 完整的 Build 脚本

using UnityEditor; using UnityEngine; using YooAsset.Editor; using System.IO; public class GameBuildPipeline { [MenuItem("Build/Android")] public static void BuildAndroid() { var buildParams = new BuildParameters { // 基础配置 BuildOutputRoot = GetBuildOutputRoot(), BuildVersion = PlayerSettings.bundleVersion, // 构建管线 BuildPipeline = EBuildPipeline.ScriptableBuildPipeline, // 压缩与加密 CompressOption = ECompressOption.LZ4, EncryptionOption = EEncryptionOption.None, // 平台 BuildTarget = BuildTarget.Android, // 输出 OutputNameStyle = EOutputNameStyle.HashName, CopyToStreamingAssets = true, // 共享 EnableSharedPackRule = true, // 验证 VerifyBuildingResult = true, // 报告 BuildReportPath = "BuildReports" }; var pipeline = new ScriptableBuildPipeline(); var manifest = pipeline.Build(buildParams); if (manifest.Success) { Debug.Log($"[Build] 构建成功: {manifest.OutputRoot}"); OpenBuildReport(manifest.OutputRoot); } else { Debug.LogError($"[Build] 构建失败: {manifest.ErrorInfo}"); } } static string GetBuildOutputRoot() { return Path.Combine(Application.dataPath, "..", "Builds", "YooAsset"); } static void OpenBuildReport(string outputRoot) { var reportPath = Path.Combine(outputRoot, "BuildReport.html"); if (File.Exists(reportPath)) { EditorUtility.RevealInFinder(reportPath); } } }

4.3 多平台构建

public class MultiPlatformBuild { [MenuItem("Build/All Platforms")] public static void BuildAll() { var platforms = new[] { BuildTarget.Android, BuildTarget.iOS, BuildTarget.StandaloneWindows64, BuildTarget.WebGL }; foreach (var target in platforms) { BuildForPlatform(target); } } static void BuildForPlatform(BuildTarget target) { var buildParams = GetBuildParams(target); var pipeline = new ScriptableBuildPipeline(); var result = pipeline.Build(buildParams); Debug.Log($"[{target}] Build {result.Success}: {result.OutputRoot}"); } }

4.4 命令行构建

public class CommandLineBuild { public static void Build() { // 从命令行参数读取 var buildPath = System.Environment.GetEnvironmentVariable("BUILD_OUTPUT") ?? "Builds"; var buildVersion = System.Environment.GetEnvironmentVariable("BUILD_VERSION") ?? "1.0.0"; var buildTargetStr = System.Environment.GetEnvironmentVariable("BUILD_TARGET") ?? "Android"; var buildTarget = (BuildTarget)System.Enum.Parse(typeof(BuildTarget), buildTargetStr); var buildParams = new BuildParameters { BuildOutputRoot = buildPath, BuildVersion = buildVersion, BuildTarget = buildTarget, // ... 其他配置 }; var pipeline = new ScriptableBuildPipeline(); var result = pipeline.Build(buildParams); // 退出码(CI 使用) EditorApplication.Exit(result.Success ? 0 : 1); } }

五、构建性能优化

5.1 构建时间优化

优化项效果
启用增量构建构建时间减少 50%+
减少 Bundle 数量构建时间减少 30%+
关闭 verifyBuildingResult构建时间减少 10%
并行构建构建时间减少 20%+
SSD 硬盘构建时间减少 30%+
关闭 LZMA 压缩构建时间减少 50%+

5.2 增量构建

YooAsset 默认支持增量构建:

var buildParams = new BuildParameters { IncrementalBuild = true, // 启用增量 // ... };

5.3 并行构建

public class ParallelBuild { [MenuItem("Build/Parallel")] public static void BuildParallel() { var tasks = new[] { Task.Run(() => BuildForPlatform(BuildTarget.Android)), Task.Run(() => BuildForPlatform(BuildTarget.iOS)), Task.Run(() => BuildForPlatform(BuildTarget.StandaloneWindows64)) }; Task.WaitAll(tasks); } }

5.4 构建缓存

public class BuildCache { public void SetupCache() { var cachePath = Path.Combine(Application.dataPath, "..", "Library", "YooAssetBuildCache"); Directory.CreateDirectory(cachePath); YooAssetBuildCache.CachePath = cachePath; } }

六、BuildReport 解读

6.1 报告结构

BuildReport.html 包含:

BuildReport.html ├── 总览 │ ├── 构建时间 │ ├── Bundle 总数 │ ├── 资源总数 │ ├── 总大小 │ └── 压缩率 │ ├── Bundle 列表 │ ├── bundle_01 │ │ ├── 大小 │ │ ├── 资源数 │ │ └── 依赖 │ └── ... │ ├── 资源列表 │ ├── 按类型分类 │ └── 按大小排序 │ ├── 警告与错误 └── 优化建议

6.2 关键指标

6.2.1 压缩率
压缩率 = 压缩后大小 / 原始大小 理想值:< 70%(LZ4)
6.2.2 Bundle 数量
资源总量推荐 Bundle 数
< 100MB< 50
100MB-1GB50-200
1GB-10GB200-1000
> 10GB1000-5000
6.2.3 重复资源

报告中的"重复资源"列表:

⚠️ 检测到以下资源被多个 Bundle 引用: - assets/Common/Atlas/UI.png (5 个 Bundle) - assets/Common/Font/Default.ttf (10 个 Bundle)

6.3 优化建议

public class BuildReportAnalyzer { public void Analyze(string reportPath) { var report = LoadReport(reportPath); // 1. 检查 Bundle 数量 if (report.BundleCount > 1000) { Debug.LogWarning("Bundle 数量过多,考虑合并"); } // 2. 检查大 Bundle foreach (var bundle in report.Bundles) { if (bundle.Size > 50 * 1024 * 1024) // 50MB { Debug.LogWarning($"Bundle {bundle.Name} 过大: {bundle.Size}"); } } // 3. 检查重复资源 foreach (var kvp in report.DuplicatedAssets) { Debug.LogWarning($"资源 {kvp.Key} 重复 {kvp.Value} 次"); } } }

七、CI/CD 集成

7.1 Jenkins 集成

// Jenkinsfile pipeline { agent any stages { stage('Checkout') { steps { git 'https://github.com/your-org/your-game.git' } } stage('Build') { steps { sh ''' docker run --rm \ -v $WORKSPACE:/workspace \ unityci/editor:2022.3.20f1 \ -batchmode -quit \ -projectPath /workspace \ -executeMethod GameBuildPipeline.BuildAndroid ''' } } stage('Upload') { steps { sh 'python3 upload.py $WORKSPACE/Builds $BUILD_NUMBER' } } } }

7.2 GitLab CI 集成

# .gitlab-ci.yml build_android: stage: build image: unityci/editor:2022.3.20f1 script: - BUILD_OUTPUT=$(pwd)/Builds - BUILD_VERSION=$CI_PIPELINE_ID - BUILD_TARGET=Android - Unity -batchmode -quit -projectPath . -executeMethod GameBuildPipeline.BuildAndroid artifacts: paths: - Builds/ expire_in: 7 days

7.3 GitHub Actions 集成

# .github/workflows/build.yml name: Build on: push: branches: [main] jobs: build: runs-on: ubuntu-latest container: image: unityci/editor:2022.3.20f1 steps: - uses: actions/checkout@v2 - name: Build Android env: BUILD_OUTPUT: ${{ github.workspace }}/Builds BUILD_VERSION: ${{ github.run_number }} BUILD_TARGET: Android run: | Unity -batchmode -quit \ -projectPath . \ -executeMethod GameBuildPipeline.BuildAndroid

八、常见问题

8.1 构建失败

错误原因解决
资源找不到路径错误检查 SearchPattern
循环依赖资源互相引用抽离共享包
Bundle 命名冲突同名 Bundle修改命名规则
类型不匹配资源类型错误检查 AssetImporter

8.2 构建警告

⚠️ Warning: 资源 X 未被任何 Collector 收集 → 检查 Collect 规则 ⚠️ Warning: Bundle 数量过多(> 1000) → 调整 PackRule ⚠️ Warning: 资源大小超过 50MB → 拆分资源

8.3 性能调优

// 1. 启用缓存 var buildParams = new BuildParameters { UseBuildCache = true, // ... }; // 2. 关闭类型树(减小体积) var buildParams = new BuildParameters { WriteTypeTree = false, // 不写入类型树 // 谨慎使用,可能影响兼容性 }; // 3. 启用并行 var buildParams = new BuildParameters { MaxConcurrent = 8, // 并行数 };

九、总结

9.1 本章要点回顾

  • Collector:配置资源收集规则,决定哪些资源进 Bundle
  • Group:打包配置的集合,决定如何打包
  • Build:构建流程,包括收集、依赖、构建、清单、报告
  • 优化:增量构建、并行构建、构建缓存

9.2 与前后章节的关联

  • 前章:10-04 介绍了资源组织与依赖管理
  • 本章:聚焦资源配置与打包
  • 后章:10-06 将介绍资源加载与使用

9.3 实践建议

  1. Collector 规则要严格:避免"什么都打包"
  2. Group 数量适中:3-10 个最佳
  3. 增量构建:日常开发用增量,正式发版用全量
  4. CI/CD 自动化:避免人工打包
  5. 报告必看:BuildReport 是优化的起点

上一篇:资源组织与依赖管理实战
下一篇:资源加载与使用

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询