Características

Esta página provee un resumen acerca de las características comunmente utilizadas en C# y Godot y cómo son usadas.

Conversión de tipo y casting

C# es un lenguaje estáticamente tipado, por lo tanto, no puedes hacer lo siguiente:

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

El método GetNode() retorna una instancia Node. Se debe convertir explícitamente al tipo derivado deseado, Sprite en este caso.

Para esto, hay varias opciones en C#.

Casting & Chequeo de Tipo

Lanza InvalidCastException si el valor retornado no puede ser convertido a Sprite. Se utiliza en lugar del operador as si se está seguro que no fallará.

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

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

Utilizando métodos genéricos

Los métodos genéricos se proveen para hacer la conversión de tipo transparente.

GetNode<T>() realiza un casting del nodo antes de retornarlo. Lanzará una InvalidCastException si el nodo no puede ser convertido al tipo deseado.

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

GetNodeOrNull<T>() usa el operador as y retornará null si el nodo no puede ser convertido al tipo deseado.

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

Chequeo de tipo usando el operador IS

Para comprobar si un nodo puede ser convertido a Sprite, puedes usar el operador is. Este operador retorna false si el nodo no puede ser convertido a Sprite, de otro modo, retorna true.

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

Para tipos avanzados de comprobaciones, puedes mirar Pattern Matching.

Señales en C#

Para ejemplos completos de C#, ver la sección Manipulando una señal en el tutorial paso a paso Scripting.

Una señal en C# se declara mediante el atributo [Signal] en un delegate.

[Signal]
delegate void MySignal();

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

These signals can then be connected either in the editor or from code with Connect. If you want to connect a signal in the editor, you need to (re)build the project assemblies to see the new signal. This build can be manually triggered by clicking the “Build” button at the top right corner of the editor window.

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

Las señales se emiten con el método EmitSignal.

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

Tener en cuenta que se puede hacer referenciar a una señal con la palabra clave nameof (aplicado al delegate).

Es posible vincular valores al establecer una conexión pasando un 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 });
}

Las señales soportan parámetros y valores vinculados de todos los tipos built-in y clases derivadas de Godot.Object. Consecuentemente, cualquier Node o Reference será compatible automaticamente, pero objetos de datos personalizados deberán extender de Godot.Object o alguna de sus subclases.

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

Finalmente, las señales pueden ser creadas llamando AddUserSinal, pero tener en cuenta que debe ser ejecutado antes de la utilización de dicha señal (con Connect o 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).

Ejemplos

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.
  • One of GODOT_64 or GODOT_32 is defined depending on if the architecture is 64-bit or 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.
  • One of GODOT_S3TC, GODOT_ETC, or GODOT_ETC2 depending on the texture compression type.
  • Any custom features added in the export menu will be capitalized and prefixed: foo -> GODOT_FOO.