当前位置: 首页 > news >正文

Unity构建详解(1)——SBP介绍

【前言】

Unity的资源工作流程分为导入、创建、构建、分发、加载。我们说的是其中的构建步骤。

构建是指将项目工程中的资源文件和代码整合程可执行文件的过程,构建的结果是生成可执行文件,在win平台上是exe,在Android平台上是apk,在ios平台上是ipa。

游戏比互联网的app多了很多资产,资产的整合是构建过程中非常耗时且重要的一步,这一步通常会被单独拿出来说,叫打包,在Unity中叫打Bundle。因此,我们说游戏构建通常分为两个大步骤,一是打包,二是构建。

Unity目前主要提供两种打包方式:

一是默认的BuildPipeline.BuildAssetBundles

二是比较新的Scriptable Build Pipeline

SBP的功能日趋完善,逐渐被认可,是以后的主要趋势。

SBP底层调用的接口和BuildIn的类似,是在其基础上实现的,SBP将打包过程中的更多的接口暴露出来,采用流水线的设计方式,提供更加灵活的打包方式。

【流水线模式】

流水线概念源于现代工业,在生产流水线上,原材料经过一系列操作被制作成商品,每个操作可能会修改原材料或添加新材料

将其转换为代码,我们可以提炼三个关键词,材料data,操作Operation,流水线Pipeline,每个操作继承一个IOperation接口,每个材料继承IData接口,Pipeline有一系列的IOperation和IData,先准备好一系列操作和材料,随后顺序执行每个操作。

如果随后需要添加新的操作和材料,向流水线中添加即可,具体实现可以看下面的文章

流水线的实现

【SBP的优势】

流水线本身带来的优势

  • 灵活性,更精细的控制打包流程,增加自定义处理
  • 并行性,将打包步骤进行了拆分,有利于在某些步骤做并行处理,减少打包时长

其他优势

  • 增量打包,对打包做了数据缓存,有利于减少打包时长
  • 精细日志,对打包过程做了更细粒度的Profiler、耗时信息统计、结果日志输出,有利于在对打包流程进行分析和优化

【SBP的流水线实现】

IData对应IBuildContext,IOperation对应IBuildTask,Pipeline对应ContentPipeline

ContentPipeline应该持有一系列的IBuildContext,这里没有设置单独的字段持有,而是在调用BuildAssetBundles方法时将其作为参数传入

持有时作为字段,还是方法参数,区别不大,都可。

正常来说,会有个List<IBuildContext>,但这里被封装到一个类BuildContext中

 BuildContext buildContext = new BuildContext(contextObjects);

 List<IBuildTask>一般来说会在Pipeline中foreach顺序执行,这里将执行拿出来放在BuildTasksRunner中,这样做是为了自定义的Pipeline也能用同一个执行逻辑。

接下来的问题是如何传递数据:每个Task都有需要的初始化数据和处理完成的结果数据,如何获取初始化数据并将结果数据传递出去。

SBP用InjectContextAttribute特性简化每次手动取值赋值。

            foreach (IBuildTask task in pipeline){{try{if (!tracker.UpdateTaskUnchecked(task.GetType().Name.HumanReadable()))return ReturnCode.Canceled;ContextInjector.Inject(context, task);ReturnCode result;using (logger.ScopedStep(LogLevel.Info, task.GetType().Name))result = task.Run();if (result < ReturnCode.Success)return result;ContextInjector.Extract(context, task);}catch (Exception e){BuildLogger.LogError("Build Task {0} failed with exception:\n{1}\n{2}", task.GetType().Name, e.Message, e.StackTrace);return ReturnCode.Exception;}}}

通过ContextInjector.Inject(context, task)将初始化数据注入,通过ContextInjector.Extract(context, task)将数据取出。

为此,需要将List<IBuildContext>封装,用字典保存数据类及其实例

 public class BuildContext : IBuildContext{internal Dictionary<Type, IContextObject> m_ContextObjects;
}

【SBP的Task】

  • Setup 
    • SwitchToBuildPlatform 切换至目标平台
    • RebuildSpriteAtlasCache 重新构建图集
  • Player Scripts
    • BuildPlayerScripts 编译目标平台源代码
    • PostScriptsCallback 编译后处理回调
  • Dependency
    • CalculateSceneDependencyData 计算场景依赖数据
    • CalculateAssetDependencyData 计算资源依赖数据
    • AddHashToBundleNameTask 修改bundle名字为hash
    • StripUnusedSpriteSources 剔除Asset中被 SpritePacker 打包的Sprite的引用
    • CreateBuiltInShadersBundle 创建BuildIn 的Shader对应的Bundle
    • CreateMonoScriptBundle 创建脚本对应的bundle
    • PostDependencyCallback 依赖后处理回调
  •  Packing
    • GenerateBundlePacking 组装AssetBundle并计算依赖加载列表
    • GenerateBundleCommands 为AssetBundle生成写入参数
    • GenerateSubAssetPathMaps 向AssetBundle里插入扩展资源
    • GenerateBundleMaps 生成AssetBundle之间的依赖关系
    • PostPackingCallback 组装后处理
  • Writing
    • WriteSerializedFiles 生成序列化文件
    • ArchiveAndCompressBundles 构建和压缩Bundle
    • GenerateLocationListsTask 生成检索的Location
    • PostWritingCallback 写入后处理
  • Other
    • GenerateLinkXml 生成AssetBundle的link文件,用于代码裁剪
    • GenerateCatalog 生成Catalog文件

【参考】

【Unity】SBP - Scriptable Build Pipeline - 知乎

 

相关文章:

Unity构建详解(1)——SBP介绍

【前言】 Unity的资源工作流程分为导入、创建、构建、分发、加载。我们说的是其中的构建步骤。 构建是指将项目工程中的资源文件和代码整合程可执行文件的过程&#xff0c;构建的结果是生成可执行文件&#xff0c;在win平台上是exe&#xff0c;在Android平台上是apk&#xff…...

贪心算法(算法竞赛、蓝桥杯)--奶牛晒衣服

1、B站视频链接&#xff1a;A28 贪心算法 P1843 奶牛晒衣服_哔哩哔哩_bilibili 题目链接&#xff1a;奶牛晒衣服 - 洛谷 #include <bits/stdc.h> using namespace std; priority_queue<int> q;//用大根堆维护湿度的最大值 int n,a,b; int tim,maxn;int main(){s…...

Redis列表:高效消息通信与实时数据处理的利器

Redis是一个强大的开源内存数据库&#xff0c;被广泛应用于缓存、会话存储、队列等各种场景中。在Redis中&#xff0c;列表&#xff08;List&#xff09;是一种非常重要的数据结构&#xff0c;它提供了存储、获取、操作有序元素集合的功能。本文将深入探讨Redis列表的特性、使用…...

Redis中的缓存雪崩

缓存雪崩 &#x1f914;现象分析 缓存雪崩是指在同一时段大量的缓存key同时失效或者缓存服务(Redis等)宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 &#x1f44a; 解决方案 利用Redis集群提高服务的可用性&#xff0c;避免缓存服务宕机给缓存业务添…...

使用远程工具连接Mysql

&#xff08;若想要远程连接Mysql需要下面解决四个问题&#xff09; 1、目标地址 直接查询 2、端口号 3306 3、防火墙关闭 [rootlocalhost date]# systemctl stop firewalld.service 4、授权mysql数据库root用户权限&#xff08;因为mysql开始不允许其他IP访问&#xff0…...

2024不起眼的“致富”野路子,不想打工了,做做这些暴利创业项目。2024个人创业做什么项目好;最适合白手起家的创业项目

经济大环境差&#xff0c;并不代表就没有机会。相反&#xff0c;主流经济不好正是另一些人所看重的千载难逢的机会。就像股票市场一样&#xff0c;有人靠做多赚钱&#xff0c;有人靠做空赚钱。下面我们就来分析一下哪些行业会在这个时候崛起。 首先二手行业会迅速崛起&#xff…...

从后端获取文件数据并导出

导出文件的公共方法 export const download (res, tools) > {const { message, hide } tools;const fileReader: any new FileReader();console.log(fileReader-res>>>, res);fileReader.onload (e) > {if (res?.data?.type application/json) {try {co…...

哲♂学家带你深♂入了♂解结构体及结构体内存大小问题

目录 概要 一、结构体的声明 二、结构体变量的创建和初始化 三、结构体的特殊声明 四、结构体内存对齐 1、对齐原则 2、例一 对齐数 计算方法 3、例二 总结 概要 结构体是我们日常编程中经常要用到的一种自定义类型&#xff0c;使用起来也是十分的方便。接下来就由…...

基于SSM的土家风景文化管理平台(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的土家风景文化管理平台&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spri…...

2024年03月CCF-GESP编程能力等级认证C++编程一级真题解析

本文收录于专栏《C++等级认证CCF-GESP真题解析》,专栏总目录:点这里。订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 C++表达式 (3 - 2) * 3 + 5 的值是( )。 A. -13 B. 8 C. 2 D. 0 答案:B 第 2 题 C++语句 cout << “5%2=” <&l…...

[Linux]条件变量:实现线程同步(什么是条件变量、为什么需要条件变量,怎么使用条件变量(接口)、例子,代码演示(生产者消费者模式))

目录 一、条件变量 1.什么是条件变量 故事说明 2、为什么需要使用条件变量 竞态条件 3.什么是同步 饥饿问题 二、条件变量的接口 1.pthread_cond_t 2.初始化&#xff08;pthread_cond_init&#xff09; 3.销毁&#xff08;pthread_cond_destroy&#xff09; 4.等待&…...

从Java到json:探索 Jackson 的魔力

引言 Jackson简介 Jackson是一个用于处理JSON数据的开源Java库。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于计算机解析和生成。在Java领域,Jackson已经成为处理JSON数据的事实标准库。它提供了丰富的功能,包括将Java对象转…...

Docker之docker compose!!!!

一、概述 是 Docker 官方提供的一款开源工具&#xff0c;主要用于简化在单个主机上定义和运行多容器 Docker 应用的过程。它的核心作用是容器编排&#xff0c;使得开发者能够在一个统一的环境中以声明式的方式管理多容器应用的服务及其依赖关系。 也就是说Docker Compose是一个…...

shardingsphere+达梦+jpa项目改造适配中遇到的一些问题与解决

问题一&#xff1a;shardingsphere.dialect.exception.syntax.database.UnknownDatabaseException 解决&#xff1a; jdbcTemplate 类注入有问题&#xff0c;如&#xff1a; 1&#xff09;如果使用Resource注解引入该类时&#xff0c;变量名需要与初始化时Bean修饰的方法名相…...

YOLOV9训练自己的数据集

1.代码下载地址GitHub - WongKinYiu/yolov9: Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information 2.准备自己的数据集 这里数据集我以SAR数据集为例 具体的下载链接如下所示&#xff1a; 链接&#xff1a;https:/…...

UG NX二次开发(C++)-CAM-获取加工操作的四种方法

文章目录 1、前言2、采用选中工序导航器获取操作的Tag_t3、采用遍历对象的方法获取操作的Tag_t4、采用Collection遍历获取操作对象NXOpen::CAM::Operation5、采用FindObject获取操作对象NXOpen::CAM::Operation6、以上4种方法封装成类 Class CAMOperation6.1 CAMOperation.h文件…...

python共享单车信息系统的设计与实现flask-django-php-nodejs

课题主要分为二大模块&#xff1a;即管理员模块和用户模块&#xff0c;主要功能包括&#xff1a;用户、区域、共享单车、单车租赁、租赁归还、报修信息、检修信息等&#xff1b; 语言&#xff1a;Python 框架&#xff1a;django/flask 软件版本&#xff1a;python3.7.7 数据库…...

Python之Web开发中级教程----Django站点管理

Python之Web开发中级教程----Django站点管理 网站的开发分为两部分&#xff1a;内容发布和公共访问 内容发布是由网站的管理员负责查看、添加、修改、删除数据 Django能够根据定义的模型类自动地生成管理模块 使用Django的管理模块, 需要按照如下步骤操作 : 1.管理界面本地…...

Spring Boot项目中使用MyBatis连接达梦数据库6

在开发中&#xff0c;使用Spring Boot框架结合MyBatis来操作数据库是一种常见的做法。本篇博客将介绍如何在Spring Boot项目中配置MyBatis来连接达梦数据库6&#xff0c;并提供一个简单的示例供参考。(达梦六不仅分表还分模式.) 我拿SYSTEM表的LPS模式下面Student表做案例。 1.…...

Matlab快捷键与函数

注释&#xff1a;注释对于代码的重要性我们就不做过多的解释了。不做注释的代码不是好代码。选中要注释的语句&#xff0c;按快捷键CtrlR,或者在命令行窗口上面的注释地方可以进行注释。当然也可以直接在语句前面“%”就可以&#xff08;注意&#xff1a;一定要用英文符号&…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...