Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

C# exported properties

在 Godot 中可以匯出類別成員。也就是說匯出成員的數值可以與附加的資源一起保存 (如 場景) 。匯出成員也能在屬性面板編輯器中編輯。使用 export 關鍵字來匯出:

using Godot;

public partial class ExportExample : Node3D
{
    [Export]
    private int Number = 5;
}

在該範例中,值「5」將被儲存,建置目前專案後,它將在屬性編輯器中可見。

匯出成員變數的其中一個基本的好處就是能在編輯器中瀏覽並編輯。這樣一來,如美術或遊戲設計師之後就能通過修改數值來更改程式的執行方式。為此有一個特殊的匯出語法。

匯出只適用於:ref:`與 Variant 相容 <doc_c_sharp_variant>`的型別。

備註

GDScript 中也能夠匯出屬性,相關資訊見 GDScript exported properties

Basic use

匯出套件、修正檔與 Mod

[Export]
private int _number;

[Export]
public int Number { get; set; }

匯出的成員可以指定預設值;否則,將使用「型別的預設值 <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/default-values>」。

[Export]
private int _number; // Defaults to '0'

[Export]
private string _text; // Defaults to 'null' because it's a reference type

[Export]
private string _greeting = "Hello World"; // Exported field specifies a default value

[Export]
public string Greeting { get; set; } = "Hello World"; // Exported property specifies a default value

// This property uses `_greeting` as its backing field, so the default value
// will be the default value of the `_greeting` field.
[Export]
public string GreetingWithBackingField
{
    get => _greeting;
    set => _greeting = value;
}

可以匯出資源和節點。

[Export]
public Resource Resource { get; set; }

[Export]
public Node Node { get; set; }

建立屬性群組

可以使用“[ExportGroup]”屬性在屬性面板中對匯出的屬性進行群組。此屬性之後的每個匯出屬性都會新增到群組中。開始一個新群組或使用``[ExportGroup("")]`` 進行群組。

[ExportGroup("My Properties")]
[Export]
public int Number { get; set; } = 3;

此屬性的第二個參數可用於僅對具有指定前綴的屬性進行群組。

群組可以巢狀,請使用 [ExportSubgroup] 在群組中建立子群組。

[ExportSubgroup("Extra Properties")]
[Export]
public string Text { get; set; } = "";
[Export]
public bool Flag { get; set; } = false;

您也可以變更主類別的名稱,或使用「[ExportCategory]」屬性在屬性列表中建立其他類別。

[ExportCategory("Main Category")]
[Export]
public int Number { get; set; } = 3;
[Export]
public string Text { get; set; } = "";

[ExportCategory("Extra Category")]
[Export]
private bool Flag { get; set; } = false;

備註

屬性列表是根據類別繼承來組織的,而新類別打破了這種期望。謹慎使用它們,尤其是在建立供公共使用的專案時。

每行字數限制

屬性提示可用於將字串匯出為路徑

使用檔案

[Export(PropertyHint.File)]
public string GameFile { get; set; }

字串是目錄的路徑。

[Export(PropertyHint.Dir)]
public string GameDirectory { get; set; }

字串是檔的路徑,在提示中提供自訂篩檢程式。

[Export(PropertyHint.File, "*.txt,")]
public string GameFile { get; set; }

也可以使用全域檔案系統中的路徑,但是僅支援工具模式的腳本。

字串是全域檔案系統中某個 PNG 檔的路徑。

[Export(PropertyHint.GlobalFile, "*.png")]
public string ToolImage { get; set; }

字串是全域檔案系統中某個目錄的路徑。

[Export(PropertyHint.GlobalDir)]
public string ToolDir { get; set; }

多行註解告訴編輯器顯示一個大的輸入欄位以進行多行編輯。

[Export(PropertyHint.MultilineText)]
public string Text { get; set; }

翻譯現有頁面

使用 range 屬性提示可以限制使用編輯器輸入的值。

允許 0 到 20 之間的整數。

[Export(PropertyHint.Range, "0,20,")]
public int Number { get; set; }

允許 -10 到 20 之間的整數。

[Export(PropertyHint.Range, "-10,20,")]
public int Number { get; set; }

允許 -10 到 20 之間的數,對齊到 0.2 的倍數。

[Export(PropertyHint.Range, "-10,20,0.2")]
public float Number { get; set; }

如果新增提示“or_greater”和/或“or_less”,則在調整值時可以透過鍵入而不是使用滑桿來高於或低於限制。

[Export(PropertyHint.Range, "0,100,1,or_greater,or_less")]
public int Number { get; set; }

帶緩動提示的浮點數

編輯時顯示“ease()”函式的可視化表示。

[Export(PropertyHint.ExpEasing)]
public float TransitionSpeed { get; set; }

顏色

使用紅、綠、藍、Alpha 值指定的普通顏色。

[Export]
private Color Color { get; set; }

使用紅、綠、藍值指定的顏色(Alpha 始終為 1)。

[Export(PropertyHint.ColorNoAlpha)]
private Color Color { get; set; }

節點

從Godot 4.0開始,可以直接匯出節點,而無需使用NodePaths。

[Export]
public Node Node { get; set; }

也可以使用自訂節點類,請參閱 doc_c_sharp_global_classes`。

如果需要,仍然可以和 Godot 3.x 中一樣匯出 NodePath:

[Export]
private NodePath _nodePath;

public override void _Ready()
{
    var node = GetNode(_nodePath);
}

資源

[Export]
private Resource Resource;

在屬性面板中,您可以將資源檔案從檔案系統停靠欄拖曳到變數槽中。

然而,開啟屬性面板下拉列表可能會導致要建立的可能類別的列表非常長。因此,如果您指定從 Resource 衍生的型別,例如:

[Export]
private AnimationNode Resource;

下拉式選單將僅限於 AnimationNode 及其所有繼承類別。也可以使用自訂資源類,請參閱 doc_c_sharp_global_classes。

請特別注意,即使腳本不是在編輯器中執行,匯出屬性依然可以被編輯。這個功能可以與 「工具」模式的腳本 一起使用。

匯出位元旗標

可以匯出型別為具有「[Flags]」屬性的列舉的成員,並且它們的值僅限於列舉型別的成員。編輯器將在屬性面板中建立一個小元件,允許選擇不選擇、選擇一個或多個列舉成員。該值將儲存為整數。

// Use power of 2 values for the values of the enum members.
[Flags]
public enum MyEnum
{
    Fire = 1 << 1,
    Water = 1 << 2,
    Earth = 1 << 3,
    Wind = 1 << 4,

    // A combination of flags is also possible.
    FireAndWater = Fire | Water,
}

[Export]
public SpellElements MySpellElements { get; set; }

作為位元旗標的整數可以在單一屬性內儲存多個 true/false (布林) 值。只需要使用匯出提示 int, FLAGS, 就可以在編輯器中設定:

// Set any of the given flags from the editor.
[Export(PropertyHint.Flags, "Fire,Water,Earth,Wind")]
public int SpellElements { get; set; } = 0;

必須為每個旗標提供說明字串。在這個例子中, Fire 的值為 1, Water 為 2, Earth 為 4 而 Wind 則為 8。通常必須定義對應的常數 (如: const ELEMENT_WIND = 8 等)。

您可以使用冒號新增明確的值:

[Export(PropertyHint.Flags, "Self:4,Allies:8,Foes:16")]
public int SpellTargets { get; set; } = 0;

只有 2 的冪值作為位元旗標選項才有效。允許的最低值為 1,因為 0 表示未選擇任何內容。您也可以新增其他旗標組合的選項:

[Export(PropertyHint.Flags, "Self:4,Allies:8,Self and Allies:12,Foes:16")]
public int SpellTargets { get; set; } = 0;

匯出提示在專案設定中也定義了物理與渲染層:

[Export(PropertyHint.Layers2DPhysics)]
public uint Layers2DPhysics { get; set; }
[Export(PropertyHint.Layers2DRender)]
public uint Layers2DRender { get; set; }
[Export(PropertyHint.Layers3DPhysics)]
public uint Layers3DPhysics { get; set; }
[Export(PropertyHint.Layers3DRender)]
public uint Layers3DRender { get; set; }

使用位元旗標會需要理解位元運算子。若不確定的話,則應該使用布林變數。

匯出選單

可以匯出列舉型別的成員,且其值僅限於列舉型別的成員。編輯器將在屬性面板中建立一個小元件,將以下內容列舉為「Thing 1」、「Thing 2」、「Another Thing」。該值將儲存為整數。

public enum MyEnum
{
    Thing1,
    Thing2,
    AnotherThing = -1,
}

[Export]
public MyEnum MyEnum { get; set; }

也可以使用帶有“PropertyHint.Enum”提示的“[Export]”註釋將整數和字串成員限制為特定的值列表。編輯器將在 Inspector 中建立一個小元件,列舉以下角色:戰士、魔術師、小偷。該值將儲存為整數,對應於所選選項的索引(即“0”、“1”或“2”)。

[Export(PropertyHint.Enum, "Warrior,Magician,Thief")]
public int CharacterClass { get; set; };

您可以使用冒號新增明確的值:

[Export(PropertyHint.Enum, "Slow:30,Average:60,Very Fast:200")]
public int CharacterSpeed { get; set; }

如果是 string , 檔將從該路徑載入.

[Export(PropertyHint.Enum, "Rebecca,Mary,Leah")]
public string CharacterName { get; set; }

如果要設定初始值,則必須明確指定:

[Export(PropertyHint.Enum, "Rebecca,Mary,Leah")]
public string CharacterName { get; set; } = "Rebecca";

其他建議

如 C# Variant <doc_c_sharp_variant> 檔案中所述,只有某些 C# 陣列和「Godot.Collections」命名空間中定義的集合型別是 Variant 相容的,因此,只能匯出這些型別。

匯出陣列

[Export]
public Godot.Collections.Array Array { get; set; }

使用通用的「Godot.Collections.Array<T>」允許指定將用作編輯器提示的陣列元素的型別。屬性面板會將元素限制為指定型別。

[Export]
public Godot.Collections.Array<string> Array { get; set; }

Godot 陣列的預設值為 null,可以指定不同的預設值:

[Export]
public Godot.Collections.Array<string> CharacterNames { get; set; } = new Godot.Collections.Array<string>
{
    "Rebecca",
    "Mary",
    "Leah",
};

若匯出的陣列指定了從 Resource 繼承來的型別,則陣列值在屬性面板中就可以從檔案系統中一次拖放多個檔案過來。

[Export]
public Godot.Collections.Array<Texture> Textures { get; set; }

[Export]
public Godot.Collections.Array<PackedScene> Scenes { get; set; }

其他建議

[Export]
public Godot.Collections.Dictionary Dictionary { get; set; }

使用通用的「Godot.Collections.Dictionary<TKey, TValue>」允許指定字典的鍵和值元素的型別。

備註

目前 Godot 編輯器不支援型別化字典,因此 Inspector 不會限制可以指派的型別,這可能會導致執行時期異常。

[Export]
public Godot.Collections.Dictionary<string, int> Dictionary { get; set; }

Godot 字典的預設值為 null,可以指定不同的預設值:

[Export]
public Godot.Collections.Dictionary<string, int> CharacterLives { get; set; } = new Godot.Collections.Dictionary<string, int>
{
    ["Rebecca"] = 10,
    ["Mary"] = 42,
    ["Leah"] = 0,
};

匯出陣列

只要元素型別是 Variant 相容的 <doc_c_sharp_variant> 型別,就可以匯出 C# 陣列。

[Export]
public Vector3[] Vectors { get; set; }

[Export]
public NodePath[] NodePaths { get; set; }

C# 陣列的預設值為 null,可以指定不同的預設值:

[Export]
public Vector3[] Vectors { get; set; } = new Vector3[]
{
    new Vector3(1, 2, 3),
    new Vector3(3, 2, 1),
}

從工具腳本中設定匯出變數

工具模式 腳本中更改匯出變數值是,顯示在屬性面板上的值不會自動更新。要更新屬性面板上的值,則需要在設定匯出變數值後呼叫 property_list_changed_notify()

進階匯出

為了避免不必要的複雜設計,並非所有匯出型別都有在語言層面上提供。下面說明了一些能使用低階 API 實作的常見匯出功能。

Before reading further, you should get familiar with the way properties are handled and how they can be customized with _Set(), _Get(), and _GetPropertyList() methods as described in 從物件中存取資料或邏輯.

也參考

若要在 C++ 中以上述方法繫結屬性,請參考 使用 _set/_get/_get_property_list 來繫結屬性

警告

腳本必須為 tool 模式,才可在編輯器中使用上述方法。