UE蓝图 编译过程详解

系列文章目录

UE蓝图 Get节点和源码
UE蓝图 Set节点和源码
UE蓝图 Cast节点和源码
UE蓝图 分支(Branch)节点和源码
UE蓝图 入口(FunctionEntry)节点和源码
UE蓝图 返回结果(FunctionResult)节点和源码
UE蓝图 函数调用(CallFunction)节点和源码
UE蓝图 序列(Sequence)节点和源码
UE蓝图 宏(Macro)节点和源码
UE蓝图 编译过程详解


文章目录

  • 系列文章目录
  • 一、蓝图编译器
  • 二、术语
  • 三、编译过程
      • 1、清理类
      • 2、创建类属性
      • 3、创建函数列表
        • 3.1 处理事件图表
        • 3.2 处理函数图表
        • 3.3 预编译函数
      • 4、绑定和链接类
      • 5、编译函数
      • 6、后编译函数
      • 7、完成编译类
      • 8、复制类默认对象属性
      • 9、重新实例化
  • 总结


一、蓝图编译器

蓝图编译器是一种用于编译UE蓝图的可视化脚本系统的编译器。 其主要作用是将蓝图资源的属性和图转换成类,以便在运行时使用。

当在蓝图编辑器中按下编译按钮时,编译器会将蓝图资源的属性和图转换成类。这个过程中,会生成一个新的实例,存储需要编译类的引用和蓝图等信息。同时,编译器还会处理函数信息的编译,包括相关图的引用、属性以及生成的UFunction。

在编译过程中,编译器会将节点转换成一系列的语句,然后编译器后端会将这些节点翻译成字节码操作。例如,变量赋值、无条件跳转(goto)和调用(call)等操作。

二、术语

FKismetCompilerContext
执行编译工作的类。系统为每次编译生成一个新实例。存储对正在编译的类、蓝图等的引用。

FKismetFunctionContext
保存用于编译单个函数的信息,例如对关联图表、属性和生成的UFunction的引用。

FNodeHandlingFunctor
一个辅助工具类,用于处理编译器中的一个节点类(单件)。包含用于注册引脚连接和生成编译语句的函数。

FKismetCompiledStatement
编译器中的工作单元。编译器将节点转换为一组已编译语句,后端将这些语句转换为字节码操作。

FKismetTerm
图中的终端(文字、常量或变量引用)。每个数据引脚连接都与其中一个终端关联!您还可以在"NodeHandlingFunctor"中为Scratch变量、中间结果等创建自己的术语。

三、编译过程

在这里插入图片描述

1、清理类

类是实时编译的,这意味着相同的 UBlueprintGeneratedClass 会被一次又一次地清理和重用, 因此指向类的指针不必固定。CleanAndSanitizeClass() 将属性和函数从类中移到临时包中的垃圾类中, 然后清除类中的任何数据。

2、创建类属性

编译器在蓝图的 新变量(NewVariables) 阵列以及其他一些地方(构造脚本等)上进行迭代, 以查找类所需的所有UProperty,然后在 函数 CreateClassVariablesFromBlueprint() 中创建UClass作用域上的UProperty。

3、创建函数列表

编译器通过处理事件图表,处理函数图表和_预编译_函数(即为每个上下文调用 PrecompileFunction()) 来为类创建函数列表。

3.1 处理事件图表

事件图表的处理由 CreateAndProcessUberGraph() 函数执行。此 函数将所有事件图表复制到一个大图表中,在此之后,节点将获得机会而展开。然后, 此函数为图表中的每个事件节点创建一个函数存根,并为每个事件图表创建一个 FKismetFunctionContext。

3.2 处理函数图表

常规函数图表的处理是通过ProcessOneFunctionGraph()函数来完成的,它会把图中的每一个节点拷贝到另外一个节点中去,这个时候调用expansionStep展开每个节点(expandNode),最后会为每一个函数创建一个FKismetFunctionContext,添加到functionList中。

3.3 预编译函数

函数的预编译由每个上下文的 PrecompileFunction() 处理。此函数执行 以下操作:

  • 计划执行并计算数据依赖性。

  • 删除任何计划外的或不是数据依赖项的节点。

  • 在每个剩余节点上运行节点处理器的 RegisterNets()。

  • 此操作将为函数内的值创建 FKismetTerms。

  • 创建 UFunction 和关联属性。

4、绑定和链接类

现在编译器已经了解类的所有UProperty和UFunction,因此它可以绑定和链接该类, 这包括填充属性链、属性大小、函数图等。此时,从本质上看,它具有一个类标头 -减去最终的标记和元数据 - 以及一个类默认对象(CDO)。

5、编译函数

下一步是为剩余的节点生成 FKismetCompiledStatment 对象, 此操作使用 AppendStatementForNode() 通过节点处理器的 Compile() 函数完成。此 函数可以在编译函数中创建 FKismetTerm 对象,但前提是这些对象仅在本地使用。

6、后编译函数

PostCompileFunction()是编译函数的最后一个阶段,在所有函数调用了CompileFunction()之后调用,蓝图编译器会对Statements进行简单的优化,由FKismetFunctionContext::ResolveStatements()函数实现。该函数对linearExecutionList进行排序,链接goto,并合并相邻的语句。

  • finalSortLinearExecList
    按照可能的执行顺序再次对“线性执行列表”进行排序;列表中应该只包含执行节点。
  • ResolveGotoFixups
    链接goto,如果执行Flow Stack不是必需的,那么使用GotoReturn代替EndOfThread。 EndOfThread弹出Flow Stack,GotoReturn无需处理。
  • mergeAdjacentStates
    合并相邻的语句

7、完成编译类

为了完成编译类,编译器将确定类标记,并从父类传播标记和元数据, 最后执行一些最终检查,以确保编译过程中一切正常。

后端发出生成的代码
后端将每个函数上下文中的语句集合转换为代码。有两个后端 在使用:

FKismetCompilerVMBackend - 将FKCS转换为UnrealScript VM字节码,然后将其序列化为函数的脚本阵列。引擎运行时会读取字节码,并交由蓝图虚拟机动态解释执行。

FKismetCppBackend - 发出_类似C++_的代码,仅用于调试用途。自动生成的C++代码与我们自己写的有些差异,其行数会特别多,执行流程都用switch-case进行实现,因此执行效率会稍低些,而且可读性不友好。

8、复制类默认对象属性

编译器使用一个特殊的函数 CopyPropertiesForUnrelatedObjects() 将类的旧CDO中的值 复制到新CDO中。属性通过标记序列化复制, 因此只要名称一致,它们就应当会被正确地传输。在此阶段, CDO的组件将被重新实例化并进行适当的修复。操作时以GeneratedClass CDO为准。

9、重新实例化

由于类可能已经更改了大小,且属性可能已经过添加或删除, 因此编译器需要用刚编译的类重新实例化所有对象。这个过程使用 TObjectIterator 查找类的所有实例, 生成一个新实例,然后使用 CopyPropertiesForUnrelatedObjects() 函数 将旧实例复制到新实例。

总结

更详细信息请下载UE蓝图编译过程详解,基于UE4源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/419239.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BUUUCTF---LSB1

1.题目描述(提示lsb) 2.下载附件是一张图片 3.在010编辑器中查看没有发现什么信息,再看属性也没有什么有用的信息,根据题目提示lsb想到用Stegsolve这个工具 4.在该工具中打开图片 5.先将红绿蓝三种颜色的通道设置成0,…

如何使用Potplayer远程访问本地群晖NAS搭建的WebDAV中的本地资源

文章目录 本教程解决的问题是:按照本教程方法操作后,达到的效果是:1 使用环境要求:2 配置webdav3 测试局域网使用potplayer访问webdav3 内网穿透,映射至公网4 使用固定地址在potplayer访问webdav ​ 国内流媒体平台的内…

Spring八股 常见面试题

什么是Spring Bean 简单来说,Bean 代指的就是那些被 IoC 容器所管理的对象。我们需要告诉 IoC 容器帮助我们管理哪些对象,这个是通过配置元数据来定义的。配置元数据可以是 XML 文件、注解或者 Java 配置类。 将一个类声明为 Bean 的注解有哪些? Com…

什么是虚拟DOM,有什么作用?有了解过diff算法吗?

虚拟DOM(Virtual DOM): 虚拟DOM是一个轻量级的JavaScript对象,它是真实DOM(Document Object Model)的抽象表示。开发者通过操作这个JavaScript对象来描述视图层的状态,当这个状态发生变化时&…

STL容器之vector类

文章目录 STL容器之vector类1、vector的介绍2、vector的使用2.1、vector的常见构造2.2、vector的iterator的使用2.3、vector空间增长问题2.4、vector的增删查改2.5、vector迭代器失效问题 3.vector的模拟实现 STL容器之vector类 1、vector的介绍 vector是表示可变大小数组的序…

常用网络协议的学习

TCP/IP TCP/IP的定义 TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/互联网协议)是互联网的基本协议,也是国际互联网络的基础。 TCP/IP 不是指一个协议,也不是 TCP 和 IP 这两个协议的合称…

天津廉租房如何申请取得廉租住房租房补贴资格

如何申请廉租住房租赁补贴资格? 低收入住房困难家庭应当向户籍所在地街道办事处(乡镇人民政府)提出申请。 申请时,您需要提供以下要求的原件和复印件: (一)您及家人的身份证件; &a…

海外代理IP干货:应该选择SOCKS55代理还是Http代理?

在使用IPFoxy全球代理时,选择 SOCKS55代理还是HTTP代理?IPFoxy代理可以SOCKS55、Http协议自主切换,但要怎么选择?为解决这个问题,得充分了解两种代理的工作原理和配置情况。 在这篇文章中,我们会简要介绍 …

每日一类:Qt GUI开发的基石《QWidget》

深入探索QWidget:Qt GUI开发的基石 在Qt框架中,QWidget类扮演着构建图形用户界面(GUI)的基础角色。它不仅提供了窗口的基本功能,还允许开发者通过继承和定制来创建各式各样的用户界面元素。本文将详细介绍QWidget的关…

低功耗运放D722,具有9MHz的高增益带宽积,转换速率为8.5V/μs

D722是低噪声、低电压、低功耗运放,应用广泛。D722具有9MHz的高增益带宽积,转换速率为8.5V/μs,静态电流为1.7mA(5V电源电压)。D722具有低电压、低噪声的特点,并提供轨到轨输出能力,D722的最大输…

vue实现自定义树形穿梭框功能

需求: 我们在开发过程中,会遇到需要将一个数据选择做成穿梭框,但是要求穿梭框左侧为树形结构、右侧为无层级结构的数据展示,ElementUI自身无法在穿梭框中添加树形结构,网上搜到了大佬封装的插件但是对于右侧的无树形结…

Go字符串实战操作大全!

目录 1. 引言文章结构概览 2. Go字符串基础字符串的定义与特性什么是字符串?Go字符串的不可变性原则 字符串的数据结构Go字符串的内部表达byte和rune的简介 3. 字符串操作与应用3.1 操作与应用字符串连接字符串切片字符串查找字符串比较字符串的替换字符串的大小写转…

androidapp开发工具,Android MVP模式详解

**工欲善其事必先利其器,要想拿到满意的offer,必须有一定的准备。**以下列出来的东西是笔者认为应该准备的东西 简历中提到的,一定要有准备,别给自己挖坑Java准备,Java基础,有的公司会扣的很细&#xff0c…

自动驾驶技术详解

🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:自动驾驶技术 🎀CSDN主页 发狂的小花 🌄人生秘诀:学习的本质就是极致重复! 目录 一 自动驾驶视觉感知算法 1目标检测 1.1 两阶…

挑战30天学完Python:Day28 数据库Mysql

🎉 本系列为Python基础学习,原稿来源于 30-Days-Of-Python 英文项目,大奇主要是对其本地化翻译、逐条验证和补充,想通过30天完成正儿八经的系统化实践。此系列适合零基础同学,或仅了解Python一点知识,但又没…

Dsco Dropship EDI需求分析

供应商要想从Dsco处通过EDI获取订单,需要部署自己的EDI系统,与Dsco的EDI供应商CommerceHub 建立连接,分为两个方向: 1.从CommerceHub 的 Dsco 平台获取 EDI 850 采购订单 2.向Dsco发送库存(846)、订单状态…

中仕公考:2024年安徽省直事业单位发布公告

2024年度安徽省直事业单位统一招聘发布公告,具体考试时间如下: 报名时间:2024年3月5日9.00-3月11日18.00 缴费时间:2024年3月13日18.00前 打印准考证时间:2024年3月27日-3月29日 笔试时间:2024年3月30日…

实现前端开发几个常用技巧

如何知道iframe下载完成 定时器轮询监听readyState的状态,如果是 complete 或者 interactive 说明文件加载完成。 常用的全屏居中 JS 函数 JS实现deepCopy 生成星级评分 JS数组扁平化之简单方法实现 toString 优点:简单,方便,对…

大势智慧黄先锋:现实世界数字重建 拥抱AI 擘画自主可控的三维画卷

来源:中国地理信息产业协会 实景三维涉及到大面积、高精度的地理空间信息数据,然而早期国内99%以上的实景三维数据制作测绘单位都基于国外软件进行三维重建,如此重要的工作大量使用国外软件,如何确保国家地理空间信息的安全&#…

MAC M1 安装mongodb7.0.5 版本

1、进入官网 Download MongoDB Community Server | MongoDBDownload MongoDB Community Server non-relational database to take your next big project to a higher level!https://www.mongodb.com/try/download/community 2、选择版本 3、下载后解压 放到 /usr/local 并修改…