版权声明:本文为CSDN博主「Papals」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
UE4 在 4.25 中,进行了一些非常重要的改进。 其中就有 FProperty 。
一. 老旧的结构体系
UE4 中带有前缀 U 的类是 UObject 派生类。每个 UObject 都有一个与之对应的 UClass,
- 这个
UClass保存了所有的反射系统相关的信息,描述了各个 Property 之间的内存布局和关系; - 通过
UClass可以遍历所有的序列化 Property; - 通过 Object 对象的实例化地址就可以将相应的 Property 的值取出来,进行读写操作。
UClass 保留了这个对象的结构信息。它在内部拥有成员的元素列表,例如 UFunction,UEnum,UProperty 等。它们一起作用来提供 “反射” 机制。从命名不难看出 UClass 和下文中的 UProperty,都是从 UObject 继承而来,主要是为了使用 Object 的 GC 功能。
UProperty 将变量定义为类的组成部分。这也是我们这次的重点内容。
不管我们是在蓝图中还是在 C++ 中,属性都是由我们的 UProperty 来指定的。这些属性包括 蓝图变量 和 节点 ,以及 执行节点的返回值 。
二. 反射
我们将 C++ 编译成 exe 文件。编译器将 C++ 中的信息翻译成了机器语言。我们本身的函数名称在编译时将会被替换和省略。因此你不能在自己的程序中使用字符串 "HogeHogeFunc" 来处理任何事情。反射是静态或者动态的去构造这一映射信息,并且在运行时使用他们。UE4 是静态反射的。
在 UE4 中,我们在通过他特殊的宏,将所需要反射的数据进行标记,从而自动的生成供运行时查询的信息。
从而其生成了一些额外的信息。
三. 反射案例
四. FProperty
在创建类时,会生成大量属性,包括蓝图类。有些类型将可能有几十万多个 UProperty,因为所有的 UProperty 继承自 UObject,因此会产生各种各样的开销。这一特性对整个引擎影响及其广泛,包括额外的内存空间,UProperty 构建/销毁成本,垃圾回收性能。
从 4.25 开始,此 UProperty 已完全更改为 FProperty。 前缀 “F” 说明其不再继承UObject。UProperty 类的定义仍然存在,但它只用于在将早期版本中创建的资源转换为FProperty 做一次。
这是 4.24 的继承关系。
这是 4.25 的继承关系
由于 Field 与 UObject 和 UField 大多数函数拥有相同的名称,因此当您更新引擎时,只需将其从 UxxProperty 重命名为 FxxProperty 即可。
五. 改善点
内存消耗减少
在整个应用程序中使用的 UObject 中内存占用中,Property 占 40% 以上,根据情况也有超过 60% 的程度。特别是在包含多个函数调用的蓝图很多的情况下。在 ThirdPersonTemplate 中, UE 4.24 的 UObject 合计有 5 万多个,其中 70% 左右是 Property 。这些消耗直接没了。
由于继承了 UObject,因此每个属性不再需要超过 100 个字节的额外内存。 虽然每个容量都是微乎其微的,但由于数量众多,有时会减少数十 MB 或更多的内存使用量。
使用宏调用 8 个 BoolProperty 返回值的函数 2304 次。
如前所述,由于不适用 NewObject 而是 C++ 的 New 和 Delete,因此生成和销毁特性也变得简单和快速。同样,您还可以缩短应用程序的启动时间。
六. 结论
4.25 UProperty 变成了 FProperty
- 继承
UObject后的开销不见了 - 提高了引擎启动时间
- GC 处理时间明显改善
- 内存使用量的减少
- 打包后包体体积减少