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, 然后循环EngineTickLaunch.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