UE3 BYTECODE执行简单概述
为什么要一开始就介绍UE的脚本,而不是学习它的类层次结构?就跟我们学习计算机原理要先学习其汇编语言,在学习指令大概是如何在CPU中执行一样,这是一个学习其原理的一个捷径,如果我们一开始就学习CPU模块构成,只会让我们摸不着头脑.UE3是个复杂的系统,代码太杂,理清楚需要一番工夫啊!
前面说过,UE3是一个完全基于脚本控制的引擎,更象个虚拟的游戏机,其脚本语言类似与JAVA,虚幻脚本(以下简称UnS)在语言层面支持了状态,时钟,事件,网络等游戏概念.在这篇短短的概述里我只能介绍下 UnS Bytecode 的执行流程, 对于Uns->Bytecode的编译过程就不叙述了.
编译后的UnS中的概念以相应C++类来呈现,比如Class对应到游戏中的UClass类,Function对应到UFunction类,State对应到UState类.而编译后的Bytecode保存在相关类的Script变量中,这个变量是一个TArray<Byte>类型.在脚本执行中有几个息息相关的数据结构:
UObject->里面定义了所有字节码对应的功能函数
FFrame->脚本执行堆栈和字节码执行指针
GNative->保存了字节码与对应功能实现的联系
Event->脚本执行的调用入口
引擎的运作是基于事件驱动的,事件由UE内部组织和管理,当事件被触发,UE会调用相关对象的event Method.比如:触发了一个时间事件Tick,那么相关对象的eventTick()方法就会被引擎调用,在eventTick中有一个函数ProcessEvent(FindFunctionChecked(ENGINE_Tick),&Parms); FindFunctionChecked会根据ENGINE_Tick这个枚举值,现在对象域中寻找对应的UFunction(前面说过UFUNCTION就是UnS中的Function),如果没有找到,则会到全局域中寻找.找到后会将这个UFunction对象返回给ProcessEvent.ProcessEvent会设置FFrame的相关参数,比如Bytecode指针等,然后读取UFunction Script变量中的字节码,通过GNative找到对象中相对应的C++方法,然后执行,参数传递通过FFrame来完成,这样就完成了一次脚本执行.
其实UnS执行同LUA很象,内部有一个基于堆栈的虚拟机实现,对字节码进行解释执行,关于虚拟机详细信息请参考 LUA实现,<编译原理>,<游戏脚本高级编程>.