Godot 4.7 内嵌 C# 模块切换到 .NET 9.0 编译指南
1. 背景
Godot 4.7 源码默认使用 Mono/.NET 8.0 构建 C# 绑定(GodotSharp)。当开发机上只安装了 .NET SDK 9.0 或希望升级到 .NET 9.0 时,
需要对若干 C# 项目文件和 Python 构建脚本做少量改动,使整套 C# 绑定可以用本地 .NET 9.0 SDK 直接编译,
并且生成的程序集能被 Godot 编辑器正确加载。
本文档记录一套经过实测可以成功编译并被 Godot 4.7 识别的最小改动方案。
2. 前提条件
- 操作系统:Windows 10/11 x64
- Godot 源码 :本地工作区
D:\my2024\godot\godot - Visual Studio 2022 + MSVC 工具链(脚本中使用的版本号见
build_godot.ps1) - .NET SDK :9.0.314(示例路径
C:\Program Files\dotnet\sdk\9.0.314\) - Python :3.12(用于
build_assemblies.py) - MSYS2 / SCons:常规 Godot 构建依赖
用以下命令确认本机 .NET SDK 版本:
powershell
dotnet --list-sdks
3. 需要修改的文件总览
| 文件 | 修改点 |
|---|---|
modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/Godot.SourceGenerators.Internal.csproj |
TargetFramework → net9.0,移除 NuGet 包引用,改用本地 Roslyn DLL |
modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj |
TargetFramework → net9.0 |
modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj |
TargetFramework → net9.0 |
modules/mono/glue/GodotSharp/GodotPlugins/GodotPlugins.csproj |
TargetFramework → net9.0 |
modules/mono/build_scripts/build_assemblies.py |
硬编码路径 net8.0 → net9.0 |
nuget.config(可选) |
保持官方源即可,国内网络可切换镜像 |
build_godot.ps1(可选) |
已注明 .NET SDK 9.0,无需强制改动 |
4. 详细修改步骤
4.1 修改 Godot.SourceGenerators.Internal.csproj
文件路径
modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/Godot.SourceGenerators.Internal.csproj
问题根因
该项目原本使用 TargetFramework = netstandard2.0,并通过 <PackageReference> 从 NuGet 下载
Microsoft.CodeAnalysis 和 Microsoft.CodeAnalysis.CSharp。在网络受限或国内网络环境下,
NuGet 包容易损坏(End of Central Directory record could not be found)或 XML 解析失败。
修改方案
直接引用本机 .NET SDK 9.0 自带的 Roslyn DLL,不走 NuGet。
修改后完整内容:
xml
<Project Sdk="Microsoft.NET.Sdk">
<!--
TargetFramework 改为 net9.0 以匹配本地 .NET SDK 9.0。
全部使用本地 SDK 自带的 Roslyn DLL,不从 NuGet 下载大包。
-->
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- 仅引用本地 SDK 的 Roslyn DLL -->
<ItemGroup>
<Reference Include="Microsoft.CodeAnalysis"
HintPath="C:\Program Files\dotnet\sdk\9.0.314\Roslyn\bincore\Microsoft.CodeAnalysis.dll" />
<Reference Include="Microsoft.CodeAnalysis.CSharp"
HintPath="C:\Program Files\dotnet\sdk\9.0.314\Roslyn\bincore\Microsoft.CodeAnalysis.CSharp.dll" />
</ItemGroup>
</Project>
注意
HintPath 中的 SDK 版本号(9.0.314)必须与 dotnet --list-sdks 显示的完全一致;升级 SDK 版本时需要同步更新此处路径。
4.2 修改 GodotSharp.csproj
文件路径
modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
将 <TargetFramework>net8.0</TargetFramework> 修改为:
xml
<TargetFramework>net9.0</TargetFramework>
其余内容保持不变。该项目会自动引用上一步修改后的 Godot.SourceGenerators.Internal。
4.3 修改 GodotSharpEditor.csproj
文件路径
modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj
同样把 <TargetFramework>net8.0</TargetFramework> 修改为:
xml
<TargetFramework>net9.0</TargetFramework>
该项目依赖 GodotSharp,两者必须保持相同 TargetFramework。
4.4 修改 GodotPlugins.csproj
文件路径
modules/mono/glue/GodotSharp/GodotPlugins/GodotPlugins.csproj
把 <TargetFramework>net8.0</TargetFramework> 修改为:
xml
<TargetFramework>net9.0</TargetFramework>
该项目会自动生成 GodotPlugins.runtimeconfig.json,其内容会基于 TargetFramework 自动填充,无需手工编写。
4.5 修改 build_assemblies.py
文件路径
modules/mono/build_scripts/build_assemblies.py
问题根因
脚本中存在硬编码的 net8.0 路径,用于定位 GodotPlugins.dll 的输出目录:
python
# 修改前(约第 228 行)
plugins_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotPlugins", "bin", build_config, "net8.0"))
修改方案
将 net8.0 替换为 net9.0:
python
# 修改后
plugins_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotPlugins", "bin", build_config, "net9.0"))
这样 SCons 在构建完成后调用 build_assemblies.py 时,能正确把 GodotSharp 系列 DLL
拷贝到 bin/GodotSharp/Api/Debug/,Godot 编辑器才能在启动时找到这些程序集。
4.6 nuget.config(可选)
项目根目录的 nuget.config 当前内容:
xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
因为我们已经把 Roslyn 依赖全部切到本地 DLL,nuget 只可能被 GodotSharp 里的
ReflectionAnalyzers 分析器包用到(体积很小、下载很快),官方源即可。
如果国内下载仍慢,可临时改成 Azure 镜像:
xml
<add key="nuget.org" value="https://nuget.cdn.azure.cn/v3/index.json" />
或 USTC / 清华镜像(按需选择其一):
xml
<add key="ustc" value="https://mirrors.ustc.edu.cn/nuget/v3/index.json" />
<add key="tuna" value="https://mirrors.tuna.tsinghua.edu.cn/nuget/v3/index.json" />
5. 构建流程
5.1 环境清理(可选)
powershell
# 清空 NuGet 本地缓存(仅在怀疑缓存损坏时需要)
dotnet nuget locals all --clear
5.2 一键构建
项目根目录下的 build_godot.ps1 已经配置好 MSVC 工具链、Windows SDK、.NET SDK 和 Python 路径,
直接运行即可:
powershell
cd D:\my2024\godot\godot
.\build_godot.ps1
脚本会执行:
powershell
scons platform=windows target=editor use_mingw=no clean
scons platform=windows target=editor use_mingw=no d3d12=yes winrt=no accesskit=no optimize=debug debug_symbols=yes module_mono_enabled=yes -j8
SCons 会在 C++ 原生层编译后自动调用 modules/mono/build_scripts/build_assemblies.py,
后者再用 dotnet build 编译 4 个 C# 项目,并把最终程序集拷贝到
bin/GodotSharp/Api/Debug/。
5.3 构建产物位置
- 原生编辑器 :
bin/godot.windows.editor.x86_64.mono.exe - C# 程序集目录 :
bin/GodotSharp/Api/Debug/
该目录应包含以下文件(构建成功后):
GodotSharp.dll
GodotSharp.pdb
GodotSharp.xml
GodotSharpEditor.dll
GodotSharpEditor.pdb
GodotSharpEditor.xml
GodotPlugins.dll
GodotPlugins.pdb
GodotPlugins.runtimeconfig.json
- 工具 / NuGet 包 :
bin/GodotSharp/Tools/nupkgs/*.nupkg
5.4 runtimeconfig.json(自动生成)
GodotPlugins.csproj 中启用了 <EnableDynamicLoading>true</EnableDynamicLoading> 与
<RollForward>LatestMajor</RollForward>,所以构建时会自动生成:
json
{
"runtimeOptions": {
"tfm": "net9.0",
"rollForward": "LatestMajor",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "9.0.0"
}
}
}
这个 runtimeconfig 就是 Godot 编辑器启动 .NET 运行时的依据,严禁手工篡改。
6. 常见问题排查
6.1 "找不到中央目录结尾记录" / "根级别上的数据无效"
- 原因:NuGet 下载大文件时被网络截断或缓存损坏。
- 解决 :执行
dotnet nuget locals all --clear;或直接跳过 NuGet(本方案已经在 Roslyn 依赖上这样做了)。
6.2 "项目指向 net9.0,不能被 net8.0 项目引用"
- 原因 :某一个
.csproj漏改,其余已经是net9.0。 - 解决 :重新执行第 4.2 ~ 4.4 步,确保 4 个
.csproj的TargetFramework全部一致。
6.3 启动 Godot 编辑器提示 "没有 .NET 集合"
- 原因 A :
build_assemblies.py没有找到输出目录(net8.0vsnet9.0路径错配)。 - 解决 A :执行第 4.5 步;确认
bin/GodotSharp/Api/Debug/下确实有 3 个*.dll。 - 原因 B :
.runtimeconfig.json中framework.version与本机 SDK 不匹配。 - 解决 B :确保
GodotPlugins.csproj已经是net9.0,然后重新dotnet build让文件自动刷新,不要手改 JSON。
6.4 Roslyn DLL HintPath 指向版本不存在
- 原因 :升级了 SDK 但忘了更新
HintPath。 - 解决 :重新执行
dotnet --list-sdks,确认sdk\<版本号>\Roslyn\bincore\目录下两个 DLL 都存在,
再更新Godot.SourceGenerators.Internal.csproj。
7. 未来升级提示
- 任何时候升级 .NET SDK 主版本(例如 9.0.x → 10.0.x):
- 更新 4 个
.csproj的TargetFramework(必要时)。 - 更新
Godot.SourceGenerators.Internal.csproj中 Roslyn DLL 的HintPath。 - 更新
build_assemblies.py中的硬编码路径。
- 更新 4 个
- 建议把上述 4 个文件里的版本号统一改成一个共享变量(例如从环境变量或 props 文件读取),
以彻底避免"改一处漏三处"的问题。
文档生成日期:2026-06-08
适用 Godot 源码分支:godotengine/godot(2024.0x / 4.7 系列)
适用 .NET SDK:9.0.314(Windows x64)