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# 匯出屬性
在 Godot 中,類別成員可以被匯出。這代表它們的值會與其所屬的資源(像是 場景)一起儲存。這些屬性也會在屬性編輯器中顯示,並可供編輯。匯出是透過 [Export] 屬性來實現的。
using Godot;
public partial class ExportExample : Node3D
{
[Export]
public int Number { get; set; } = 5;
}
在這個範例中,值 5 會被儲存,並在建置專案後於屬性編輯器中顯示。
匯出成員變數的主要好處之一,是能讓它們在編輯器中顯示並編輯。這樣美術和遊戲設計師就可以直接調整影響程式執行的數值。為此,Godot 提供了專屬的匯出語法。
只能對 Variant 相容型別 進行匯出。
備註
屬性也可以在 GDScript 中匯出,相關資訊請參閱 GDScript 匯出屬性。
基本用法
匯出可以用於欄位與屬性,且存取修飾詞不限。
[Export]
private int _number;
[Export]
public int Number { get; set; }
匯出的成員可以指定預設值;若未指定,則會採用 型別的預設值 。
像 Number 這樣的 int 預設值為 0。而 Text 預設為 null,因為 string 屬於參考型別。
[Export]
public int Number { get; set; }
[Export]
public string Text { get; set; }
欄位與屬性皆可指定預設值。
[Export]
private string _greeting = "Hello World";
[Export]
public string Greeting { get; set; } = "Hello World";
有備援欄位的屬性會使用備援欄位的預設值。
private int _number = 2;
[Export]
public int NumberWithBackingField
{
get => _number;
set => _number = value;
}
備註
屬性的 get 方法實際上並不會執行來決定預設值。Godot 會直接分析 C# 原始碼。這在大多數情況下都沒問題,但有些屬性若過於複雜,分析器可能無法正確判斷。
例如,下列屬性嘗試用數學運算讓屬性編輯器顯示預設值 5,但這樣並不會如預期運作:
[Export]
public int NumberWithBackingField
{
get => _number + 3;
set => _number = value - 3;
}
private int _number = 2;
分析器無法解析這段程式碼,因此會回退為 int 的預設值 0。但執行場景或檢查有 tool script 的節點時,_number 會是 2,而 NumberWithBackingField 會回傳 5。這樣的落差可能導致行為混淆。為避免這種情況,請避免用複雜屬性。如果可以明確指定預設值,也可用 _PropertyCanRevert() 和 _PropertyGetRevert() 方法覆寫。
任何 Resource 或 Node 型別都可以匯出。屬性編輯器會針對這些型別顯示易於指定的對話框。這通常可以取代 GD.Load 和 GetNode。詳見 節點與資源。
[Export]
public PackedScene PackedScene { get; set; }
[Export]
public RigidBody2D RigidBody2D { get; set; }
匯出屬性分組
可以在屬性編輯器(Inspector)中,透過 [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]
public 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; }
multiline 註記會讓編輯器顯示較大的欄位以編輯多行文字。
[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; }
匯出時加上單位提示
為匯出的變數顯示單位提示。適用於數值型別,如浮點數或向量:
[Export(PropertyHint.None, "suffix:m/s\u00b2")]
public float Gravity { get; set; } = 9.8f;
[Export(PropertyHint.None, "suffix:m/s")]
public Vector3 Velocity { get; set; }
在上述範例中,\u00b2 用來顯示「平方」符號(²)。
顏色
以紅、綠、藍、Alpha 值指定的標準顏色。
[Export]
public Color Color { get; set; }
以紅、綠、藍值指定顏色(Alpha 固定為 1)。
[Export(PropertyHint.ColorNoAlpha)]
public Color Color { get; set; }
節點
Nodes can also be directly exported without having to use NodePaths.
[Export]
public Node Node { get; set; }
也可以直接匯出特定型別的節點。在屬性檢視器按下「指派」後,顯示的節點列表會依指定型別過濾,只能指派符合型別的節點。
[Export]
public Sprite2D Sprite2D { get; set; }
自訂節點類別也能直接匯出。過濾行為取決於自訂類別是否為 全域類別。
如有需要,仍可如 Godot 3.x 一樣匯出 NodePath:
[Export]
public NodePath NodePath { get; set; }
public override void _Ready()
{
var node = GetNode(NodePath);
}
資源
[Export]
public Resource Resource { get; set; }
在屬性編輯器中,可以將資源檔從檔案總管拖拉到變數欄位。
不過,展開屬性檢視器下拉選單時,可能會顯示極長的類別清單。因此,若指定 Resource 的衍生型別,例如:
[Export]
public AnimationNode AnimationNode { get; set; }
下拉選單會只顯示 AnimationNode 及其所有衍生類別。也可使用自訂資源類別,詳見 C# 全域類別。
請注意,即使腳本在編輯器中未執行,匯出屬性仍可編輯。這可以搭配 「tool」模式腳本 使用。
匯出位元旗標
型別為帶有 [Flags] 屬性的列舉成員可以匯出,其值僅限於該列舉型別的成員。編輯器會在屬性檢視器建立即時元件,讓你可以選擇不選、單選或多選列舉成員。該值會以整數存儲。
列舉型別帶有 [Flags] 屬性時,成員值通常為 2 的冪次方。也可以用邏輯 OR(|)組合多個旗標成一個成員。
[Flags]
public enum SpellElements
{
Fire = 1 << 1,
Water = 1 << 2,
Earth = 1 << 3,
Wind = 1 << 4,
FireAndWater = Fire | Water,
}
[Export]
public SpellElements MySpellElements { get; set; }
以整數作為位元旗標時,可以在單一屬性內儲存多個 true / false``(布林)值。透過 ``Flags 屬性提示,可在編輯器中勾選任意旗標。
[Export(PropertyHint.Flags, "Fire,Water,Earth,Wind")]
public int SpellElements { get; set; } = 0;
必須為每個旗標提供說明字串。例如這裡,Fire 為 1、Water 為 2、Earth 為 4、Wind 為 8。通常也會定義對應常數(如 private const int ElementWind = 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; }
使用位元旗標需要基本的位元運算知識。如不熟悉,請改用布林變數。
匯出列舉(Enum)
型別為列舉的成員可以匯出,其值僅限於列舉型別的成員。編輯器會在屬性檢視器產生元件,將下列選項列舉為「Thing 1」、「Thing 2」、「Another Thing」。該值會以整數儲存。
public enum MyEnum
{
Thing1,
Thing2,
AnotherThing = -1,
}
[Export]
public MyEnum MyEnumCurrent { get; set; }
也可以使用 [Export] 註記搭配 PropertyHint.Enum 限制整數或字串成員只能選擇特定值。編輯器會在屬性編輯器中產生元件,將下列選項列舉為 Warrior、Magician、Thief。該值會以整數儲存,對應所選項目的索引(即 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 文件所述,僅有部分 C# 陣列與 Godot.Collections 命名空間中定義的集合型別與 Variant 相容,因此只有這些型別可匯出。
匯出 Godot 陣列
[Export]
public Godot.Collections.Array Array { get; set; }
使用泛型 Godot.Collections.Array<T> 可指定陣列元素型別,編輯器會以此作為提示,Inspector 也會限制元素型別。
[Export]
public Godot.Collections.Array<string> Array { get; set; }
Godot 陣列的預設值為 null,可指定不同預設值:
[Export]
public Godot.Collections.Array<string> CharacterNames { get; set; } =
[
"Rebecca",
"Mary",
"Leah",
];
若指定為繼承自 Resource 的型別陣列,可從檔案系統面板拖拉多個檔案設定。
[Export]
public Godot.Collections.Array<Texture> Textures { get; set; }
[Export]
public Godot.Collections.Array<PackedScene> Scenes { get; set; }
匯出 Godot 字典
[Export]
public Godot.Collections.Dictionary Dictionary { get; set; }
使用泛型 Godot.Collections.Dictionary<TKey, TValue> 可指定字典的鍵與值型別。
[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,
};
匯出 C# 陣列
只要元素型別是 Variant 相容型別,C# 陣列就可以匯出。
[Export]
public Vector3[] Vectors { get; set; }
[Export]
public NodePath[] NodePaths { get; set; }
C# 陣列的預設值為 null,可指定不同預設值:
[Export]
public Vector3[] Vectors { get; set; } =
[
new Vector3(1, 2, 3),
new Vector3(3, 2, 1),
];
從 tool 腳本設定匯出變數
從 工具模式 腳本中修改匯出變數值時,Inspector 上顯示的值不會自動更新。如要更新,請在設定匯出變數值後呼叫 NotifyPropertyListChanged()。
進階匯出
為避免語言設計過於複雜,並非所有匯出型別都能直接由語言層級提供。以下介紹一些常見但需使用低階 API 實現的匯出功能。
在深入閱讀之前,建議先熟悉屬性處理方式,以及如何透過 _Set()、_Get() 與 _GetPropertyList() 方法來自訂屬性,詳見 從物件中存取資料或邏輯。
也參考
如需在 C++ 中使用上述方法綁定屬性,請參閱 用 _set/_get/_get_property_list 綁定屬性。
警告
腳本必須運作於 tool 模式,上述方法才能於編輯器內運作。