Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
C# 基礎
前言
本頁簡要介紹 C# 以及如何在 Godot 中使用它。之後,建議你可以參考 如何使用特定功能、閱讀 C# 與 GDScript API 的差異,或者(重新)瀏覽按部就班教學的 腳本區段。
C# is a high-level programming language developed by Microsoft. In Godot, it is implemented with the modern .NET runtime.
注意
目前使用 Godot 4 撰寫的 C# 專案尚無法匯出到網頁平台。如果你需要在網頁平台用 C#,請考慮改用 Godot 3。自 Godot 4.2 起已可匯出至 Android 與 iOS,但功能仍屬實驗性,且 有些限制。
備註
本頁**不是**完整的 C# 語言教學。如果你還不熟悉 C# 的語法與功能,請參考 Microsoft C# 指南 或尋找其他合適的入門資源。
先決條件
Godot bundles the parts of .NET needed to run already-compiled games. However, Godot does not bundle the tools required to build and compile games, such as MSBuild and the C# compiler. These are included in the .NET SDK, and need to be installed separately.
總結來說,你必須安裝 .NET SDK 以及 支援 .NET 的 Godot 版本。
Download and install the latest stable version of the SDK from the .NET download page. Godot 4.5 requires .NET 8 or later, but exporting to Android requires .NET 9 or later.
重要
如果你使用的是 64 位元版本的 Godot,請務必安裝 64 位元的 SDK。
若你是從原始碼自行建置 Godot,請依照 使用 .NET 編譯 文件中的步驟啟用 .NET 支援。
設定外部編輯器
Godot 內建的腳本編輯器對 C# 的支援相當基本。建議改用外部 IDE 或編輯器,例如 Visual Studio Code 或 Visual Studio。它們提供自動完成、除錯等實用功能。要在 Godot 指定外部編輯器,請按 Editor → Editor Settings,往下捲到 Dotnet。在 Dotnet 底下點 Editor,選擇你偏好的外部編輯器。Godot 目前支援以下外部編輯器:
Visual Studio 2022
Visual Studio Code
MonoDevelop
Visual Studio for Mac
JetBrains Rider
有關如何設定外部編輯器,請參考以下說明:
JetBrains Rider
閱讀完「先決條件」後,即可下載並安裝 JetBrains Rider。
在 Godot 的 編輯器 → 編輯器設定 選單:
將 Dotnet → Editor → External Editor 設為 JetBrains Rider。
於 Rider:
將 MSBuild version 設為 .NET Core。
如果你使用 2024.2 之前版本的 Rider,請另外安裝 Godot support 擴充套件。新版 Rider 已內建此功能。
Visual Studio Code
閱讀完「先決條件」後,即可下載並安裝 Visual Studio Code (又稱 VS Code)。
在 Godot 的 編輯器 → 編輯器設定 選單:
將 Dotnet → Editor → External Editor 設為 Visual Studio Code。
於 Visual Studio Code:
安裝 C# 擴充套件。
若要設定專案除錯,必須在 .vscode 資料夾內建立 tasks.json 與 launch.json,並填入必要的設定。
以下為一個 launch.json 範例:
{
"version": "0.2.0",
"configurations": [
{
"name": "Play",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${env:GODOT4}",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
}
]
}
若要使這個啟動組態生效,你需要設定一個名為 GODOT4 的環境變數指向 Godot 執行檔,或直接將 program 欄位填入 Godot 執行檔的路徑。
以下為一個 tasks.json 範例:
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build"
],
"problemMatcher": "$msCompile"
}
]
}
現在,當你在 Visual Studio Code 啟動除錯器時,你的 Godot 專案就會執行。
Visual Studio(僅限 Windows)
下載並安裝最新版 Visual Studio。只要安裝時選對工作負載,Visual Studio 會自動包含所需 SDK,因此不需要額外手動安裝「先決條件」中的內容。
安裝 Visual Studio 時,請選擇以下工作負載:
.NET 桌面開發
在 Godot 的 編輯器 → 編輯器設定 選單:
將 Dotnet → Editor → External Editor 設為 Visual Studio。
備註
如果看到「Unable to find package Godot.NET.Sdk」這類錯誤,表示 NuGet 設定有誤,需要修正。
解決 NuGet 設定檔的方法之一是重新產生它。在檔案總管中前往 %AppData%\NuGet,將 NuGet.Config 檔案重新命名或刪除。重新建置 Godot 專案時,該檔案會自動以預設值重建。
若要用 Visual Studio 除錯 C# 腳本,請開啟第一個 C# 腳本後產生的 .sln 檔。於 偵錯 選單中,進入專案的 偵錯屬性 。點擊 建立新設定檔 並選擇 可執行檔 。在 可執行檔 欄位選擇 Godot 編輯器支援 C# 版本的執行檔路徑,若已設好 GODOT4 環境變數,也可填 %GODOT4% 。此路徑必須是主 Godot 執行檔,不能用 console 版本。 工作目錄 填入單一點號 . (表示目前目錄)。勾選 啟用原生程式碼偵錯 。設定完成後即可關閉視窗,從偵錯設定檔下拉選單選擇剛建立的設定檔,點擊綠色開始按鈕,遊戲就會以除錯模式啟動。
建立 C# 腳本
當你成功設定好 Godot 的 C# 支援後,於場景節點的右鍵選單選擇 附加腳本 時應會出現下列選項:
請注意,儘管細節略有不同,大部分腳本概念在 C# 與 GDScript 之間是一致的。如果你剛接觸 Godot,建議先閱讀 為場景編寫腳本 相關教學。雖然有些文件頁面缺乏 C# 範例,大部分觀念都能直接從 GDScript 套用。
專案設定與工作流程
當你建立第一個 C# 腳本時,Godot 會自動初始化整個專案的 C# 專案檔案,包括產生 C# 解決方案(.sln)、專案檔(.csproj),以及一些工具相關檔案和資料夾(如 .godot/mono)。除了 .godot/mono 外,其餘都很重要,應納入版本控制。.godot 底下內容可安全加入版本控制忽略清單。有時排除問題時,刪除 .godot/mono 讓 Godot 重新產生會有幫助。
範例
以下是一個空白的 C# 腳本範例,並附有說明註解。
using Godot;
public partial class YourCustomClass : Node
{
// Member variables here, example:
private int _a = 2;
private string _b = "textvar";
public override void _Ready()
{
// Called every time the node is added to the scene.
// Initialization here.
GD.Print("Hello from C# to Godot :)");
}
public override void _Process(double delta)
{
// Called every frame. Delta is time since the last frame.
// Update game logic here.
}
}
如你所見,GDScript 中屬於全域作用域的函式(如 Godot 的 print 函式),在 C# 中則位於 Godot 命名空間內的靜態類別 GD。完整方法清單請參考類別參考文件:@GDScript 及 @GlobalScope。
備註
請注意,你要掛載到節點上的類別名稱必須與 .cs 檔案名稱相同,否則會出現下列錯誤:
"Cannot find class XXX for script res://XXX.cs"
C# 與 GDScript 的主要差異
C# API 採用 PascalCase (大駝峰式命名),而非 GDScript/C++ 的 snake_case (底線式命名)。大多數欄位與 getter/setter 都盡量轉換為屬性。整體而言,C# 的 Godot API 盡可能遵循慣用 C# 風格。
詳情請參閱 C# API 與 GDScript 的不同 頁面。
警告
每當你想在編輯器內看到新的匯出變數或訊號時,都必須重新建置專案組件。你可以點擊編輯器右上角的 建置 按鈕手動觸發建置。
若要套用「tool」腳本的變更,也必須重新建置專案組件。
目前注意事項與已知問題
由於 Godot 對 C# 的支援仍屬新穎,現階段仍有不少待完善之處。以下列出目前在 Godot 使用 C# 時需特別留意的重點問題。若有疑問,也可參閱官方的 .NET 問題追蹤。
雖然可以用 C# 撰寫編輯器外掛,但目前流程較為繁瑣。
熱重載時,目前只有匯出變數的狀態會被保存與還原。
C# 腳本附加時,類別名稱必須與檔名相符。
有些方法(如
Get()/Set()、Call()/CallDeferred()以及訊號連接用的Connect())仍依賴 Godot 的snake_case命名。例如CallDeferred("AddChild")會失敗,因為 API 只接受原始的add_child。但你可以自訂屬性或方法,不受此限。建議優先使用PropertyName、MethodName、SignalName等已公開的StringName,這樣可避免多餘的StringName配置,也不用顧慮 snake_case。
自 Godot 4.0 起,.NET 專案可匯出至桌面平台(Linux、Windows、macOS)。其他平台的支援會於 4.x 未來版本陸續加入。
常見陷阱
你在嘗試修改部份 Godot 物件的屬性時(如變更 Node2D 的 X 座標)可能會遇到下列錯誤:
public partial class MyNode2D : Node2D
{
public override void _Ready()
{
Position.X = 100.0f;
// CS1612: Cannot modify the return value of 'Node2D.Position' because
// it is not a variable.
}
}
這是正常現象。C# 的結構(如 Vector2)在賦值時是複製,從屬性或索引子取得這類物件時,得到的是副本而非原物件。單獨改變副本的內容並不會改變原屬性,必須重新指定回去。
解法很簡單:先取出整個結構,修改所需值後,再把整個結構重新指定回屬性。
var newPosition = Position;
newPosition.X = 100.0f;
Position = newPosition;
自 C# 10 起,也可以在結構上使用 with 運算式,讓上述操作一行完成。
Position = Position with { X = 100.0f };
你可在 C# 語言參考 了解更多關於此錯誤的資訊。
Godot 的 C# 效能
也參考
關於 Godot 支援語言的效能比較,請參考 哪種程式語言最快?。
大多數繼承自 GodotObject 的 C# 物件屬性(如 Control、Camera3D 等節點),在存取時都需與 Godot C++ 核心進行互操作(interop)呼叫。如果你需要重複存取或修改同一屬性,建議先存到區域變數再操作:
using Godot;
public partial class YourCustomClass : Node3D
{
private void ExpensiveReposition()
{
for (var i = 0; i < 10; i++)
{
// Position is read and set 10 times which incurs native interop.
// Furthermore the object is repositioned 10 times in 3D space which
// takes additional time.
Position += new Vector3(i, i);
}
}
private void Reposition()
{
// A variable is used to avoid native interop for Position on every loop.
var newPosition = Position;
for (var i = 0; i < 10; i++)
{
newPosition += new Vector3(i, i);
}
// Setting Position only once avoids native interop and repositioning in 3D space.
Position = newPosition;
}
}
將原生陣列(如 byte[])或 string 傳遞給 Godot 的 C# API 時,會經過封送處理(marshalling),效能開銷較大。
將 string 隱式轉換為 NodePath 或 StringName 時,會同時產生互操作與資料封送的效能損耗,因為字串需封送並傳給原生建構函式。
在 Godot 使用 NuGet 套件
你可以像一般 C# 專案一樣,在 Godot 中安裝並使用 NuGet 套件。多數 IDE 支援直接加入套件,也可手動於專案根目錄的 .csproj 檔案中加入套件參考:
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>
...
</Project>
Godot automatically downloads and sets up newly added NuGet packages the next time it builds the project.
C# 程式碼效能剖析
你可使用下列工具分析受控(managed)程式碼的效能與記憶體:
JetBrains Rider,搭配 dotTrace/dotMemory 外掛。
獨立版 JetBrains dotTrace/dotMemory。
Visual Studio。
JetBrains 工具與 Visual Studio 均可同時剖析受控與非受控程式碼,但僅支援 Windows。