Funkcjonalności

This page provides an overview of the commonly used features of both C# and Godot and how they are used together.

Type conversion and casting

C# is a statically typed language. Therefore, you can’t do the following:

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

Metoda GetNode() zwraca instancję Węzeła. Musisz wyraźnie przekształcić go na żądany typ pochodny, w tym przypadku Sprite.

W tym celu w C# masz różne opcje.

Rzutowanie i sprawdzanie typu

Throws InvalidCastException if the returned node cannot be cast to Sprite. You would use it instead of the as operator if you are pretty sure it won’t fail.

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

Używanie AS jako operator

The as operator returns null if the node cannot be cast to Sprite, and for that reason, it cannot be used with value types.

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

Using the generic methods

Generic methods are also provided to make this type conversion transparent.

GetNode<T>() casts the node before returning it. It will throw an InvalidCastException if the node cannot be cast to the desired type.

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

GetNodeOrNull<T>() uses the as operator and will return null if the node cannot be cast to the desired type.

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

**Sprawdzanie **

To check if the node can be cast to Sprite, you can use the is operator. The is operator returns false if the node cannot be cast to Sprite, otherwise it returns true.

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

W celu bardziej zaawansowanego sprawdzania typu, można zajrzeć do Dopasowywanie wzorów.

C# signals

Kompletny przykład C#, patrz Zarządzanie sygnałem w sekcji krok po kroku Skrypty.

Deklaracja sygnału w C# odbywa się z atrybutem [Signal].

[Signal]
delegate void MySignal();

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

Sygnały te mogą być podłączone w edytorze lub z kodu za pomocą Connect.

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");
}

Sygnały emitowane są metodą EmitSignal.

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

Zauważ, że zawsze można odwołać się do nazwy sygnału za pomocą słowa kluczowego nameof.

It is possible to bind values when establishing a connection by passing an object array.

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 object[] { 1 });
    minusButton.Connect("pressed", this, "ModifyValue", new object[] { -1 });
}

Signals support parameters and bound values of all the built-in types and Classes derived from Godot.Object. Consequently, any Node or Reference will be compatible automatically, but custom data objects will need to extend from Godot.Object or one of its subclasses.

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

Sygnały mogą być tworzone przez wywołanie AddUserSignal, należy jednak pamiętać, że powinny być one wykonywane przed użyciem tych sygnałów (za pomocą Connect lub EmitSignal).

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