概述
UE4的对象系统可以说是整个引擎的核心模块,其在引擎中的地位如下图:
该对象系统具有很强的扩展性,新增的类只需要从UObject类继承下来就可以融入到对象系统中。
对象系统具有如下几个特性:
- 反射对象属性和方法
- 对象的序列化
- 垃圾回收
- 创建和查找对象
- 通过配置文件设置对象的默认属性
- 网络支持(Replication和RPC)
C++语言本身不支持上述功能,为了实现上述功能,引擎定义了对象基类UObject, UObject类和其子孙类分别拥有一个UClass实例, UClass实例作为对象类的元数据(meta data),描述了类的反射信息和其它编辑器需要的信息。
Unreal Reflection System:
Each class that derives from UObject has a singleton UClass created for it that contains all of the meta data about the class instance. UObject and UClass together are at the root of everything that a gameplay object does during its lifetime. The best way to think of the difference between a UClass and a UObject is that the UClass describes what an instance of a UObject will look like, what properties are available for serialization, networking, etc.
整个对象系统,跟UE3比较起来变化不大。Blueprint对应UE3中的uc脚本系统和Kismet。 UE3通过在uc中定义一些uc class属性,通过uc编译器进行生成C++头文件;UE4通过在C++的头文件中的类定义中加入些宏(确切地说是空宏),让UnrealHeaderTool对.h文件进行预处理,产生一些C++ .h,.cpp文件,这些代码充当胶水层,将C++ Class加入Reflection功能。
注:UE3中的Kismet也是一个通过可视化连线达到编程目的,但是谈不上一个语言,其连接结点由C++代码实现;Blueprint集成了uc脚本和Kismet的功能,既能可视化编程又能够后端生成uc虚拟机字节码执行(也可以生成其它语言),所以Blueprint又叫Kismet2(这也许就是引擎Blueprint的接口有K2前缀的原因)。
对象的名字空间
与UE3类似,在对象系统中,每个对象有唯一的路径名和类型(路径名相同但类型不同是允许的)。这点应该是学习Java的包命名方式吧。
举个例子:
上图中FirstPerson_Run资源的全路径名为:
AnimSequence'/Game/FirstPerson/Animations/FirstPerson_Run.FirstPerson_Run'。
- AnimSequence 是资源对象类名
- /Game/FirstPerson/Animations/ 是资源所在的路径(游戏项目的Content目录下的FirstPerson/Animations目录)
- FirstPerson_Run.FirstPerson_Run 第一个FirstPerson_Run是包名(加载到内存后对应一个UPackage实例, 每个uasset文件对应为一个包,第二个FirstPerson_Run是动画序列对象的名字,它的类型是AnimSequece。在虚幻中把第一个FirstPerson_Run对象称为第二个FirstPerson_Run对象的Outer。
通过类型和路径名就可以精确找到该对象。
注:在UE3中是对象名字空间是不带有资源所在路径这一因素的。
行程安排
代码模块:
- RunTime\UObjectCore 对象系统
- RunTime\Core 封装平台相关代码和算法
后续对象系统系列文章将从如下几个方面进行着手:
- 对象的类描述,主要通过UClass类来实现。
- 与UClass的相关概念
- UClass实例的创建
- 分析一个由UnrealHeaderTool生成的反射代码
- 对象的创建流程和查找
- 对象的序列化, 文件格式,Linker
- 垃圾回收流程和机制
- Blueprint的原理 和 VM
a. Blueprint的可视化描述
b. 字节码生成
c. VM的执行 - 模块机制,如何实现hot-reload
- 对象的Replication(Network)
使用UE4开发应用必须要了解对象系统(特别是1-5点),在开发中会碰到有的同学创建的对象被莫名其妙地回收了,导致系统崩溃。究其原因就是没有了解对象系统是如何利用UClass提供的信息来进行GC的,在定义C++类时是否需要给成员变量加UPROPERTY宏犯迷糊。