引擎启动流程

自动关联目录:引擎启动流程

1. 定位

知道引擎怎么起来,才能判断"启动时卡在哪一步"——启动慢、启动崩溃、编辑器与打包行为不同,都落在这条链上。

一句话定位:启动流程的关键分界是"引擎可用"与"世界存在"——很多代码放错位置,就是没分清这两步。

2. 粗略阶段

① 平台入口(main / WinMain)
      ↓
② 引擎预初始化(PreInit):加载核心模块、配置、平台层
      ↓
③ 引擎初始化(Init):RHI、渲染模块、各子系统
      ↓
④ 创建 GameInstance / World
      ↓
⑤ 加载地图(LoadMap)→ 初始化 GameMode / GameState
      ↓
⑥ BeginPlay → 开始 Tick
阶段能做什么
PreInit加载配置与核心模块,还没有 RHI
Init渲染、音频等子系统就绪
LoadMapWorld 与 Actor 创建
BeginPlay游戏逻辑起点

3. 模块加载

UE 的启动大量依赖模块系统(见 模块与 Subsystem):

阶段说明
LoadingPhase模块声明自己的加载阶段(PreDefault / Default / PostDefault 等)
StartupModule模块初始化入口
ShutdownModule清理

模块加载顺序由 LoadingPhase 决定,依赖错了会在启动时崩("还没起来就用了")。

4. 与各类对象的关系

对象在哪个阶段说明
Engine(GEngine)Init全局引擎对象
UGameInstance创建 World 前跨关卡存活
UWorldLoadMap世界
AGameModeBaseLoadMap 后仅服务端(见 Framwork)
APlayerController玩家登录
Subsystem各自生命周期见 模块与 Subsystem

Subsystem 的生命周期各不相同(Engine / Editor / GameInstance / World / LocalPlayer),选错会导致"数据跨关卡丢失"或"一直不释放"。

5. 启动性能

阶段耗时常见原因
模块加载模块数量多
着色器编译 / DDC见 材质与着色器编译、Cook 与 DDC 基础设施
PSO 预缓存见 PSO 预缓存
资产加载见 资源加载
关卡初始化Actor 数量、构造脚本

"启动慢"通常不是引擎本身,而是着色器/PSO/资产加载这三项。

6. 打包版与编辑器的差异

差异说明
编辑器有额外模块启动更慢、行为不同
打包版无编辑器数据某些编辑器专用查询失效(见 资产注册表)
Cook 后的资产格式与体积不同
命令行参数如 -clearPSODriverCache、-corelimit 只在测试时用

性能与启动问题必须测打包版本(见 性能方法论)。

7. 代价与权衡

设计收益代价什么时候不该用
早期加载模块后续可用启动变慢只在必要时用
延迟加载启动快首次使用时卡顿高频使用的不适合
启动屏等待 PSO消除进场卡顿启动时间变长见 PSO 篇
全量预加载资产后续无卡顿启动慢、内存高应改为流式

8. 踩坑与排查

坑现象怎么验证
在模块构造里用还没初始化的系统启动崩调整 LoadingPhase
启动脚本依赖 World崩(World 还不存在)移到 LoadMap 之后
在构造函数里访问 World不可用移到 BeginPlay(见 UObject)
Subsystem 生命周期选错数据跨关卡丢失见 Subsystem 篇
启动慢只怪引擎判断错拆分计时:模块/着色器/PSO/资产
只测编辑器打包版不同测打包版本
模块循环依赖启动失败见 模块与 Subsystem

9. 排查顺序

1. 启动崩?→ 崩溃栈在哪个阶段 → 是否用了尚未初始化的系统
2. 启动慢?→ 分段计时(模块 / 着色器 / PSO / 资产 / 关卡)
      ├─ 着色器 → DDC 是否命中
      ├─ PSO   → 是否预缓存
      └─ 资产  → 是否该改流式
3. 编辑器与打包差异?→ 编辑器模块 / 编辑器专用数据 / 命令行参数
4. 数据跨关卡丢失?→ Subsystem 与 GameInstance 的选择

参考