中EN
概念页

模块、插件与构建系统

Modules, Plugins & Build System

更新于 2026-10-11 约 10 分钟UE5模块插件UBTBuild.csuplugin构建系统

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所有情况,包括发行版游戏
RuntimeNoCommandletRuntime 的变体(文档未展开说明)
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。
  1. Unreal Engine Modules UE 5.8 文档
  2. Plugins UE 5.8 文档
  3. UnrealBuildTool (UBT) & Targets UE 5.8 文档
  4. Objects in Unreal Engine UE 5.8 文档

相关页面

游戏开发 · UE5UObject 与反射系统UObject & Reflection System虚幻引擎 (Unreal Engine) 的对象基类是 UObject。在 C++ 类、属性、函数上加 UCLASS/UPROPERTY/UFUNCTION 等宏,再由构建前的预处理工具虚幻头文件工具 (Unreal Header Tool, UHT) 扫描头文件生成代码,引擎就能在运行时“看见”这些类型——这就是反射系统 (Reflection System)。垃圾回收、序列化、编辑器面板、蓝图、网络复制都建立在它之上。游戏开发 · UE5蓝图与 C++ 协作Blueprint & C++ InteropEpic 官方建议:多数项目混用蓝图 (Blueprint) 与 C++,以 C++ 作为基础、在其上构建蓝图类。C++ 适合“编程”——定义系统;蓝图适合“脚本”——在已有系统上定义具体行为。两者通过反射说明符互相调用:C++ 用 BlueprintCallable/BlueprintReadWrite 等暴露给蓝图,用 BlueprintImplementableEvent/BlueprintNativeEvent 让蓝图实现或覆盖 C++ 声明的函数。游戏开发多线程渲染与任务系统Multithreaded Rendering & Task SystemsCPU 时钟频率约在 2003 年停在 3.4 GHz 附近后,性能来自多核。应用阶段的优化一是让代码与内存访问更缓存友好,二是利用多核:多处理器流水线(时间并行,提高吞吐但增加延迟)、并行处理(空间并行,延迟更低)以及两者结合的任务系统;图形 API 用命令缓冲让多个线程并行录制绘制命令,新一代 API(DirectX 12、Vulkan、Metal)把更多责任交给应用以降低驱动开销。游戏开发 · UE5资产管理与异步加载Asset Management & Async LoadingUE 资产默认按引用自动加载:硬引用 (Hard Reference) 会让被引用资产随引用者一起加载,不加控制就可能在启动时加载全部内容。软引用 (Soft Reference,TSoftObjectPtr/FSoftObjectPath) 只存路径,配合流式管理器 (Streamable Manager) 异步按需加载;资产管理器 (Asset Manager) 进一步把内容划分为主资产 (Primary Asset) 和次资产 (Secondary Asset),用资产包 (Asset Bundle) 管理加载、卸载、烘焙分块与内存审计。游戏开发 · UE5UE5 渲染架构UE5 Rendering ArchitectureUE5 的渲染器是独立的 Renderer 模块,在渲染线程 (Rendering Thread) 上以「场景代理」镜像游戏线程的组件状态,每帧按固定顺序执行深度预通道、G-buffer 基础通道、光照、雾、半透明和后处理。现代渲染代码用渲染依赖图 (Render Dependency Graph, RDG) 声明通道与资源,由 RDG 自动排屏障、复用瞬态内存、并行录制;最终命令经 RHI 线程翻译成 D3D12/Vulkan 等图形 API 调用。默认走延迟着色 (Deferred Shading),也可切换前向着色 (Forward Shading)。游戏开发 · UE5Gameplay 标签深入Gameplay Tags In DepthGameplay 标签 (Gameplay Tags) 是用 . 分层的用户定义标签,必须登记到标签字典(项目设置 .ini、数据表或 C++ 原生标签宏)。对象用 FGameplayTagContainer 持有多个标签并以 HasTag/HasAny/HasAll 判断(注意空集合语义),复杂条件用 FGameplayTagQuery 的叶/根表达式组合并配置在资产里。它是 GAS、AI 和各类玩法状态的通用词汇表;大项目可限制标签编辑权限,并用 IGameplayTagAssetInterface 免 Cast 取标签。游戏开发 · UE5子系统Subsystems子系统 (Subsystem) 是自动实例化、生命周期绑定在宿主对象上的类:Engine、Editor、GameInstance、World、LocalPlayer 五种。宿主创建时自动创建并 Initialize(),宿主关闭时 Deinitialize(),之后无引用即被 GC。它替代了「继承 GameInstance 塞管理器」的老做法,自带按类型的蓝图节点和 Python 访问,特别适合插件。官方编程页只列四种,World 子系统依据 5.8 Python API 补充。游戏开发 · UE5Game Features 与模块化玩法Game Features & Modular GameplayGame Features 与 Modular Gameplay 两个插件让开发者把一个玩法功能做成独立的插件,可以单独启用或停用。功能本身由一个 GameFeatureData 资产里的 Action 列表描述,最常用的是 Add Components:把插件里的组件按需挂到已有的 Actor 类上。这样主工程的代码保持干净,无关功能之间不会意外产生依赖,对需要长期增减功能的线上产品尤其重要。游戏开发 · UE5配置文件系统Configuration FilesUE 的 .ini 配置按类别(Engine、Game、Input……)分层加载:从引擎 Base 文件到项目 Default 文件,再到平台文件和用户文件,后加载的同名键覆盖先加载的。数组可以用 +、-、! 等运算符跨层增删。UCLASS(config=X) 加上 UPROPERTY(Config) 可以让类的默认值从 ini 自动读取;命令行 -ini: 可以临时覆盖。游戏开发 · UE5专用服务器Dedicated ServerUE 多人游戏采用客户端-服务器模型。监听服务器 (listen server) 由某个玩家的客户端兼任服务器;专用服务器 (dedicated server) 无头运行,不渲染画面,也没有本地玩家。专用服务器体积更小、房主没有不公平优势、能专注于玩法逻辑,适合大规模或竞技游戏。构建专用服务器需要源码版引擎和支持客户端-服务器的 C++ 项目,并要有 <ProjectServer.Target.cs。游戏开发 · UE5烘焙、打包与 Zen 加载器Cooking, Packaging & Zen Loader打包是一组构建操作:编译 (Build) → 烘焙 (Cook,把资产转成目标平台格式) → 暂存 (Stage) → 打包 (Package) → 可选的部署 (Deploy)。UE5 的运行时加载器 Zen Loader 会在暂存阶段离线算好包与对象的依赖图,并把数据装进 .utoc/.ucas 容器(IoStore),由 I/O 分发器以很低的 CPU 开销定位数据块;.pak 只用于不常访问的零散文件。游戏开发 · UE5Live Coding 实时编译Live CodingLive Coding 集成了 Live++,在引擎运行时重新编译 C++ 并给二进制打补丁;它比旧的 Hot Reload 快得多、也更灵活,新安装默认启用,快捷键 Ctrl+Alt+F11。默认开启的「对象重实例化 (Object Reinstancing)」会替换掉现有的 UCLASS/USTRUCT 等对象实例,从而支持新增函数、变量这类结构性修改;关闭它时只适合小改动,大改通常会崩溃。坑:在 .cpp 构造函数里改的默认值不会作用到已存在的实例。游戏开发 · UE5编辑器扩展与 Python 脚本Editor Extension & Python Scripting扩展 UE 编辑器有三条主要路线,门槛由低到高:Python 脚本(只在编辑器中可用,适合批量处理资产和串联外部 DCC 管线)、Editor Utility Widget(基于 UMG 的蓝图编辑器界面,做成自定义标签页),以及 C++ 编辑器插件(如 Editor Standalone Window 模板,用 Slate 的声明式语法构建窗口)。游戏开发 · UE5在线子系统与 EOSOnline Subsystem & EOSOnline Subsystem (OSS) 是 UE 访问 Steam、Xbox Live、Epic 等在线服务的统一抽象:按功能分成身份 (Identity)、会话 (Session)、好友、成就等接口,所有远程操作都是异步的,用委托回调。UE 5.1 起新增了 Online Services 插件(5.8 中仍为 Beta),返回 TOnlineAsyncOpHandle 句柄。Epic Online Services 通过 OSS EOS 插件接入;在 Steam 等其他平台发行时,可以再叠加 EOS Plus 插件。游戏开发构建配置与编译优化Build Configurations & Compiler OptimizationC++ 游戏代码从源文件到可执行文件要经过预处理、编译、链接。游戏项目通常不止 Debug/Release 两种构建配置 (build configuration),而是 Debug、Development、Ship,有时再加混合构建;配置越多测试越难。编译器优化分为局部优化和全局优化(链接时优化 LTO、剖析引导优化 PGO),它们让程序更快,但也让调试器“说谎”。所以要学会调试优化过的构建,并用统计式或插桩式性能分析器 (profiler) 找出最耗时的代码。游戏开发 · UE5Gameplay 能力系统Gameplay Ability SystemGameplay 能力系统 (Gameplay Ability System, GAS) 是 UE 用来构建「Actor 可拥有并反复触发的能力」的框架:能力系统组件 (Ability System Component, ASC) 是持有者,Gameplay 能力 (Gameplay Ability) 编排执行过程,属性集 (Attribute Set) 存数值,Gameplay 效果 (Gameplay Effect, GE) 改数值和标签,Gameplay 标签 (Gameplay Tags) 做状态与互斥,Gameplay Cue 负责表现。它内建复制与客户端预测,代价是概念多、上手重,游戏开发 · UE5网络复制与 RPCNetwork Replication & RPCUE 采用服务器权威 (Server-Authoritative) 的客户端-服务器模型:游戏真正在服务器上进行,服务器把状态复制 (Replication) 给客户端,客户端通过远程过程调用 (Remote Procedure Call, RPC) 向服务器请求操作。开发者需要显式声明哪些 Actor、属性、函数要走网络,并借助所有权、网络角色、相关性、优先级控制“发给谁、发多少”。UE 5.8 提供通用复制系统、Replication Graph 和实验性的 Iris 三套复制系统。

被这些页面引用1 篇

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原