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

Métodos genéricos também são providenciados para fazer esse tipo de conversão transparente.

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

Esses sinais podem então ser conectados no editor ou no código com Connect. Se você quiser conectar um sinal no editor, você precisa (re)build as DLLs do projeto para ver o novo sinal. Esta compilação pode ser acionada manualmente clicando no botão “Build” no canto superior direito da janela do editor.

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

Preprocessor defines

Godot has a set of defines that allow you to change your C# code depending on the environment you are compiling to.

Nota

If you created your project before Godot 3.2, you have to modify or regenerate your csproj file to use this feature (compare <DefineConstants> with a new 3.2+ project).

Exemplos

For example, you can change code based on the platform:

    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
    }

Or you can detect which engine your code is in, useful for making cross-engine libraries:

    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
    }

Full list of defines

  • GODOT is always defined for Godot projects.
  • Um dos GODOT_64 ou GODOT_32 é definido dependendo se a arquitetura é 64-bit ou 32-bit.
  • One of GODOT_X11, GODOT_WINDOWS, GODOT_OSX, GODOT_ANDROID, 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 :ref:OS <class_OS> singleton, but not every possible OS the method returns is an OS that Godot with Mono runs on.

When exporting, the following may also be defined depending on the export features:

  • One of GODOT_PC, GODOT_MOBILE, or GODOT_WEB depending on the platform type.
  • One of GODOT_ARM64_V8A or GODOT_ARMEABI_V7A on Android only depending on the architecture.
  • Um dos GODOT_S3TC, GODOT_ETC, ou GODOT_ETC2, dependendo do tipo de compressão de textura.
  • Any custom features added in the export menu will be capitalized and prefixed: foo -> GODOT_FOO.