C# Merkmale

Diese Seite bietet einen Überblick über die häufig verwendeten Funktionen von C# und Godot und wie sie zusammen verwendet werden.

Typumwandlung und Casting

C# ist eine statische Programmiersprache, daher ist dies hier nicht möglich:

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

Die Methode GetNode() liefert eine Node Instance. Diese muss nun in den gewünschten abgeleiteten Typ konvertiert werden , Sprite in diesem Fall.

Hierfür gibt es verschiedene Möglichkeiten in C#.

Casting und Typprüfung

Löst InvalidCastException aus, wenn der zurückgegebene Node nicht in Sprite umgewandelt werden kann. Sie können es anstelle des Operators as verwenden, wenn Sie sich sicher sind, dass es nicht fehlschlagen wird.

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

Nutzen des AS Operators

Der as Operator liefert null falls der Node nicht als Sprite genutzt werden kann, daher kann es nicht mit Wert Typen genutzt werden.

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

Nutzen der allgemeinen Methoden

Es werden auch generische Methoden bereitgestellt, um diese Typkonvertierung transparent zu machen.

GetNode<T>() wandelt den Node um, bevor er zurückgegeben wird. Es wird eine InvalidCastException ausgelöst, wenn der Node nicht in den gewünschten Typ umgewandelt werden kann.

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

GetNodeOrNull<T>() verwendet den Operator as und gibt null zurück, wenn der Node nicht in den gewünschten Typ umgewandelt werden kann.

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

Typprüfung mit dem IS-Operator

Um zu überprüfen, ob der Node in Sprite umgewandelt werden kann, können Sie den Operator is verwenden. Der Operator is gibt "false" zurück, wenn der Node nicht in Sprite umgewandelt werden kann, andernfalls gibt er "true" zurück.

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

Weitere Informationen zur Typprüfung finden Sie unter Pattern Matching.

C# Signale

Ein vollständiges C# Beispiel finden Sie im Abschnitt Behandeln eines Signals in der Schritt-für-Schritt-Anleitung Skriptsprachen.

Das Deklarieren eines Signals in C# erfolgt mit dem Attribut [Signal] eines Beauftragten.

[Signal]
delegate void MySignal();

[Signal]
delegate void MySignalWithArguments(string foo, int bar);

Diese Signale können dann entweder im Editor oder aus Code mit Connect verbunden werden. Wenn Sie ein Signal im Editor verbinden möchten, müssen Sie die Projektassemblys (neu) erstellen, um das neue Signal anzuzeigen. Dieser Build kann manuell ausgelöst werden, indem Sie auf die Schaltfläche "Build" in der oberen rechten Ecke des Editorfensters klicken.

public void MyCallback()
{
    GD.Print("My callback!");
}

public void MyCallbackWithArguments(string foo, int bar)
{
    GD.Print("My callback with: ", foo, " and ", bar, "!");
}

public void SomeFunction()
{
    instance.Connect("MySignal", this, "MyCallback");
    instance.Connect(nameof(MySignalWithArguments), this, "MyCallbackWithArguments");
}

Das Senden von Signalen erfolgt mit der Methode EmitSignal.

public void SomeFunction()
{
    EmitSignal(nameof(MySignal));
    EmitSignal("MySignalWithArguments", "hello there", 28);
}

Beachten Sie, dass Sie einen Signalnamen immer mit dem Schlüsselwort nameof referenzieren können (angewendet auf den Beauftragten selbst).

Es ist möglich, beim Verbindungsaufbau Werte zu binden, indem ein Godot-Array übergeben wird.

public int Value { get; private set; } = 0;

private void ModifyValue(int modifier)
{
    Value += modifier;
}

public void SomeFunction()
{
    var plusButton = (Button)GetNode("PlusButton");
    var minusButton = (Button)GetNode("MinusButton");

    plusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { 1 });
    minusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { -1 });
}

Signale unterstützen Parameter und sind an alle Werte der eingebauten Typen und den Klassen Godot.Object, aus denen sie übernommen sind, gebunden. Daraus folgend, sind Nodes oder Referenzen automatisch kompatibel. Eigene Datenobjekte müssen an Godot.Object oder einer seiner Unterklassen anbauen.

public class DataObject : Godot.Object
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
}

Abschließend, Signale können durchs aufrufen von AddUserSignal erstellt werden, jedoch seien sie vorsichtig, dass dies durchgeführt, bevor das betroffene Signal benutzt wird (durch Connect oder EmitSignal).

public void SomeFunction()
{
    AddUserSignal("MyOtherSignal");
    EmitSignal("MyOtherSignal");
}

Präprozessor Festlegungen

Godot verfügt über eine Reihe von Definitionen, mit denen Sie Ihren C# Code abhängig von der Umgebung in die Sie kompilieren ändern können.

Bemerkung

Wenn Sie Ihr Projekt vor Godot 3.2 erstellt haben, müssen Sie Ihre csproj Datei ändern oder neu generieren, um diese Funktion zu verwenden (vergleichen Sie <DefineConstants> mit einem neuen 3.2+ -Projekt).

Beispiele

Sie können beispielsweise den Code basierend auf der Plattform ändern:

    public override void _Ready()
    {
#if GODOT_SERVER
        // Don't try to load meshes or anything, this is a server!
        LaunchServer();
#elif GODOT_32 || GODOT_MOBILE || GODOT_WEB
        // Use simple objects when running on less powerful systems.
        SpawnSimpleObjects();
#else
        SpawnComplexObjects();
#endif
    }

Oder Sie können erkennen in welcher Engine sich Ihr Code befindet, was für die Erstellung von Cross-Engine-Bibliotheken hilfreich ist:

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

Vollständige Liste von Definitionen

  • GODOT wird immer in den Godot Einstellungen definiert.

  • Ob GODOT_64 oder GODOT_32 definiert wird, ist abhängig von der Architektur 64-bit oder 32-bit.

  • One of GODOT_X11, GODOT_WINDOWS, GODOT_OSX, GODOT_ANDROID, GODOT_IOS, GODOT_HTML5, or GODOT_SERVER depending on the OS. These names may change in the future. These are created from the get_name() method of the OS singleton, but not every possible OS the method returns is an OS that Godot with Mono runs on.

Beim Exportieren kann Folgendes auch abhängig von den Exportfunktionen definiert werden:

  • Je nach Plattformtyp eine von GODOT_PC, GODOT_MOBILE oder GODOT_WEB.

  • Eine von GODOT_ARM64_V8A oder GODOT_ARMEABI_V7A auf Android je nach Architektur.

  • Einer von GODOT_ARM64 oder GODOT_ARMV7 unter iOS abhängig von der Architektur.

  • Je nach Texturkomprimierungstyp GODOT_S3TC, GODOT_ETC und GODOT_ETC2.

  • Alle benutzerdefinierten Funktionen, die im Exportmenü hinzugefügt wurden, werden großgeschrieben und mit dem Präfix foo -> GODOT_FOO versehen.

Ein Beispielprojekt finden Sie in der OS-Testdemo: https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test