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.

Exportierte Propertys in C#

In Godot können Klassenmember exportiert werden. Das bedeutet, dass ihr Wert zusammen mit der Ressource (z. B. der Szene) gespeichert wird, der sie zugeordnet sind. Sie sind dann auch für die Bearbeitung im Property-Editor verfügbar. Das Exportieren wird mit dem [Export]-Attribut durchgeführt.

using Godot;

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

In diesem Beispiel wird der Wert 5 gespeichert und nach dem Erstellen des aktuellen Projekts im Property-Editor angezeigt.

Einer der größten Vorteile exportierter Variablen ist, dass diese im Editor sichtbar und veränderbar sind. Auf diese Weise können Grafiker, Spiele-Designer, etc. diese Werte verändert, die dann das Spielgeschehen beeinflussen. Hierfür gibt es eine spezielle Export-Syntax.

Exportieren kann nur mit Variantenkompatible Typen durchgeführt werden.

Bemerkung

Der Export von Propertys kann auch in GDScript erfolgen, Informationen dazu finden Sie unter GDScript exportierte Propertys.

Grundlegende Verwendung

Exportieren funktioniert mit Feldern und Propertys. Sie können einen beliebigen Zugangsmodifikator haben.

[Export]
private int _number;

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

Exportierte Member können einen Defaultwert angeben; andernfalls wird stattdessen der Defaultwert des Typs verwendet.

Ein int wie Number hat den Defaultwert 0. Text hat den Defaultwert null, da string ein Referenztyp ist.

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

[Export]
public string Text { get; set; }

Für Felder und Propertys können Defaultwerte angegeben werden.

[Export]
private string _greeting = "Hello World";

[Export]
public string Greeting { get; set; } = "Hello World";

Propertys mit einem Hintergrundfeld verwenden den Defaultwert des Hintergrundfeldes.

private int _number = 2;

[Export]
public int NumberWithBackingField
{
    get => _number;
    set => _number = value;
}

Bemerkung

Das get einer Property wird nicht tatsächlich ausgeführt, um den Defaultwert zu bestimmen. Stattdessen analysiert Godot den C#-Quellcode. Das funktioniert in den meisten Fällen gut, wie zum Beispiel bei den Beispielen auf dieser Seite. Einige Propertys sind jedoch zu komplex, als dass der Analyzer sie verstehen könnte.

Die folgende Property versucht zum Beispiel, den Defaultwert als 5 im Property-Editor anzuzeigen, aber es funktioniert nicht:

[Export]
public int NumberWithBackingField
{
    get => _number + 3;
    set => _number = value - 3;
}

private int _number = 2;

Der Analyzer versteht diesen Code nicht und greift auf den Defaultwert für int, 0, zurück. Wenn die Szene jedoch läuft oder ein Node mit einem angehängten Tool-Skript untersucht wird, ist _number gleich 2, und NumberWithBackingField gibt 5 zurück. Dieser Unterschied kann zu verwirrendem Verhalten führen. Um dies zu vermeiden, verwenden Sie keine komplexen Propertys. Wenn der Defaultwert explizit angegeben werden kann, kann er alternativ mit den Methoden _PropertyCanRevert() und _PropertyGetRevert() überladen werden.

Jeder Typ von Ressource oder Node kann exportiert werden. Der Property-Editor zeigt einen benutzerfreundlichen Zuweisungsdialog für diese Typen. Dieser kann anstelle von GD.Load und GetNode verwendet werden. Siehe Nodes und Ressourcen.

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

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

Gruppieren der Exporte

Es ist möglich, die exportierten Propertys innerhalb des Inspektors mit dem Attribut [ExportGroup] zu gruppieren. Jede exportierte Property nach diesem Attribut wird zu dieser Gruppe hinzugefügt. Beginnen Sie eine neue Gruppe oder verwenden Sie [ExportGroup("")], um sie abzubrechen.

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

Das zweite Argument des Attributs kann verwendet werden, um nur Propertys mit dem angegebenen Präfix zu gruppieren.

Gruppen können nicht verschachtelt werden, verwenden Sie [ExportSubgroup] um Untergruppen innerhalb einer Gruppe zu erstellen.

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

Sie können auch den Namen Ihrer Hauptkategorie ändern oder zusätzliche Kategorien in der Property-Liste mit dem Attribut [ExportCategory] erstellen.

[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;

Bemerkung

Die Liste der Propertys ist auf der Grundlage der Klassenvererbung organisiert, und neue Kategorien brechen mit dieser Erwartung. Verwenden Sie sie sorgfältig, insbesondere bei der Erstellung von Projekten für die öffentliche Nutzung.

Strings als Pfade

Property-Hints können verwendet werden, um Strings als Pfade zu exportieren

String als Pfad zu einer Datei.

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

String als Pfad zu einem Verzeichnis.

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

String als Pfad zu einer Datei, benutzerdefinierter Filter wird als Hint angegeben.

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

Die Verwendung von Pfaden im globalen Dateisystem ist ebenfalls möglich, allerdings nur in Skripten im Tool-Modus.

String als Pfad zu einer PNG-Datei im globalen Dateisystem.

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

String als Pfad zu einem Verzeichnis im globalen Dateisystem.

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

Die mehrzeilige Annotation weist den Editor an, ein großes Eingabefeld zur Bearbeitung über mehrere Zeilen anzuzeigen.

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

Begrenzung der Eingabebereiche des Editors

Mit Hilfe des Range Property-Hints können Sie einschränken, was mit dem Editor als Wert eingegeben werden kann.

Erlauben von Integer-Werten zwischen 0 und 20.

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

Erlauben von Integer-Werten zwischen -10 und 20.

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

Erlauben von Floats zwischen -10 und 20 und Einrasten des Wertes auf Vielfache von 0.2.

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

Wenn Sie die Hints "or_greater" und/oder "or_less" hinzufügen, können Sie beim Einstellen des Wertes über oder unter die Grenzen gehen, indem Sie ihn eingeben, anstatt den Schieberegler zu verwenden.

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

Floats mit Easing-Hint

Display a visual representation of the ease function when editing.

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

Export with suffix hint

Display a unit hint suffix for exported variables. Works with numeric types, such as floats or vectors:

[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; }

In the above example, \u00b2 is used to write the "squared" character (²).

Farben

Normale Farbe, die als Rot-Grün-Blau-Alpha-Wert angegeben wird.

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

Die Farbe wird als Rot-Grün-Blau-Wert angegeben (Alpha ist immer 1).

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

Nodes

Seit Godot 4.0 können Nodes direkt exportiert werden, ohne NodePaths verwenden zu müssen.

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

Ein bestimmter Node-Typ kann auch direkt exportiert werden. Die Liste der Nodes, die nach dem Drücken von "Zuweisen" im Inspektor angezeigt wird, wird nach dem angegebenen Typ gefiltert, und nur ein korrekter Node kann zugewiesen werden.

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

Benutzerdefinierte Node-Klassen können auch direkt exportiert werden. Das Filterverhalten hängt davon ab, ob die benutzerdefinierte Klasse eine globale Klasse ist.

Das Exportieren von NodePaths wie in Godot 3.x ist immer noch möglich, falls Sie es benötigen:

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

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

Ressourcen

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

Im Inspektor können Sie dann eine Ressourcendatei aus dem Dateisystem-Dock per Drag&Drop in den Variablenslot ziehen.

Das Öffnen des Inspektor-Dropdowns kann jedoch zu einer extrem langen Liste möglicher zu erstellender Klassen führen. Wenn Sie daher einen von Resource abgeleiteten Typ angeben, z.B.:

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

The drop-down menu will be limited to AnimationNode and all its derived classes. Custom resource classes can also be used, see Globale C#-Klassen.

Es ist zu beachten, dass die exportierten Propertys auch dann editierbar sind, wenn das Skript im Editor nicht ausgeführt wird. Dies kann in Verbindung mit einem Skript im "Tool"-Modus verwendet werden.

Exportieren von Bit-Flags

Member, deren Typ ein Enum mit dem Attribut [Flags] ist, können exportiert werden und ihre Werte sind auf die Member des Enum-Typs beschränkt. Der Editor erzeugt ein Widget im Inspektor, das es erlaubt, keines, eines oder mehrere der Enum-Mitglieder auszuwählen. Der Wert wird als Integer gespeichert.

Ein Flags-Enum verwendet Zweierpotenzen für die Werte der Enum-Member. Member, die mehrere Flags mit logischem OR (|) kombinieren, sind ebenfalls möglich.

[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; }

Integer, die als Bit-Flags verwendet werden, können mehrere true/false (boolesche)-Werte in einer Property speichern. Durch die Verwendung des Property-Hints Flags kann jedes der angegebenen Flags vom Editor aus gesetzt werden.

[Export(PropertyHint.Flags, "Fire,Water,Earth,Wind")]
public int SpellElements { get; set; } = 0;

Sie müssen für jedes Flag eine Beschreibung angeben. In diesem Beispiel hat Fire den Wert 1, Water den Wert 2, Earth den Wert 4 und Wind entspricht dem Wert 8. Normalerweise sollten Konstanten entsprechend definiert werden (z.B. private const int ElementWind = 8 und so weiter).

Sie können explizite Werte mit einem Doppelpunkt hinzufügen:

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

Als Bit-Flag-Optionen sind nur Werte in 2er-Potenzen zulässig. Der niedrigste zulässige Wert ist 1, da 0 bedeutet, dass nichts ausgewählt ist. Sie können auch Optionen hinzufügen, die eine Kombination aus anderen Flags sind:

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

Für die in den Projekteinstellungen definierten Physik- und Renderebenen werden ebenfalls Exportkommentare bereitgestellt.

[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; }

Die Verwendung von Bit-Flags erfordert ein gewisses Verständnis der bitweisen Operationen. Verwenden Sie im Zweifelsfall stattdessen boolesche Variablen.

Exportieren von Enums

Member, deren Typ ein Enum ist, können exportiert werden und ihre Werte sind auf die Member des Enum-Typs beschränkt. Der Editor erstellt ein Widget im Inspector, das die folgenden Elemente aufzählt: "Ding 1", "Ding 2", "Noch ein Ding". Der Wert wird als Integer gespeichert.

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

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

Integer- und String-Members können auch auf eine bestimmte Liste von Werten beschränkt werden, indem die [Export]-Annotation mit dem PropertyHint.Enum-Hinweis verwendet wird. Der Editor erstellt ein Widget im Inspektor, das die folgenden Werte aufzählt: Warrior, Magician, Thief. Der Wert wird als Integer gespeichert, wobei der Index der ausgewählten Option entspricht (d.h. 0, 1 oder 2).

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

Sie können explizite Werte mit einem Doppelpunkt hinzufügen:

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

Wenn der Typ String ist, wird der Wert als String gespeichert.

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

Wenn Sie einen Initialwert setzen wollen, müssen Sie diesen explizit angeben:

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

Exporting inspector buttons with [ExportToolButton]

If you want to create a clickable button in the inspector, you can use the [ExportToolButton] attribute. This exports a Callable property or field as a clickable button. Since this runs in the editor, usage of the [Tool] attribute is required. When the button is pressed, the callable is called:

[Tool]
public partial class MyNode : Node
{
    [ExportToolButton("Click me!")]
    public Callable ClickMeButton => Callable.From(ClickMe);

    public void ClickMe()
    {
        GD.Print("Hello world!");
    }
}

You can also set an icon for the button with a second argument. If specified, an icon will be fetched via GetThemeIcon(), from the "EditorIcons" theme type.

[ExportToolButton("Click me!", Icon = "CharacterBody2D")]
public Callable ClickMeButton => Callable.From(ClickMe);

Exportieren von Collections

Wie in der C# Variant-Dokumentation erläutert, sind nur bestimmte C#-Arrays und die im Godot.Collections-Namespace definierten Collection-Typen Variant-kompatibel, daher können nur diese Typen exportiert werden.

Exportieren von Godot-Arrays

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

Die Verwendung des generischen Godot.Collections.Array<T> erlaubt die Angabe des Typs der Array-Elemente, die als Hint für den Editor verwendet werden. Der Inspektor beschränkt die Elemente auf den angegebenen Typ.

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

Der Defaultwert von Godot-Arrays ist null. Ein anderer Defaultwert kann angegeben werden:

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

Arrays mit bestimmten Typen, die von Resource erben, können durch Drag&Drop mehrerer Dateien aus dem Dateisystem-Dock gesetzt werden.

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

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

Exportieren von Godot-Dictionarys

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

Die Verwendung des generischen Godot.Collections.Dictionary<TKey, TValue> erlaubt es, den Typ der Key- und Value-Elemente des Dictionarys zu spezifizieren.

Bemerkung

Typisierte Dictionarys werden derzeit im Godot-Editor nicht unterstützt, so dass der Inspektor die Typen, die zugewiesen werden können, nicht einschränkt, was zu Laufzeit-Exceptions führen kann.

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

Der Defaultwert von Godot-Dictionarys ist null. Ein anderer Defaultwert kann angegeben werden:

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

Exportieren von C#-Arrays

C#-Arrays können exportiert werden, solange der Elementtyp ein Variant-kompatibler-Typ ist.

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

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

Der Defaultwert von C#-Arrays ist null. Ein anderer Default kann angegeben werden:

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

Festlegen exportierter Variablen aus einem Tool-Skript

Wenn Sie den Wert einer exportierten Variablen aus einem Skript im Tool-Modus ändern, wird der Wert im Inspektor nicht automatisch aktualisiert. Um ihn zu aktualisieren, rufen Sie NotifyPropertyListChanged() auf, nachdem Sie den Wert der exportierten Variable gesetzt haben.

Fortgeschrittene Exporte

Nicht jede Art von Export kann auf der Sprachebene selbst bereitgestellt werden, um unnötige Designkomplexität zu vermeiden. Im Folgenden werden einige mehr oder weniger häufig verwendete Exportfunktionen beschrieben, die mit einer Low-Level-API implementiert werden können.

Bevor Sie weiter lesen, sollten Sie sich mit der Art und Weise vertraut machen, wie Propertys behandelt werden und wie sie mit _Set(), _Get(), und _GetPropertyList()-Methoden angepasst werden können, wie in Zugriff auf Daten oder Logik aus einem Objekt beschrieben.

Siehe auch

Informationen zum Binden von Propertys mit den oben genannten Methoden in C++ finden Sie unter Binding von Propertys mit _set/_get/_get_property_list.

Warnung

Das Skript muss im Tool -Modus arbeiten, damit die oben genannten Methoden im Editor ausgeführt werden können.