【UE5】虚幻引擎的运行逻辑

UE5的运行逻辑可以分为引擎启动流程游戏运行流程两个部分。

引擎启动流程

一、平台入口&引擎主流程初始化

1、系统入口

不同的平台会有不同的入口。在Windows平台,入口是Launch模块下的\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp文件中的WinMain()函数。

2、FEngineLoop初始化

FEngineLoop是整个引擎运行控制器,生命周期管理器。

FEngineLoop::PreInit()

作用:用于早期设置,引擎模块初始化。

  • 解析命令行
  • 加载config文件(DefaultEngine.ini等)
  • 初始化日志系统(GLog)
  • 创建GIsEditor或GIsGameAgnosticExe标志
  • 加载平台相关信息(平台模块)
FEngineLoop::Init()

作用:用于引擎的主要子系统初始化。

  • 加载各个模块(ModuleManager)
  • 创建并初始化UGameEngine或UEditorEngine
  • 初始化RHI(渲染硬件接口)和Rendering System
  • 加载默认地图或启动器地图
  • 创建GameInstance,启动游戏或进入编辑器

二、模块加载系统:FModuleManager

UE使用FMoudleManager统一控制管理动态模块加载,常见模块有:

  • Core
  • CoreUObject
  • Engine
  • InputCore
  • RenderCore
  • RHI
  • Renderer
  • Slate
  • UMG
  • MyGameModule(用户创建的项目模块)
cpp 复制代码
FModuleManager::Get().LoadModuleChecked<ISlateRHIRendererModule>("SlateRHIRenderer");
FModuleManager::Get().LoadModule(TEXT("Renderer"));

三、创建&初始化UGameEngine

在游戏模式下,会构造UGameEngine,并调用其Init():

cpp 复制代码
//\Engine\Source\Runtime\Launch\PrivateLaunchEngineLoop.cpp

GEngine = NewObject<UEngine>(GetTransientPackage(), EngineClass);
check(GEngine);

GEngine->ParseCommandline();

UE_LOG(LogInit, Log, TEXT("Initializing Game Engine..."));
GEngine->Init(this);
UE_LOG(LogInit, Log, TEXT("Initializing Game Engine Completed"));

内部做了:

  • 加载GameViewportClient
  • 创建UWorld,并加载初始地图
  • 初始化Audio、Physics、Navigation、Streaming、Scene、AI、Input等子系统。

四、世界和地图加载:UWorld创建

UEngine::LoadMap()中会:

  • 创建UWorld(每个地图一个世界)
  • 创建GameModeBase,GameState,PlayerController
  • 加载Level、Actors、components等内容
  • 初始化Navigation、Lightmaps、Landscape、AI、Streaming等系统

五、初始化关键对象

  • UGameInstance:游戏生命周期管理器(全局)
  • AGameModeBase:地图规则控制器(服务器端)
  • AGameStateBase:同步游戏状态(客户端可见)
  • APlayerController:玩家输入管理器
  • APawn/ACharacter:玩家可操控角色

六、Editor与Game的分支流程

|-------|---------------|---------|---------------------------------------|
| 类型 | 对应Engine类 | 初始化地图 | 特殊流程 |
| 编辑器运行 | UEditorEngine | 启动编辑器地图 | 创建FEditorViewportClient,运行SlateEditor |
| 游戏运行 | UGameEngine | 加载默认地图 | 创建GameInstance,运行主循环 |

七、Tick启动,进入主循环

cpp 复制代码
FEngineLoop::Tick();

启动主循环,每帧调用:

  • 输入处理
  • Tick世界(UWorld)
  • AI、动画、物理等更新
  • 提交渲染数据,开启RenderThread
  • Slate/UMG UI更新

游戏运行流程

未完待续