引擎启动流程
自动关联目录:引擎启动流程
1. 定位
知道引擎怎么起来,才能判断"启动时卡在哪一步"——启动慢、启动崩溃、编辑器与打包行为不同,都落在这条链上。
一句话定位:启动流程的关键分界是"引擎可用"与"世界存在"——很多代码放错位置,就是没分清这两步。
2. 粗略阶段
① 平台入口(main / WinMain)
↓
② 引擎预初始化(PreInit):加载核心模块、配置、平台层
↓
③ 引擎初始化(Init):RHI、渲染模块、各子系统
↓
④ 创建 GameInstance / World
↓
⑤ 加载地图(LoadMap)→ 初始化 GameMode / GameState
↓
⑥ BeginPlay → 开始 Tick| 阶段 | 能做什么 |
|---|---|
| PreInit | 加载配置与核心模块,还没有 RHI |
| Init | 渲染、音频等子系统就绪 |
| LoadMap | World 与 Actor 创建 |
| BeginPlay | 游戏逻辑起点 |
3. 模块加载
UE 的启动大量依赖模块系统(见 模块与 Subsystem):
| 阶段 | 说明 |
|---|---|
LoadingPhase | 模块声明自己的加载阶段(PreDefault / Default / PostDefault 等) |
StartupModule | 模块初始化入口 |
ShutdownModule | 清理 |
模块加载顺序由 LoadingPhase 决定,依赖错了会在启动时崩("还没起来就用了")。
4. 与各类对象的关系
| 对象 | 在哪个阶段 | 说明 |
|---|---|---|
Engine(GEngine) | Init | 全局引擎对象 |
UGameInstance | 创建 World 前 | 跨关卡存活 |
UWorld | LoadMap | 世界 |
AGameModeBase | LoadMap 后 | 仅服务端(见 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 的选择参考
许可协议:CC BY
作者:Davids
本文链接:https://hustjjd.github.io/23abf105.html
更新于:2026年10月10日