Unreal3(以下简称U3)是一个以脚本为主体的游戏引擎,所有代码几乎都为脚本服务,意味着所有源码都会提供相应的脚本函数在脚本中使用。
UObject是U3中很重要的一个基类,所有由UObject派生的类都可以导出到脚本中(不从UObject派生行不行?不知道呢),但我对U3的脚本不熟。暂且从C++角度来分析下UObject是如何实现的。
UObject顾名思义是一个“基本对象”,材质、mesh、文件、玩家等等都是从这个UObject继承而来,这个类做了很多事情:
1、属性的统一访问接口,脚本中就可以通过这个接口来访问属性了;
2、成员函数的统一访问接口,脚本中可以通过这些接口来调用UObject或其派生类的成员函数;
3、串行化的统一接口,实现了一个保存所有对象的UPackage包管理器,从而做到保存到二进制文件、从二进制文件读取,这样做的好处是持久化对象(比如游戏中的材质列表)的载入非常快速,由于是二进制格式,不需要任何字符串数据转换;
4、提供对象的垃圾回收功能;
5、提供编辑器的相应功能,如:对象的“属性”有各种编辑器所需的标记(是否可编辑CPF_Edit等)、对象在编辑器中的渲染DrawThumbnail、对象描述GetThumbnailDesc、对象选择IsSelected、是否更改了包MarkPackageDirty等等;
6、提供一个对象的管理器,这个对象管理器是通过UObject中的一堆静态函数来实现的,如:从管理器中查找一个对象StaticFindObject、分配一个对象StaticAllocateObject、从包中载入一个对象StaticLoadObject、根据类型来遍历管理器中的所有对象FObjectIterator/TObjectIterator、遍历所有选择了的对象TSelectedObjectIterator(编辑器使用)
7、提供配置管理器,通过UObject中的LoadConfig、SaveConfig实现
8、提供类描述信息,描述了这个类从哪个类派生、有什么属性、每个属性的访问方式、有什么函数,从而实现了动态类型判断、脚本属性访问、脚本函数访问、属性串行化等等
9、其他。。。。
简单分析下UObject中的各个成员变量的意义:
Index,用来记录这个UObject在所有UObject列表GObjObjects中的唯一索引
HashNext,用来记录全局UObject Hash表GObjHash中跟这个UObject 的Hash值相同的下一个UObject的指针,用来配合全局Hash表GObjHash通过StaticFindObject函数快速搜索一个指定名称的UObject
StateFrame,脚本相关的咚咚,还没看
_Linker,通过在包文件中载入时的载入器
_LinkerIndex,通过包文件载入时的UPackage包对象在GObjObjects中的唯一索引,相当于Outer->Index
Outer,这个对象所属的包
ObjectFlags,这个对象的一些标记,具体参见EObjectFlags枚举,不同标记来决定这个对象的一些行为,比如是否可以保存、是否可见等等
Name,对象名称,通过一个FName来实现,这个FName可是个好东西哦,字符串比较变成了一个Hash值比较
Class,用来描述这个类,就是以上第1、2、8点说到的。这个Class在调用UObject::StaticClass或派生类的StaticClass静态函数时会一次性初始化,意味着即使创建多少个UObject,但Class只会有一个实例,我们通过这个类,可以使用TFieldIterator的统一方式来遍历这个类的所有属性、函数。
UObject的静态变量,这些静态变量其实就是UObject对象管理器使用的变量,如果用Ogre的设计方法来做,就相当于另外一个class UObjectManager : public Singleton<UObjectManager>,然后在里面把这些静态变量拿到UObjectManager中去。简要分析下静态变量的意义:
GObjInitialized,对象管理器是否已经初始化,全局对象管理器只需要初始化一次就够了;
GObjNoRegister,调用StaticInit时会设置成1;
GObjBeginLoadCount,有多少个对象被BeginLoad了;
GObjRegisterCount,ProcessRegistrants中使用
GImportCount,还没细看哦
GObjHash,通过每个UObject的Name的Hash值取低12位作为索引值保存在GObjHash表中,Hash值的低12位相同的,只记录第一个在GObjHash表中,其他的通过链表方式使用UObject的HashNext来链接起来
GAutoRegister,自动注册的对象列表
GObjRoot,对象树种的顶层对象
GObjObjects,所有对象的列表
先说这么多了,继续学习。