模块、插件与构建系统
Modules, Plugins & Build System
UE 的代码由模块 (Module) 组成:每个模块是一个独立编译单元,用 [模块名].Build.cs 声明依赖。插件 (Plugin) 是可按项目启用/禁用的代码与内容集合,用 .uplugin 描述,可包含多个模块。虚幻构建工具 (UnrealBuildTool, UBT) 根据 .Target.cs 和 .Build.cs(而不是 IDE 的 .sln)编译,默认把模块编成 DLL 由一个可执行文件加载,也可整体链接成单体 (Monolithic) 可执行文件。
三层结构
下图表示目标、模块与插件之间的关系:目标决定构建什么,模块通过 Build.cs 形成依赖图,插件和项目各自携带模块。
flowchart TD T["MyProject.Target.cs<br/>TargetRules:Game / Client / Server / Editor / Program"] --> UBT["UBT"] UP[".uproject<br/>启用插件、列出模块"] --> UBT UBT --> M1["主游戏模块<br/>MyProject.Build.cs"] M1 -->|"Public/PrivateDependencyModuleNames"| M2["自定义游戏模块"] M1 --> PL["插件 .uplugin"] PL --> PM1["Runtime 模块"] PL --> PM2["Editor 模块"] M1 --> EM["引擎模块:Core、Engine、Slate……"] UBT -->|"UHT 生成反射代码"| UHT["UHT"]
模块
好处
- 强制代码隔离,封装并隐藏内部实现;
- 单独编译,只有改动的模块需要重编,大项目编译显著加快;
- 依赖图 + “包含你所用 (Include What You Use, IWYU)”原则,项目没用到的模块会被排除在编译之外(UBT 只编译依赖链上的模块);
- 可控制运行时加载/卸载;可按平台等条件包含或排除。
注意:UE 模块与 C++20 模块无关。
目录结构
Source/
MyModule/
MyModule.Build.cs
Public/ 公共头文件(依赖本模块的其他模块可见)
Private/ 所有 .cpp 与私有头文件,包括 MyModuleModule.cpp
Public/Private 文件夹与 C++ 的访问说明符无关,只控制对其他模块的可见性。位于依赖链末端的主游戏模块可以不用这两个文件夹。在 Public 中建子文件夹时,Private 中应建同名对应文件夹。
Build.cs 与依赖
using UnrealBuildTool;
public class MyModule : ModuleRules
{
public MyModule(ReadOnlyTargetRules Target) : base(Target)
{
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine" });
PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
}
}
| 列表 | 何时用 |
|---|---|
PublicDependencyModuleNames | 依赖模块的类型出现在本模块的公共头文件中,依赖本模块的模块也要能包含 |
PrivateDependencyModuleNames | 只在 .cpp 中使用。优先使用私有依赖以缩短编译时间;在头文件中用前置声明可把很多依赖改成私有 |
模块实现:在 Private/[模块名]Module.cpp 中写 IMPLEMENT_MODULE(FDefaultModuleImpl, MyModule);。需要启动/关闭逻辑时,自定义继承 IModuleInterface 的类。要把类导出给其他模块,类声明需加 MYMODULE_API 宏,见 UObject 与反射系统。
加载控制:.uproject/.uplugin 的 Modules 列表:
"Modules": [ { "Name": "MyModule", "Type": "Runtime", "LoadingPhase": "Default" } ]
- 最常用的类型:
Runtime(游戏内类)、Editor(仅编辑器类)。 LoadingPhase默认Default;插件有时要更早加载,若编辑器常报找不到插件中的 C++ 类,可试PreDefault。- 可按平台(Win64、Mac、Linux、Android、IOS 等)、目标(Game、Server、Client、Editor、Program)、配置(Debug、DebugGame、Development、Shipping、Test)设置包含/排除列表。
- 同一加载阶段内模块加载顺序不确定;需要保证顺序时,在 C++ 中用
LoadModule/LoadModuleChecked,可能不存在的模块用GetModule。
插件
- 位置:引擎插件在
Engine/Plugins/,对所有项目可用;项目插件在[项目]/Plugins/。可在 Plugins 下按子目录组织,但已找到的插件目录内部不会再扫描。 - 结构:
Source(一个或多个模块)、Binaries、Intermediate、可选Content(需"CanContainContent": true)、Config、Resources/Icon128.png(128×128)。 - 含
Source的插件会被加入生成的 IDE 工程并随项目自动编译;没有 Source 的插件不进工程,但只要有二进制仍会加载。 - 插件可声明自己的反射类型,构建系统会为其生成代码。
.uplugin 描述文件(JSON):FileVersion 是唯一必填字段(当前为 3);布尔字段名去掉开头的 b(bEnabledByDefault → EnabledByDefault)。每个模块条目必须有 Name 和 Type:
| 模块类型 | 何时加载 |
|---|---|
Runtime | 所有情况,包括发行版游戏 |
RuntimeNoCommandlet | Runtime 的变体(文档未展开说明) |
Developer | 只在开发版运行时或编辑器构建中,绝不进 Shipping |
Editor / EditorNoCommandlet | 只在编辑器启动时 |
Program | 独立程序 |
典型做法:一个插件分成 Runtime 模块(游戏功能)和 Editor 模块(编辑器工具),避免编辑器代码进入发行包。
依赖层级规则:插件与模块分层,只能依赖同层或更高层——项目模块可以依赖引擎模块,引擎模块不能依赖项目模块,因为引擎必须能脱离任何项目独立构建。项目在 .uproject 中启用插件,插件在自己的 .uplugin 中启用其他插件。
UBT 与构建目标
- UBT 管理多种构建配置下的编译;构建不依赖 IDE 工程文件。新增/移动源文件或修改 Build.cs 后,需重新生成工程文件(
GenerateProjectFiles.bat、右键 .uproject 选择 Generate Project Files,或编辑器 File > Refresh Visual Studio Project)。 - 目标类型:Game(需要烘焙数据的独立游戏)、Client(不含服务器代码)、Server(不含客户端代码,用于专用服务器)、Editor、Program。
.Target.cs放在项目根目录,类继承TargetRules且命名为“文件名 + Target”,如MyProjectTarget。
| 常用 TargetRules 属性 | 作用 |
|---|---|
Type | 目标类型 |
LinkType | 单体还是模块化链接 |
ExtraModuleNames | 额外编进目标的模块 |
EnablePlugins / DisablePlugins | 为该目标启用/禁用插件 |
bUseUnityBuild | 把 C++ 文件合并成大文件(Unity 构建)以加快编译 |
bUseAdaptiveUnityBuild | 把正在修改的文件排除出 Unity 合并,加快增量编译(Perforce 看只读标志,Git 用 git status) |
bWithLiveCoding / bAllowHotReload | 支持实时编码 (Live Coding) / 热重载 |
DefaultBuildSettings | 保持与某引擎版本兼容的默认构建设置;设为 Latest 升级时可能引入编译错误 |
取舍与常见坑
- 模块拆得越细,增量编译越快、边界越清晰;但依赖图更复杂,公共头文件和导出宏要管理好。
- 滥用 Public 依赖会让依赖向上传染,拖慢全局编译。
bAdaptiveUnityCompilesHeaderFiles会为工作集中的每个头文件单独生成源文件,用来检测头文件中缺失的#include。- 插件的 Config 文件当前不会随项目打包,需要手动复制到项目
Config目录。 - 在 IDE 里改工程设置无效,UBT 只认 Build.cs / Target.cs。
出处
- Unreal Engine Modules UE 5.8 文档
- Plugins UE 5.8 文档
- UnrealBuildTool (UBT) & Targets UE 5.8 文档
- Objects in Unreal Engine UE 5.8 文档