网易首页 > 网易号 > 正文 申请入驻

Unity社区精华帖 | SBP - Scriptable Build Pipeline

0
分享至

Scriptable Build Pipeline 是什么?能来带什么好处?

自定义 Unity 如何构建应用内容

将原先处于C++的引擎代码移到了C#

加速了AssetBundle的构建时间

改善增量构建处理

对开发者来说具备更多的灵活性

Unity 版本要求:Unity 2018.3 +

术语

Asset

磁盘上的源文件,通常位于项目的 “Assets” 文件夹中。此文件在内部导入到您的资产的可用于游戏的表示形式,其中可以包含多个 Object(SubAsset)。

Object (SubAsset)

单个 Unity 可序列化单元。也称为 SubAsset。导入的 Asset 由一个或多个对象组成。

Includes

从中构造 Asset 的唯一一组 Object。

References

一组需要被 Asset 使用,但不在该 Asset 中的 Object。

快速入门 & BuildIn切换

BuildAssetBundles

BuildIn Pipeline


using System.IO;using UnityEditor;
public static class BuildAssetBundlesExamplepublic static bool BuildAssetBundles(string outputPath, bool forceRebuild, bool useChunkBasedCompression, BuildTarget buildTarget)var options = BuildAssetBundleOptions.None;if (useChunkBasedCompression)options |= BuildAssetBundleOptions.ChunkBasedCompression;
if (forceRebuild)options |= BuildAssetBundleOptions.ForceRebuildAssetBundle;
Directory.CreateDirectory(outputPath);var manifest = BuildPipeline.BuildAssetBundles(outputPath, options, buildTarget);return manifest != null;

SBP

CompatibilityBuildPipeline 是 SBP 目前官方使用 SBP 流程适配 BuildIn 流程的适配实现。

SBP 不支持以前支持的所有功能。


using System.IO;using UnityEditor;// Added new usingusing UnityEditor.Build.Pipeline;
public static class BuildAssetBundlesExamplepublic static bool BuildAssetBundles(string outputPath, bool forceRebuild, bool useChunkBasedCompression, BuildTarget buildTarget)var options = BuildAssetBundleOptions.None;if (useChunkBasedCompression)options |= BuildAssetBundleOptions.ChunkBasedCompression;
if (forceRebuild)options |= BuildAssetBundleOptions.ForceRebuildAssetBundle;
Directory.CreateDirectory(outputPath);// Replaced BuildPipeline.BuildAssetBundles with CompatibilityBuildPipeline.BuildAssetBundles herevar manifest = CompatibilityBuildPipeline.BuildAssetBundles(outputPath, options, buildTarget);return manifest != null;

注意事项

CompatibilityBuildPipeline.BuildAssetBundles vs BuildPipeline.BuildAssetBundle 的特性与行为的对比。

AssetBundleBuild.addressableNames:

https://docs.unity3d.com/ScriptReference/AssetBundleBuild-addressableNames.html

BuildAssetBundleOptions

AssetBundle SBP 构建流程

01 Setup - 平台环境初始化

SwitchToBuildPlatform

RebuildSpriteAtlasCache

02 Player Scripts - 工程源代码编译

BuildPlayerScripts、PostScriptsCallback

03 Dependency

CalculateSceneDependencyData

CalculateCustomDependencyData (UNITY_2019_3_OR_NEWER)

CalculateAssetDependencyData

StripUnusedSpriteSources

PostDependencyCallback

04 Packing

GenerateBundlePacking

GenerateBundleCommands

GenerateSubAssetPathMaps

GenerateBundleMaps

PostPackingCallback

05Writing

WriteSerializedFiles

ArchiveAndCompressBundles

AppendBundleHash

GenerateLinkXml

PostWritingCallback

06 Generate manifest files

官方 TODO 项

01 Setup

SwitchToBuildPlatform

切换当前平台为构建 AssetBundle 的目标平台对应的 BuildTargetGroup 、 BuildTarget。

执行回调 IPreprocessShaders 、IProcessScene、IProcessSceneWithReport

关键逻辑:


EditorUserBuildSettings.SwitchActiveBuildTarget(m_Parameters.Group, m_Parameters.Target);

RebuildSpriteAtlasCache

针对目标平台重新构建 工程内所有的 SpriteAtlas。

关键逻辑:


SpriteAtlasUtility.PackAllAtlases(m_Parameters.Target);

02 Player Scripts

BuildPlayerScripts

编译目标平台源代码生成 ScriptInfo(TypeDB - 记录了脚本类型 、 属性数据)

TypeDB 为后续的序列化提供正确的字段名称。

关键逻辑:


PlayerBuildInterface.CompilePlayerScripts(m_Parameters.GetScriptCompilationSettings(), m_Parameters.ScriptOutputFolder);

PostScriptsCallback

回调脚本订阅了脚本编译完成节点的所有函数。

上层开发者,注册监听 BuildCallbacks.PostScriptsCallbacks。

关键逻辑:


IScriptsCallback.PostScripts(IBuildParameters parameters, IBuildResults results);

03 Dependency

CalculateSceneDependencyData - 计算所有场景的依赖信息

判断是否使用 Cache 机制;计算场景相关依赖项

关键逻辑:


#if UNITY_2019_3_OR_NEWERContentBuildInterface.CalculatePlayerDependenciesForScene(scenePath, settings, usageTags, m_DependencyData.DependencyUsageCache);#elseContentBuildInterface.PrepareScene(scenePath, settings, usageTags, m_DependencyData.DependencyUsageCache, outputFolder);#endif

Cache 仅记录预制相关的依赖。

CalculateCustomDependencyData (UNITY_2019_3_OR_NEWER)

计算未被 AssetDatabase 追踪的自定义 Assets 依赖的 Object 关系;

由 IBundleBuildContent.CustomAssets 自定义 AssetBundle 包含的内容。

关键逻辑:


foreach (CustomContent info in IBundleBuildContent.CustomAssets)info.Processor(info.Asset, this);

CalculateAssetDependencyData - 计算所有 Asset的依赖数据

基础入参

源代码的 TypeDB

GraphicsSettings

场景的 LightSetting

获取 Asset 的所包含的 Objects

即为该 Asset 引用的 Object;为 该 Asset YAML 序列化中 !u![ClassID] 段所表示的 Object。

通过 TypeDB 获取 Objects 所引用的 Objects

如果是 Sprite 类型资源,则进行 Sprite Atlas 的打包设置

计算 SubAssets

关键逻辑:


var includedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(asset, input.Target);var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, input.Target, input.TypeDB);ObjectIdentifier[] representations = ContentBuildInterface.GetPlayerAssetRepresentations(asset, target);// Main Asset always returns at index 0, we only want representations, so check for greater than 1 lengthif (representations.IsNullOrEmpty() || representations.Length < 2)return;extendedData = new ExtendedAssetData();extendedData.Representations.AddRange(representations.Skip(1));

StripUnusedSpriteSources - 删除 Assets引用中被Packer的Sprite

筛选出已经被 SpritePacker 打包的Sprite,所归属的 SourceTexture;

删除 Assets 中引用的 Sprite信息;

关键逻辑:


var unusedSources = new HashSet();var textures = m_SpriteData.ImporterData.Values.Where(x => x.PackedSprite).Select(x => x.SourceTexture);unusedSources.UnionWith(textures);
// Count refs from assetsvar assetRefs = m_DependencyData.AssetInfo.SelectMany(x => x.Value.referencedObjects);foreach (ObjectIdentifier reference in assetRefs)unusedSources.Remove(reference);
// Count refs from scenesvar sceneRefs = m_DependencyData.SceneInfo.SelectMany(x => x.Value.referencedObjects);foreach (ObjectIdentifier reference in sceneRefs)unusedSources.Remove(reference);
// SetOutputInformationforeach (var source in unusedSources)var assetInfo = m_DependencyData.AssetInfo[source.guid];assetInfo.includedObjects.RemoveAt(0);
ExtendedAssetData extendedData;if (m_ExtendedAssetData != null && m_ExtendedAssetData.ExtendedData.TryGetValue(source.guid, out extendedData))extendedData.Representations.Remove(source);if (extendedData.Representations.Count == 1)m_ExtendedAssetData.ExtendedData.Remove(source.guid);

PostDependencyCallback

在依赖计算完成后的事件通知

上层开发者,注册监听 BuildCallbacks.PostDependencyCallback

关键逻辑:


IDependencyCallback.PostDependency(IBuildParameters parameters, IDependencyData dependencyData);

04Packing - 资源构建

GenerateBundlePacking - 组装AssetBundle以及计算依赖加载列表

Normal AssetBundle

Streamed Scene AssetBundle

ArchiveFileSystem

校验 Object 是否是 Assets 类型 或 自定义Assets类型 | Scene 类型,创建对应类型的 “容器结构”

可通过 ValidationMethods.ValidAssetFake 接管校验逻辑

计算 Asset 所依赖的加载列表

剔除 Unity默认的内置资源引用 - 处理依赖关系中的重复递归依赖 & 打破环形依赖;(若是 Scene Bundle,则剔除 sharedAssets 的重复引用)

关键逻辑:


foreach (var bundle in m_BuildContent.BundleLayout)if (ValidAssetBundle(bundle.Value, customAssets))PackAssetBundle(bundle.Key, bundle.Value, assetToReferences);else if (ValidationMethods.ValidSceneBundle(bundle.Value))PackSceneBundle(bundle.Key, bundle.Value, assetToReferences);
// Remove Default Resources and Includes for Assets assigned to Bundlesforeach (ObjectIdentifier reference in references)if (reference.filePath.Equals(CommonStrings.UnityDefaultResourcePath, StringComparison.OrdinalIgnoreCase))continue;if (dependencyData.AssetInfo.TryGetValue(reference.guid, out AssetLoadInfo referenceInfo))referencedAssets.Add(referenceInfo);continue;referencesPruned.Add(reference);

GenerateBundleCommands - 为需要序列化的AssetBundle创建WriteOperation行为

初始化 AssetBundle MainAsset

创建对应的 BundleCommand (CreateAssetBundleCommand、CreateSceneBundleCommand + CreateSceneDataCommand)

AssetBundleCommand :

1.建立加载 Asset的入参与 Object 的映射关系

2.记录 AssetsBundle 中包含的Assets相关信息(依赖的Object hash、序列化组织形式等)并排序,以此确保每次序列化数据的稳定性

SceneBundleCommand :

1.建立加载 Scene 所包含需要序列化的Object与加载的入参的映射关系

2.记录 SceneBundle 依赖的Object 至 preloadObjects

SceneDataCommand :

1.建立加载Scene 所需要附加的Assets 的映射关系

2.记录 SceneBundle 依赖的Object 至 preloadObjects

关键逻辑:


Dictionarystring> assetToMainFile = new Dictionarystring>();foreach (var pair in m_WriteData.AssetToFiles)assetToMainFile.Add(pair.Key, pair.Value[0]);
foreach (var bundlePair in m_BuildContent.BundleLayout)if (ValidAssetBundle(bundlePair.Value, customAssets))// Use generated internalName here as we could have an empty asset bundle used for raw object storage (See CreateStandardShadersBundle)var internalName = string.Format(CommonStrings.AssetBundleNameFormat, m_PackingMethod.GenerateInternalFileName(bundlePair.Key));CreateAssetBundleCommand(bundlePair.Key, internalName, bundlePair.Value);else if (ValidationMethods.ValidSceneBundle(bundlePair.Value))var firstScene = bundlePair.Value[0];CreateSceneBundleCommand(bundlePair.Key, assetToMainFile[firstScene], firstScene, bundlePair.Value, assetToMainFile);for (int i = 1; i < bundlePair.Value.Count; ++i)var additionalScene = bundlePair.Value[i];CreateSceneDataCommand(assetToMainFile[additionalScene], additionalScene);

Unity 官方微信

第一时间了解Unity引擎动向,学习最新开发技巧

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
辉腾鞋业28死事件发酵!网友:年运营成本至少2000万,5层7000平米的工厂,效益非常不错了

辉腾鞋业28死事件发酵!网友:年运营成本至少2000万,5层7000平米的工厂,效益非常不错了

曹莽看世界
2026-07-11 15:16:00
周星驰官宣星女郎雪野,19岁纯素人无拍戏经验!网友:太像艾米

周星驰官宣星女郎雪野,19岁纯素人无拍戏经验!网友:太像艾米

娱乐团长
2026-07-11 16:59:28
贵港动物园被淹后只剩寥寥几只动物,园方回应“锁死笼舍致3狮溺亡”争议:村落密集怕它们逃出伤人,辛苦养大我们也舍不得

贵港动物园被淹后只剩寥寥几只动物,园方回应“锁死笼舍致3狮溺亡”争议:村落密集怕它们逃出伤人,辛苦养大我们也舍不得

极目新闻
2026-07-11 00:16:49
抽象!网友用一根葱模仿哈兰德,哈兰德回复了一个表情包

抽象!网友用一根葱模仿哈兰德,哈兰德回复了一个表情包

懂球帝
2026-07-11 14:25:17
长沙美女彭慕曦社死!占他人车位8天被迫道歉,知情人曝更多细节

长沙美女彭慕曦社死!占他人车位8天被迫道歉,知情人曝更多细节

小鋭有话说
2026-07-11 13:35:21
台风"巴威"又睁眼了!重新加强至14级!登陆时间地点有变,环流非常巨大…最新研判

台风"巴威"又睁眼了!重新加强至14级!登陆时间地点有变,环流非常巨大…最新研判

浙江之声
2026-07-11 07:56:54
最新预测:“巴威”11日半夜前后在浙江苍南至三门一带登陆

最新预测:“巴威”11日半夜前后在浙江苍南至三门一带登陆

澎湃新闻
2026-07-11 08:52:27
泄洪不通知:一场被系统性赦免的决水罪

泄洪不通知:一场被系统性赦免的决水罪

朝廷心腹
2026-07-11 12:29:41
王石又登热搜!跟随田朴珺练习普拉提引争议,网友:想捂住衰老的盖子,搞得弄巧成拙

王石又登热搜!跟随田朴珺练习普拉提引争议,网友:想捂住衰老的盖子,搞得弄巧成拙

火山詩话
2026-07-11 14:23:42
四川警方突袭一牛肉制假窝点,现场多人正徒手在猪肉上抹牛油、牛血冒充牛肉,涉案超百万元

四川警方突袭一牛肉制假窝点,现场多人正徒手在猪肉上抹牛油、牛血冒充牛肉,涉案超百万元

环球网资讯
2026-07-11 11:33:26
朝鲜通报腐败犯罪 金正恩强调廉洁

朝鲜通报腐败犯罪 金正恩强调廉洁

新京报
2026-07-11 11:49:06
队报:梅西本届世界杯64%的时间都处于行走状态,但效率十足

队报:梅西本届世界杯64%的时间都处于行走状态,但效率十足

懂球帝
2026-07-11 04:50:13
曝詹姆斯与一支球队基本敲定签约!文霍斯特:这支球队不是骑士

曝詹姆斯与一支球队基本敲定签约!文霍斯特:这支球队不是骑士

罗说NBA
2026-07-11 05:10:19
闵先生怒曝调解内幕!女车主领导陪同!挑事的眼镜男消失 身份成谜

闵先生怒曝调解内幕!女车主领导陪同!挑事的眼镜男消失 身份成谜

观察鉴娱
2026-07-11 09:42:19
长沙占车位女子彭某身份被证实!车主再曝新细节,眼镜男才是关键

长沙占车位女子彭某身份被证实!车主再曝新细节,眼镜男才是关键

社会日日鲜
2026-07-11 06:13:56
娇妻全力安慰!35岁丁丁长叹一声:我都35了,还做过手术,尽力了

娇妻全力安慰!35岁丁丁长叹一声:我都35了,还做过手术,尽力了

风过乡
2026-07-11 10:41:54
48架二手歼-10B落户伊朗,西方军贸垄断彻底破防!

48架二手歼-10B落户伊朗,西方军贸垄断彻底破防!

璠爷财事通
2026-07-08 19:00:03
曝C罗遭到队友孤立!名宿:他确实很伟大,但从未进入GOAT之序列

曝C罗遭到队友孤立!名宿:他确实很伟大,但从未进入GOAT之序列

风过乡
2026-07-11 08:07:35
长沙霸车姐彻底怂了!纪委介入,手写道歉信,履历曝光,饭碗难保

长沙霸车姐彻底怂了!纪委介入,手写道歉信,履历曝光,饭碗难保

谭谈社会
2026-07-11 17:27:12
全球两大氦气巨头突然断供,中国用6年前布下的棋子一招反杀

全球两大氦气巨头突然断供,中国用6年前布下的棋子一招反杀

毒sir财经
2026-07-10 22:15:03
2026-07-11 19:00:49
Unity incentive-icons
Unity
Unity中国官方帐户
2485文章数 6733关注度
往期回顾 全部

科技要闻

苹果起诉OpenAI系统性窃密,挖超400前员工

头条要闻

长沙通报体育局女干部占车位事件:涉事干部被停职

头条要闻

长沙通报体育局女干部占车位事件:涉事干部被停职

体育要闻

燃尽的比利时黄金一代,逃不过厄运诅咒

娱乐要闻

周星驰官宣星女郎 纯素人无拍戏经验

财经要闻

一封举报信 引发小红书IPO合规考验

汽车要闻

预售权益价11.78万起 五菱星光L将于7月16日上市

态度原创

教育
艺术
数码
健康
时尚

教育要闻

2026高考首批捡漏王诞生!甘肃487投档985兰州大学!快来沾喜气!

艺术要闻

他是米芾的“头号粉丝”,临摹其字以假乱真

数码要闻

RTX 50系列显卡热点温度107°C!降频元凶找到了

肝病、肾病患者注意!吃粘食要谨慎

《2026中国时尚消费报告》发布

无障碍浏览 进入关怀版