1. 为什么我不再用 Rider 和 Visual Studio 写 UE5 项目
先说结论:UE5 项目用 VS Code 开发,不是"能不能"的问题,而是"怎么配才不折腾"的问题。我从 UE4.26 时代就开始尝试把 UE 的开发环境从 Visual Studio 迁移到 VS Code,中间踩过的坑包括 IntelliSense 疯狂报红、编译任务找不到 UBT、调试器附加不上、Live Coding 控制台没输出等等。到现在 UE5.3 之后的版本,这套流程已经相当稳定了,日常写 C++ 和蓝图混合项目完全够用。
这篇文章面向三类人:一是机器配置一般、开 Visual Studio 就卡到怀疑人生的开发者;二是习惯了 VS Code 生态、不想为了 UE 单独切换编辑器的人;三是想搞清楚 UE5 构建系统底层逻辑、不想被 IDE 黑盒绑架的人。我会从环境准备、插件选型、编译任务配置、调试器接入、常见报错排查几个维度,把整套流程拆开讲清楚,每一步都告诉你为什么这么做,而不是丢一堆配置文件让你抄。
需要提前说明的是,UE5 的 C++ 开发本质上依赖的是UnrealBuildTool(UBT)和UnrealHeaderTool(UHT)这套命令行工具链,IDE 只是外壳。Visual Studio 之所以"开箱即用",是因为 Epic 官方给它写了专门的插件(Visual Studio Tools for Unreal Engine)来对接这套工具链。VS Code 没有官方插件,所以我们需要手动把 UBT 的编译任务、调试器的启动参数、IntelliSense 的包含路径这三件事配好。理解了这一点,后面所有配置就都顺理成章了。
2. 环境准备与工具链梳理
2.1 前置依赖清单
在动手配 VS Code 之前,有几样东西必须先装好,否则后面会各种报错。我把它们列成表格,方便你对照检查:
| 组件 | 版本要求 | 作用 | 备注 |
|---|---|---|---|
| Unreal Engine 5 | 5.1 及以上 | 引擎本体 | 建议 5.3+,构建系统更稳定 |
| Visual Studio 2022 | 社区版即可 | 提供 MSVC 编译器和 Windows SDK | 必须装"使用 C++ 的游戏开发"工作负载 |
| VS Code | 最新稳定版 | 代码编辑器 | 建议 1.85+ |
| .NET SDK | 6.0 或 8.0 | UBT 运行依赖 | UE5.3 之后用 .NET 6 |
| Windows SDK | 10.0.18362 以上 | 编译 Windows 平台目标 | 装 VS 时勾选 |
这里有个很多人忽略的点:即使你完全不用 Visual Studio 写代码,也必须装它。原因是 UE5 的 UBT 在 Windows 平台下默认调用 MSVC 的编译器(cl.exe)和链接器,而这些工具链是随 Visual Studio 一起安装的。你可以不打开 VS,但不能不装它。我见过有人为了"纯净环境"只装 Build Tools,结果 UBT 找不到工具链报Unable to find a valid Visual Studio installation,折腾半天。
提示:安装 Visual Studio 时,工作负载只勾"使用 C++ 的游戏开发"就够了,单个组件里确保勾上"Windows 10/11 SDK"和"MSVC v143 生成工具"。不需要勾 .NET 桌面开发那些,省几个 G 空间。
2.2 VS Code 必装扩展
扩展不在多,在于精准。UE5 C++ 开发我实际用下来,这几个是刚需:
- C/C++(Microsoft 官方):提供 IntelliSense、调试器(cppvsdbg)、代码导航。这是核心,没有它 VS Code 就是个记事本。
- C/C++ Extension Pack:包含 CMake Tools 等,虽然 UE 不用 CMake,但里面的一些辅助工具挺方便。
- Unreal Engine 4/5 Snippets:提供 UPROPERTY、UFUNCTION 等宏的代码片段,写反射标记时省事。
- EditorConfig for VS Code:统一代码风格,UE 官方有 .editorconfig 文件,装上能自动对齐缩进。
- GitLens:UE 项目文件多,看 git blame 和提交历史很有用。
至于网上热传的什么 AI 代码补全插件,我个人建议在 UE 项目里谨慎使用。UE 的宏和模板代码(比如GENERATED_BODY()、TSubclassOf<>)比较特殊,很多补全工具会给出错误建议,反而干扰。等你把基础环境跑通了再考虑加。
2.3 生成项目文件:一切的起点
UE5 项目在 VS Code 里能正常工作的前提,是项目目录下存在.vscode文件夹和正确的编译数据库。而这两样东西,都需要通过 UBT 生成。
操作路径是这样的:在 Epic Games Launcher 里找到你的引擎版本,点引擎右侧的下拉菜单,选择"选项",确认勾选了"引擎源码"(如果你要调试引擎代码的话)。然后对你的.uproject文件右键,选择Generate Visual Studio project files。这一步会调用 UBT 生成.sln和.vcxproj文件。
很多人会问:我不用 VS,为什么还要生成 VS 项目文件?因为 UBT 生成的这些文件里包含了完整的编译配置信息,VS Code 的 C/C++ 扩展可以通过读取这些信息来构建 IntelliSense 数据库。换句话说,.vcxproj是 UBT 和 VS Code 之间的桥梁。
生成完成后,你会在项目根目录看到YourProject.sln、Intermediate/ProjectFiles/等目录。接下来打开 VS Code,用"打开文件夹"的方式打开项目根目录(注意是根目录,不是 .sln 文件)。
3. 核心配置:让 IntelliSense 不再报红
3.1 c_cpp_properties.json 的正确写法
IntelliSense 报红是新手最崩溃的问题。满屏红波浪线,但项目明明能编译通过。根本原因是 VS Code 的 C/C++ 扩展不知道 UE 的头文件在哪、不知道那些宏是什么意思。
解决办法是在.vscode/c_cpp_properties.json里配置包含路径和宏定义。但 UE 项目的包含路径动辄上百条,手写不现实。这里有个技巧:直接从 UBT 生成的 .vcxproj 文件里提取。
我实际用的配置长这样:
{ "configurations": [ { "name": "Win64", "includePath": [ "${workspaceFolder}/Source/**", "${workspaceFolder}/Intermediate/**", "C:/Program Files/Epic Games/UE_5.3/Engine/Source/**", "C:/Program Files/Epic Games/UE_5.3/Engine/Intermediate/**" ], "defines": [ "UNICODE", "_UNICODE", "__UNREAL__", "PLATFORM_WINDOWS=1", "WITH_EDITOR=1", "UE_BUILD_DEVELOPMENT=1" ], "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.38.33130/bin/Hostx64/x64/cl.exe", "cStandard": "c17", "cppStandard": "c++20", "intelliSenseMode": "windows-msvc-x64", "compileCommands": "${workspaceFolder}/.vscode/compile_commands.json" } ], "version": 4 }关键点在于compileCommands这一项。如果你能生成compile_commands.json,C/C++ 扩展会优先用它,比手动配 includePath 精准得多。生成方法后面讲。
defines里的宏也很重要。__UNREAL__让一些条件编译代码走对分支,WITH_EDITOR=1决定编辑器相关代码是否参与 IntelliSense 分析。少了这些,很多引擎头文件会解析失败。
3.2 用 compile_commands.json 提升精度
compile_commands.json是 Clang 工具链的标准编译数据库格式,记录了每个源文件的完整编译命令。UE5 从 5.0 开始支持通过 UBT 生成这个文件。
命令是这样的(在项目根目录执行):
"C:\Program Files\Epic Games\UE_5.3\Engine\Build\BatchFiles\Build.bat" YourProjectEditor Win64 Development -Project="C:\Path\To\YourProject.uproject" -WaitMutex -FromMsBuild -compdb -compdbformat=json执行完后,compile_commands.json会生成在Intermediate/目录下。把它复制到.vscode/目录,然后在c_cpp_properties.json里指向它。
注意:这个命令每次改动了模块依赖(比如在 .Build.cs 里加了新模块)后都要重新跑一遍,否则 IntelliSense 会漏掉新模块的头文件路径。我一般把它写成一个 .bat 脚本,改完 Build.cs 就双击跑一下。
3.3 处理 UE 宏导致的误报
即使配好了包含路径,UE 的一些宏还是会让 IntelliSense 犯迷糊。最典型的是UPROPERTY()、UFUNCTION()、GENERATED_BODY()这些反射宏。C/C++ 扩展不认识它们,会把它们当成未定义的标识符。
解决办法是在defines里加一个__INTELLISENSE__宏,然后在代码里用条件编译绕过。不过更省事的做法是:接受这些误报。因为 UHT(UnrealHeaderTool)会在编译前处理这些宏,实际编译是没问题的。你只需要在 VS Code 设置里把错误波浪线的显示级别调低,或者用// NOLINT注释临时压制。
我个人的经验是,配好compile_commands.json之后,90% 的误报都会消失,剩下的基本就是反射宏相关的,习惯就好。
4. 编译任务:把 UBT 接进 VS Code
4.1 tasks.json 配置编译任务
VS Code 的编译任务通过.vscode/tasks.json定义。UE 项目的编译本质就是调用 UBT,所以任务配置就是把 UBT 的命令行封装一下。
我的配置如下:
{ "version": "2.0.0", "tasks": [ { "label": "Build Editor (Development)", "type": "shell", "command": "C:/Program Files/Epic Games/UE_5.3/Engine/Build/BatchFiles/Build.bat", "args": [ "YourProjectEditor", "Win64", "Development", "-Project=${workspaceFolder}/YourProject.uproject", "-WaitMutex", "-FromMsBuild" ], "group": { "kind": "build", "isDefault": true }, "problemMatcher": "$msCompile", "presentation": { "echo": true, "reveal": "always", "panel": "shared" } }, { "label": "Rebuild Editor", "type": "shell", "command": "C:/Program Files/Epic Games/UE_5.3/Engine/Build/BatchFiles/Build.bat", "args": [ "YourProjectEditor", "Win64", "Development", "-Project=${workspaceFolder}/YourProject.uproject", "-WaitMutex", "-FromMsBuild", "-Clean" ], "problemMatcher": "$msCompile" } ] }几个参数解释一下:YourProjectEditor是目标名,对应你项目里Source/YourProject.Target.cs中定义的目标。Win64是平台,Development是配置。-WaitMutex防止多个 UBT 实例同时跑导致文件锁冲突。-FromMsBuild让输出格式更规整,方便 problemMatcher 解析错误。
problemMatcher设为$msCompile后,编译错误会直接显示在 VS Code 的"问题"面板里,点击能跳转到对应代码行。这个体验比在终端里翻日志强太多。
4.2 快捷键绑定与一键编译
配好任务后,按Ctrl+Shift+B就能触发默认编译任务。但 UE 项目经常需要在"编译编辑器"和"编译游戏"之间切换,我建议再绑几个快捷键。
在.vscode/keybindings.json里加:
[ { "key": "ctrl+shift+e", "command": "workbench.action.tasks.runTask", "args": "Build Editor (Development)" }, { "key": "ctrl+shift+r", "command": "workbench.action.tasks.runTask", "args": "Rebuild Editor" } ]这样Ctrl+Shift+E编译,Ctrl+Shift+R全量重建,比去菜单里点快得多。
4.3 Live Coding 与热重载的配合
UE5 的 Live Coding 是个好东西,改完 C++ 代码按Ctrl+Alt+F11就能热重载,不用重启编辑器。但它和 VS Code 的编译任务是两套机制:Live Coding 走的是引擎内部的编译流程,VS Code 的 task 走的是 UBT 命令行。
我的建议是:日常小改动用 Live Coding,大改动(改头文件、加新类、改模块依赖)用 VS Code 的 task 全量编译。因为 Live Coding 对头文件改动的支持有限,改了.h文件经常需要重启编辑器才能生效。
实操心得:Live Coding 编译时,VS Code 的 IntelliSense 数据库不会自动更新。如果你加了新函数,代码里会报"未定义",但实际能编译通过。这时候手动跑一次
compile_commands.json生成命令,或者重启一下 C/C++ 扩展(命令面板搜 "C/C++: Reset IntelliSense Database")就好了。
5. 调试配置:断点、附加、变量查看
5.1 launch.json 接入调试器
VS Code 调试 UE 项目,用的是 Microsoft 的 C/C++ 扩展自带的cppvsdbg调试器。配置写在.vscode/launch.json:
{ "version": "0.2.0", "configurations": [ { "name": "Launch UE5 Editor (Debug)", "type": "cppvsdbg", "request": "launch", "program": "C:/Program Files/Epic Games/UE_5.3/Engine/Binaries/Win64/UnrealEditor.exe", "args": [ "${workspaceFolder}/YourProject.uproject", "-game", "-log" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "console": "externalTerminal", "visualizerFile": "C:/Program Files/Epic Games/UE_5.3/Engine/Extras/VisualStudioDebugging/Unreal.natvis" }, { "name": "Attach to UE5 Editor", "type": "cppvsdbg", "request": "attach", "processId": "${command:pickProcess}" } ] }visualizerFile这一项是精髓。UE 引擎自带一个Unreal.natvis文件,它告诉调试器怎么漂亮地显示 UE 的容器类型(比如TArray、TMap、FString)。没有它,你在调试窗口里看到的FString就是一坨内存地址,根本没法看。
args里的-game表示以游戏模式启动(不带编辑器 UI),调试游戏逻辑时用这个。如果要调试编辑器本身,去掉-game就行。
5.2 附加到运行中的编辑器
更常用的场景是:编辑器已经开着,我想调试某个函数。这时候用 "Attach to UE5 Editor" 配置,按 F5 后会弹出进程列表,选UnrealEditor.exe就行。
附加调试有个坑:必须确保你编译的是 Debug 或 Development 配置,且带调试符号。如果你编译的是 Shipping 配置,符号被剥离了,断点根本打不上。UE 默认的 Development 配置是带符号的,放心用。
5.3 断点不生效的排查思路
断点打上去是空心圆(灰色),说明调试器没找到对应的符号文件。排查顺序:
- 确认编译配置是 Development 或 Debug,不是 Shipping。
- 确认
UnrealEditor.exe和你的模块.pdb文件在同一目录或符号路径能找到。 - 确认附加的进程是对的(有时候开了多个编辑器实例)。
- 检查代码是否真的被编译进去了——有时候改了代码没重新编译,断点自然打不上。
我遇到最多的情况是第 4 种。UE 项目模块多,有时候只编译了部分模块,你以为改了,其实跑的还是旧代码。养成改完代码先编译再调试的习惯。
6. 常见问题与排查速查表
6.1 IntelliSense 相关
| 现象 | 原因 | 解决 |
|---|---|---|
| 满屏红波浪线 | 包含路径缺失 | 生成 compile_commands.json 并配置 |
| 宏报未定义 | 反射宏不被识别 | 加__INTELLISENSE__宏或忽略 |
| 跳转定义失效 | 数据库未建立 | 重置 IntelliSense 数据库 |
| 补全卡顿 | 项目太大 | 限制 includePath 范围,排除 Intermediate |
6.2 编译相关
| 现象 | 原因 | 解决 |
|---|---|---|
| UBT 找不到 VS | 工具链未安装 | 装 VS 2022 游戏开发工作负载 |
| 编译报 mutex 错误 | 多实例冲突 | 加-WaitMutex参数 |
| 改了 .h 不生效 | Live Coding 限制 | 全量编译并重启编辑器 |
| 链接错误 LNK2019 | 模块依赖缺失 | 检查 .Build.cs 的依赖列表 |
6.3 调试相关
| 现象 | 原因 | 解决 |
|---|---|---|
| 断点是空心圆 | 符号未加载 | 确认编译配置带符号 |
| 变量显示乱码 | natvis 未加载 | 配置 visualizerFile |
| 附加进程失败 | 权限不足 | 以管理员身份运行 VS Code |
| 调试卡死 | 断点太多 | 减少断点,用条件断点 |
6.4 独家避坑技巧
说几个文档里不会写、但我实际踩过的坑:
第一,路径里的空格和中文。UE 的 UBT 对路径中的空格处理还算 OK,但对中文路径支持很差。如果你的项目路径里有中文,编译大概率会失败。我建议所有 UE 项目都放在纯英文、无空格的路径下,比如D:\UEProjects\MyGame。
第二,杀毒软件拖慢编译。Windows Defender 实时扫描会严重拖慢 UBT 的编译速度,尤其是大项目。把项目目录和引擎目录加入排除列表,编译速度能快 30% 以上。
第三,VS Code 的工作区设置。如果你同时开多个 UE 项目,建议用"多根工作区"(Multi-root Workspace),每个项目一个文件夹,避免 IntelliSense 数据库互相干扰。
第四,定期清理 Intermediate。UE 的 Intermediate 目录会越积越大,有时候还会因为缓存导致奇怪的编译错误。遇到莫名其妙的编译失败,先删掉Intermediate/和Saved/目录重新生成,能解决一半问题。
7. 我个人的实际使用体会
这套配置我从 UE5.1 一直用到 5.4,中间经历过几次引擎升级导致的配置失效,但整体框架没变过。VS Code 写 UE 的体验,说实话在纯 C++ 代码编辑和导航上,比 Visual Studio 轻快不少,尤其是机器配置一般的时候,开 VS 那个加载速度真的劝退。
但它也有明显的短板:蓝图和 C++ 的混合调试不如 VS 顺畅,UE 的一些编辑器专用工具(比如蓝图调试器、性能分析器)在 VS Code 里没有对应集成。所以我的实际工作流是:日常写 C++ 用 VS Code,需要深度调试蓝图或做性能分析时切回 Visual Studio。两个 IDE 共用同一套 UBT 工具链,项目文件是通用的,切换成本很低。
最后分享一个小技巧:把常用的 UBT 命令(编译、生成项目文件、清理)都写成.bat脚本放在项目根目录,然后在 VS Code 的 tasks.json 里引用这些脚本。这样即使换了引擎版本,只需要改脚本里的引擎路径,tasks.json 不用动。这个习惯帮我省了不少升级时的重复劳动。