UBT(虚幻编译工具(UnrealBuildTool))和UHT虚幻头工具(UnrealHeaderTool)
UE有一组用于自动执行编译虚幻引擎过程的工具,包括 UBT和UHT(以及其他工具)。实现这一套工具的目的是为了简化多平台编译,方便你配置各个平台的参数和编译选项
UBT:
- 编译每个模块,并处理相关依赖。负责管理通过各种编译配置来编译虚幻引擎源代码的过程
- 该工具处理所有复杂的项目编译工作,编译UE的逐个模块并处理依赖等。我们编写的Target.cs,Build.cs都是为这个工具服务的。 并将项目与引擎关联起来。该过程以透明方式进行,这样,您只需通过标准的Visual Studio 构建工作流程构建项目即可。
.Bulid.cs 文件
每个模块环境的依赖信息,项目包括的各种模块(一般添加组件时,需要添加模块,才能通过编译)
.Target.cs 文件
目的或者特定平台的一些设置,包括库,头文件,编译器等信息
UHT:
- 负责处理引擎反射系统编译所必需的信息,是支持UObject系统的自定义解析和代码生成工具
代码编译分两个阶段进行:
调用UHT。它将解析C++头文件中引擎相关类元数据,并生成自定义代码,以实现诸多UObject相关的功能。
调用普通C++编译器,以便对结果进行编译。- 收集头文件,编译生成反射数据,这些反射数据存储在 .generated.h或者
.generated.cpp中,当头文件发生改变时,通过UHT生成新的发射数据
完整编译流程:
UBT搜集目录中的.cs文件,然后UBT调用UHT分析需要分析的.h .cpp文件(根据文件是否含有#include、"FileName.generated.h",是否有UCLASS()、UPROPERTY等宏)生成generated.h和generated.cpp文件,生成的文件路径为 Intermediate->Build-Win64-UE4-Inc,最后UBT调用MSBuild,将.h.cpp和generated.h gen.cpp结合到一起然后编译。
UBT通过扫描头文件,记录所有包含反射类型的modules(模块),当其中有头文件改变时,就会用UHT更新反射数据。UHT解析头文件,扫描标记,生成用于支持反射的C++代码。编译时,两个工具皆有可能出现错误,必须仔细检查。
反射
描述运行时得到类型的功能,通过类型信息反过来创建对象,读取修改属性,调用方法的功能行为
- 反射用于在是在程序运行时动态加载类以及获取类的信息,反射数据描述了类在运行时的内容
- 这些数据所存储的信息包括类的名称、类中的数据成员、每个数据成员的类型、每个成员位于对象内存映像的偏移(offset),此外,它也包含类的所有成员函数信息。
作用
- 实现序列化
- 实现editor的details panel
- 垃圾回收
- 网络复制
- 蓝图/C++通信和相互调用
UObject是反射系统的核心。每一个继承UObject且支持反射系统的类型都有一个相应的UClass,或者它的子类,UClass中包含了该类的描述信息。UObject与UClass也组成了UE4对象系统的基石
实现
需要在文件顶部添加一个特殊的include文件,该文件必须放在#include的最后,这让UHT
检索到。
#include 文件名.generated.h"
你现在可以使用UENUM()、UCLASS()、USTRUCT()、UFUNCTION()、以及UPROPERTY()来在头文件中注解不同的类型以及成员变量。每一个宏都会出现在类型或者成员变量的前面,并且可以包含额外的修饰符关键字。
GENERATED_BODY()在需要反射的类或结构体里面是必要的,且必须被放置在类体的最前方,它们会被替换成额外的函数和typedef。
反射实现机制简要说明
Unreal Build Tool(UBT)和Unreal Header Tool (UHT)两个协同工作来生成运行时反射需要的数据。UBT属性通过扫描头文件,记录任何至少有一个反射类型的头文件的模块。如果其中任意一个头文件从上一次编译起发生了变化,那么 UHT就会被调用来利用和更新反射数据。UHT分析头文件,创建一系列反射数据,并且生成包含反射数据的C++代码(放到每一个模块的moulde.generated.inl中。注:最新版会生成到moudle.generated.cpp中),还有各种帮助函数以及thunk函数(每一个 头文件 .generated.h)