六一的部落格


行百里者半九十



在其他程序中, 在源码设置变量值, 实现函数, 做出调整时, 需要在源码中进行修改, 重新编译运行程序

而虚幻编辑器中, 在运行游戏之前, 我们可以设置原型和实例的属性值, 这个有点像是在gdb中修改变量值: 这是虚幻引擎通过宏实现的

在蓝图编辑器中, 做出相应修改, 除了要记得保存, 在使用之前还需点击compile进行编译


虚幻引擎的反射系统

虚幻引擎实现了反射系统, 在虚幻编辑器中运行游戏时, 能够追踪和修改数据结构和行为:

  1. 我们可以在运行时获取类型信息, 通过名字调用函数, 获取枚举元素的名字, 创建迭代器来遍历数据结构的所有字段, 以及获取其他信息
  2. 我们可以在创建实例之前, 把指定类型的指针传递给创建对象的类, 如world settings中, 指定关卡的基础类型
  3. 在实例的细节面板中设置属性:
    • 虚幻C++和蓝图的通信
    • 对象序列化
    • 在虚幻编辑器中的配置可以保存到磁盘
    • 垃圾(内存)回收机制也是基于反射系统

该系统加快了开发工程, 在多个领域中应用

纯C++开发的系统不具备上述功能, 这是游戏引擎的概念

我们可以编写纯C++代码来处理运算, 也可以在actor对象间传递计算结果


从虚幻编辑器创建C++类时使用了类模板

  1. 引擎提供了主要类的模板

    Engine/Content/Editor/Templates/

    templates文件, 或meta文件

  2. 拿ActorClass.cpp.template和ActorClass.h.template举例

    可以看到其中包含的变量

    对变量进行替换, 得到源码文件


编译项目时的头文件解析

  1. 为target解析头文件

  2. 运行unreal head tool程序, 该子例程既是解析器, 也是生成器, 负责处理源码中的宏

    UnrealHeadTool扫描头文件查看其是否包含后缀为.generated.h的头文件, 拥有该标记的头文件意味着其使用了虚幻引擎提供的特殊类型, 需要额外处理, 若无, 跳过

    uht会搜索UENUM, USTRUCT, UCLASS, UPROPERTY, UFUNCTION宏, 并生成反射系统所需的源码, 部分源码在后缀为.generated.h的头文件中

    • 类成员如果未使用宏, 不会出现在该文件中

    生成文件保存在TheBasics/Intermediate/Build/Mac/x86_64/UnrealEditor/Inc/TheBasics/UHT/目录下

    • 5.1的目录
    • 5.1之前在TheBasics/Intermediate/Build/Mac/x86_64/UnrealEditor/Inc/TheBasics/目录下

    生成文件的可读性很差

    注意到定义类时使用的xxx_API宏

    • 该宏被定义为DLLEXPORT, 而DLLEXPORT宏针对不同的平台有不同的定义
    • windows为 __declspec(dllexport), 即可从dll文件导出类

项目文件夹

  1. 需要保留的

    文件夹 说明
    Config 虚幻编辑器和游戏的项目设置
    Content 资产和蓝图
    Source 源码
    uproject文件 项目文件
  2. 可以删除的

    文件夹 说明
    Binaries 项目编译的生成文件
    DerivedDataCache 临时文件
    Intermediate 临时文件
    Saved 日志和备份
    工程文件

    Intermediate/ProjectFiles 包含使用的源码编辑器(VS)的项目文件


宏和项目中间文件


在其他程序中, 在源码设置变量值, 实现函数, 做出调整时, 需要在源码中进行修改, 重新编译运行程序

而虚幻编辑器中, 在运行游戏之前, 我们可以设置原型和实例的属性值, 这个有点像是在gdb中修改变量值: 这是虚幻引擎通过宏实现的

在蓝图编辑器中, 做出相应修改, 除了要记得保存, 在使用之前还需点击compile进行编译


虚幻引擎的反射系统

虚幻引擎实现了反射系统, 在虚幻编辑器中运行游戏时, 能够追踪和修改数据结构和行为:

  1. 我们可以在运行时获取类型信息, 通过名字调用函数, 获取枚举元素的名字, 创建迭代器来遍历数据结构的所有字段, 以及获取其他信息
  2. 我们可以在创建实例之前, 把指定类型的指针传递给创建对象的类, 如world settings中, 指定关卡的基础类型
  3. 在实例的细节面板中设置属性:
    • 虚幻C++和蓝图的通信
    • 对象序列化
    • 在虚幻编辑器中的配置可以保存到磁盘
    • 垃圾(内存)回收机制也是基于反射系统

该系统加快了开发工程, 在多个领域中应用

纯C++开发的系统不具备上述功能, 这是游戏引擎的概念

我们可以编写纯C++代码来处理运算, 也可以在actor对象间传递计算结果


从虚幻编辑器创建C++类时使用了类模板

  1. 引擎提供了主要类的模板

    Engine/Content/Editor/Templates/

    templates文件, 或meta文件

  2. 拿ActorClass.cpp.template和ActorClass.h.template举例

    可以看到其中包含的变量

    对变量进行替换, 得到源码文件


编译项目时的头文件解析

  1. 为target解析头文件

  2. 运行unreal head tool程序, 该子例程既是解析器, 也是生成器, 负责处理源码中的宏

    UnrealHeadTool扫描头文件查看其是否包含后缀为.generated.h的头文件, 拥有该标记的头文件意味着其使用了虚幻引擎提供的特殊类型, 需要额外处理, 若无, 跳过

    uht会搜索UENUM, USTRUCT, UCLASS, UPROPERTY, UFUNCTION宏, 并生成反射系统所需的源码, 部分源码在后缀为.generated.h的头文件中

    • 类成员如果未使用宏, 不会出现在该文件中

    生成文件保存在TheBasics/Intermediate/Build/Mac/x86_64/UnrealEditor/Inc/TheBasics/UHT/目录下

    • 5.1的目录
    • 5.1之前在TheBasics/Intermediate/Build/Mac/x86_64/UnrealEditor/Inc/TheBasics/目录下

    生成文件的可读性很差

    注意到定义类时使用的xxx_API宏

    • 该宏被定义为DLLEXPORT, 而DLLEXPORT宏针对不同的平台有不同的定义
    • windows为 __declspec(dllexport), 即可从dll文件导出类

项目文件夹

  1. 需要保留的

    文件夹 说明
    Config 虚幻编辑器和游戏的项目设置
    Content 资产和蓝图
    Source 源码
    uproject文件 项目文件
  2. 可以删除的

    文件夹 说明
    Binaries 项目编译的生成文件
    DerivedDataCache 临时文件
    Intermediate 临时文件
    Saved 日志和备份
    工程文件

    Intermediate/ProjectFiles 包含使用的源码编辑器(VS)的项目文件