C# 基礎
前言
本頁簡要介紹 C# 以及如何在 Godot 中使用它。之後,建議你可以參考 如何使用特定功能、閱讀 C# 與 GDScript API 的差異,或者(重新)瀏覽按部就班教學的 腳本區段。
C# 是由 Microsoft 開發的高階程式語言。在 Godot 中則是以 .NET 8.0 為基礎實作。
注意
目前使用 Godot 4 撰寫的 C# 專案尚無法匯出到網頁平台。如果你需要在網頁平台用 C#,請考慮改用 Godot 3。自 Godot 4.2 起已可匯出至 Android 與 iOS,但功能仍屬實驗性,且 有些限制。
備註
本頁**不是**完整的 C# 語言教學。如果你還不熟悉 C# 的語法與功能,請參考 Microsoft C# 指南 或尋找其他合適的入門資源。
先決條件
Godot 已內建執行已編譯遊戲所需的 .NET 元件,但未內建建置與編譯專案所需的工具(如 MSBuild 與 C# 編譯器)。這些工具包含在 .NET SDK 中,需另外安裝。
總結來說,你必須安裝 .NET SDK 以及 支援 .NET 的 Godot 版本。
請到 .NET 下載頁面 下載並安裝最新版 SDK。
重要
如果你使用的是 64 位元版本的 Godot,請務必安裝 64 位元的 SDK。
若你是從原始碼自行建置 Godot,請依照 使用 .NET 編譯 文件中的步驟啟用 .NET 支援。
設定外部編輯器
C# support in Godot's built-in script editor is minimal. Consider using an external IDE or editor, such as Visual Studio Code or Visual Studio. These provide autocompletion, debugging, and other useful features for C#. To select an external editor in Godot, click on Editor → Editor Settings and scroll down to Dotnet. Under Dotnet, click on Editor, and select your external editor of choice. Godot currently supports the following external editors:
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 3.2.3 起,Godot 會在下次建置專案時自動下載並設定新增的 NuGet 套件。
C# 程式碼效能剖析
你可使用下列工具分析受控(managed)程式碼的效能與記憶體:
JetBrains Rider,搭配 dotTrace/dotMemory 外掛。
獨立版 JetBrains dotTrace/dotMemory。
Visual Studio。
JetBrains 工具與 Visual Studio 均可同時剖析受控與非受控程式碼,但僅支援 Windows。