Funcionalidades

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

O método GetNode() retorna uma instância do Node. Você deve explicitamente converter para o tipo derivado desejado, Sprite neste caso.

Para isso, você tem várias opções em C#.

Casting e Verificação de Tipo

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

Usando o operador AS

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>() faz a conversão do nó antes de retorná-lo. Um erro do tipo InvalidCastException será retornado caso o nó não possa ser convertido para o tipo desejado.

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

Verificação de tipo usando o operador IS

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!
}

Para uma verificação de tipos mais avançada, você pode procurar em Correspondência de Padrões.

C# signals

Para um exemplo completo de C#, veja a seção Manipulando um sinal no tutorial passo a passo: ref: doc_scripting.

A declaração de um sinal em C# é feito com o atributo [Signal] em um delegate.

[Signal]
delegate void MySignal();

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

Estes sinais podem então ser conectados no editor ou no código com o 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");
}

A emissão de sinais é feita com o método EmitSignal.

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

Observe que você sempre pode referenciar um nome de sinal com a palavra-chave nameof (aplicada no próprio delegate).

É possível vincular valores ao estabelecer uma conexão passando um objeto 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; }
}

Finalmente, os sinais podem ser criados chamando AddUserSignal, mas esteja ciente de que ele deve ser executado antes de qualquer uso de tais sinais (com Connect ou EmitSignal).

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