C# 語言特性

本頁概述 C# 和 Godot 常用的特性,以及如何搭配使用。

型別轉換與轉型

C# 是靜態型別語言,因此,無法執行如下操作:

var mySprite = GetNode("MySprite");
mySprite.SetFrame(0);

GetNode() 方法會回傳一個 Node 實例。你必須明確將其轉型為你需要的衍生型別,例如本例中的 Sprite2D。

針對這種情況,C# 提供了多種作法。

轉型與型別檢查

若回傳的節點無法轉型為 Sprite2D,這種方式會拋出 InvalidCastException。當你很確定不會失敗時,可以用這種方式取代 as 運算子。

Sprite2D mySprite = (Sprite2D)GetNode("MySprite");
mySprite.SetFrame(0);

使用 as 運算子

as 運算子在無法將節點轉型為 Sprite2D 時會回傳 null,因此不能用於值型別。

Sprite2D mySprite = GetNode("MySprite") as Sprite2D;
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);

使用泛型方法

也可以使用泛型方法來讓型別轉換變得更簡單直觀。

GetNode<T>() 會在回傳前將節點轉型。如果節點無法轉型為所需型別,會拋出 InvalidCastException。

Sprite2D mySprite = GetNode<Sprite2D>("MySprite");
mySprite.SetFrame(0);

GetNodeOrNull<T>() 會使用 as 運算子,若節點無法轉型為所需型別時會回傳 null。

Sprite2D mySprite = GetNodeOrNull<Sprite2D>("MySprite");
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);

使用 is 運算子進行型別檢查

要檢查節點是否可以轉型為 Sprite2D,可以使用 is 運算子。若無法轉型則回傳 false,否則回傳 true。注意,當 is 運算子對 null 使用時,結果永遠是 false。

if (GetNode("MySprite") is Sprite2D)
{
    // Yup, it's a Sprite2D!
}

if (null is Sprite2D)
{
    // This block can never happen.
}

若 is 運算子回傳 true,你也可以宣告新變數來儲存轉型結果。

if (GetNode("MySprite") is Sprite2D mySprite)
{
    // The mySprite variable only exists inside this block, and it's never null.
    mySprite.SetFrame(0);
}

如需進階型別檢查,可參考 模式比對。

前置處理器定義

Godot 提供一系列定義,可讓你根據編譯目標環境調整 C# 程式碼。

範例

例如,你可以依據平台切換程式碼:

    public override void _Ready()
    {
#if (GODOT_MOBILE || GODOT_WEB)
        // Use simple objects when running on less powerful systems.
        SpawnSimpleObjects();
#else
        SpawnComplexObjects();
#endif
    }

或是偵測你的程式碼目前運行於哪個引擎,這對製作跨引擎函式庫很有幫助:

    public void MyPlatformPrinter()
    {
#if GODOT
        GD.Print("This is Godot.");
#elif UNITY_5_3_OR_NEWER
        print("This is Unity.");
#else
        throw new NotSupportedException("Only Godot and Unity are supported.");
#endif
    }

你也可以撰寫腳本,同時支援多個 Godot 版本,並運用僅部分版本支援的功能:

    public void UseCoolFeature()
    {
#if GODOT4_3_OR_GREATER || GODOT4_2_2_OR_GREATER
        // Use CoolFeature, that was added to Godot in 4.3 and cherry-picked into 4.2.2, here.
#else
        // Use a workaround for the absence of CoolFeature here.
#endif
    }

完整定義列表

  • GODOT 會在所有 Godot 專案中被定義。

  • TOOLS 會在使用 Debug 組態(編輯器與編輯器執行)建構時被定義。

  • 當 GodotFloat64 屬性設為 true 時,會定義 GODOT_REAL_T_IS_DOUBLE。

  • 根據作業系統,會定義 GODOT_LINUXBSD、GODOT_WINDOWS、GODOT_OSX、GODOT_ANDROID、GODOT_IOS 或 GODOT_WEB 其中之一。這些名稱未來可能變動。這些名稱源自 OS 單例的 get_name() 方法,但該方法回傳的所有作業系統,不一定都支援 Godot .NET 執行。

  • GODOTX、GODOTX_Y、GODOTX_Y_Z、GODOTx_OR_GREATER、GODOTX_y_OR_GREATER 以及 GODOTX_Y_z_OR_GREATER,其中 X、Y、Z 分別代表目前 Godot 的主、次、修正版號,x、y、z 則代表從 0 到該欄位目前版本號的所有值。

    備註

    這些定義自 Godot 4.0.4 與 4.1 之後才出現。舊版 Godot 不會有這些版本定義。

    舉例來說:Godot 4.0.5 會定義 GODOT4、GODOT4_OR_GREATER、GODOT4_0、GODOT4_0_OR_GREATER、GODOT4_0_5、GODOT4_0_4_OR_GREATER 和 GODOT4_0_5_OR_GREATER。Godot 4.3.2 會定義 GODOT4、GODOT4_OR_GREATER、GODOT4_3、GODOT4_0_OR_GREATER、GODOT4_1_OR_GREATER、GODOT4_2_OR_GREATER、GODOT4_3_OR_GREATER、GODOT4_3_2、GODOT4_3_0_OR_GREATER、GODOT4_3_1_OR_GREATER 與 GODOT4_3_2_OR_GREATER。

匯出時,根據匯出目標還會有以下定義:

  • 根據平台類型,會定義 GODOT_PC、GODOT_MOBILE 或 GODOT_WEB 其中之一。

  • 根據平台,會定義 GODOT_WINDOWS、GODOT_LINUXBSD、GODOT_MACOS、GODOT_ANDROID、GODOT_IOS 或 GODOT_WEB 其中之一。

欲查看範例專案,請參考作業系統測試範例: https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test