UE4模块启动顺序
前言
本文大致梳理一下UE4编辑器启动后各个模块的加载顺序, 重点看一下ELoadingPhase
枚举对应的类型的加载时机
入口
任何可执行程序都会有一个执行入口,在 UE 中,每一个 Target 都会编译出一个可执行程序。引擎启动是从 Launch
模块开始的,main
函数也是定义在其中的
简化代码表示
1 | int32 GuardedMain( const TCHAR* CmdLine ) |
从代码的字面意思就可以理解为启动步骤大概就是 预初始化->初始化, 然后是Tick循环
这里不得不说到一个引擎类 FEngineLoop
FEngineLoop
管理了程序的初始化与主循环
因为整个UE是模块化的架构,引擎的实现就是靠各个模块组合驱动的, 那么就拿模块的启动来看一下引擎的启动顺序
模块启动
先看一下模块加载的类型
1 | namespace ELoadingPhase |
先看一下PreDefault
模式的插件到StartupModule
的调用栈
先看下面代码
1 | bool FEngineLoop::LoadStartupModules() |
上面是几种类型加载模式的模块启动都在编辑器引擎启动之前, 意味着UEditorEngine::InitEditor()
还未执行.
那么其他类型比如常见的PostEngineInit
是啥时候启动的呢?
在FEngineLoop::Init()
中, 先执行了GEditor
的初始化, 然后再执行PostEngineInit
类型的模块的加载
1 | { |
总结
简单梳理各类模块加载的顺序,以及部分常见的功能的初始化顺序
- 多种平台调用
GuardedMain() //Launch.cpp
GuardedMain
依次调用EnginePreInit
,EditorInit
或EngineInit
, 然后循环EngineTick
Launch.cpp
内有全局变量FEngineLoop GEngineLoop;
, 上述方法通过GEngineLoop
执行- GEngineLoop
FEngineLoop::PreInit
会执行PreInitPreStartupScreen
,PreInitPostStartupScreen
- 前者会执行如命令行, 本地化等等大量初始化和逻辑, 先通过
FEngineLoop::AppInit
加载*EarliestPossible
和PostConfigInit
类型的模块, 随后加载*PostSplashScreen
类型的模块 (0%-18%), 退出函数时加载至39%** - 后者加载*
PreEarlyLoadingScreen
*类型的模块(39%); 随后播放开场动画等, 然后加载AssetRegistry
模块, 然后通过LoadStartupCoreModules
(45% - 55%)方法加载核心模块, 随后是*PreLoadingScreen
*类型的模块(55% - 59%), 接着开始渲染线程StartRenderingThread
(59% - 75%), 然后通过LoadStartupModules
(75%)方法加载*PreDefault
,Default
,PostDefault
*类型的模块, - 随后创建几个单例并调用
Init
(%79 - 86%)- 创建
GEditor
并调用GEditorEngine::InitEditor
, 该方法会加载编辑器资源 - 创建
GEngine
并调用GEngine::Init
, 该方法也有大量初始化比如创建FWorldContext
,Config
的加载, 音效设备的初始化, 加载一些系统模块(MovieScene
,LevelSequence
等等)
- 创建
- 前者会执行如命令行, 本地化等等大量初始化和逻辑, 先通过
- 然后通过执行
FEngineLoop::Init
加载*PostEngineInit
*类型的模块(86% - 90%)
补充
加载核心模块在 45%进度,
EarliestPossible
,PostConfigInit
,PostSplashScreen
和PreEarlyLoadingScreen
会在此之前核心模块有
Core
,Networking
,UnrealEd
,Slate
等等编辑器资源初始化在75%之后, 也就是在
PreLoadingScreen
,PreDefault
,Default
,PostDefault
之后, 所以如果需要对资源进行操作需要使用最后加载的PostEngineInit
另外, 引擎提供了几个全局代理, 可以来监听比如编辑器初始化完毕等事件 , 比如
1 | FCoreDelegates::OnPostEngineInit.AddRaw(this, &FAdvancedFrameworkEditorModule::RegisterPlaceActors); |
详情可以参考文件CoreDelegates.h