Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Scripting de varios lenguajes

Godot permite mezclar lenguajes de script según tus necesidades. Esto quiere decir que un proyecto puede definir nodos en C# y GDScript. Esta página mostrará las posibles interacciones entre dos nodos escritos en diferentes lenguajes.

Los siguientes dos scripts se utilizarán como referencias a lo largo de esta página.

extends Node

var my_field: String = "foo"

func print_node_name(node: Node) -> void:
    print(node.get_name())

func print_array(arr: Array) -> void:
    for element in arr:
        print(element)

func print_n_times(msg: String, n: int) -> void:
    for i in range(n):
        print(msg)

Instanciando nodos

Si no estás usando nodos del árbol de escena, probablemente quieras instanciar nodos directamente desde código.

Instanciando nodos C# desde GDScript

Usar C# de GDScript no necesita mucho trabajo. Una vez cargado (ver Clases como recursos), el script puede ser instanciado con new().

var my_csharp_script = load("res://Path/To/MyCSharpNode.cs")
var my_csharp_node = my_csharp_script.new()

Advertencia

Cuando se crea un script .cs, ten siempre en mente que la clase que usará Godot es la que está nombrada como el archivo .cs. Si esa clase no existe en el archivo, verás el siguiente error: Invalid call. Nonexistent function `new` in base.

Por ejemplo, "MyCoolNode.cs"debe contener una clase llamada "MyCoolNode".

The C# class needs to derive a Godot class, for example GodotObject. Otherwise, the same error will occur.

También necesitas revisar que tu archivo .cs esté referenciado en el archivo de proyecto``.csproj``. De otro modo sucederá el mismo error.

Instanciando nodos GDScript desde C#

Desde el lado de C#, todo funciona de la misma manera. Una vez cargado, el GDScript puede ser instanciado con GDScript.New().

GDScript MyGDScript = GD.Load<GDScript>("res://path/to/my_gd_script.gd");
GodotObject myGDScriptNode = (GodotObject)MyGDScript.New(); // This is a GodotObject.

Aquí usaremos un Object, pero puedes usar conversión de tipos como está explicado en Conversión de tipo y casting.

Accediendo campos

Accediendo campos C# desde GDScript

Acceder a los campos C# desde GDScript es sencillo, no deberías tener nada de qué preocuparte.

print(my_csharp_node.myField) # bar
my_csharp_node.myField = "BAR"
print(my_csharp_node.myField) # BAR

Accediendo a los campos de GDScript desde C#

As C# is statically typed, accessing GDScript from C# is a bit more convoluted, you will have to use GodotObject.Get() and GodotObject.Set(). The first argument is the name of the field you want to access.

GD.Print(myGDScriptNode.Get("my_field")); // foo
myGDScriptNode.Set("my_field", "FOO");
GD.Print(myGDScriptNode.Get("my_field")); // FOO

Ten en cuenta que al establecer un valor de campo sólo debes usar los tipos que el lado GDScript conoce. Esencialmente, quieres trabajar con tipos incorporados como se describe en GDScript reference o clases que se extienden Object.

Llamando métodos

Llamando métodos C# desde GDScript

Una vez más, llamar a métodos C# desde GDScript debería ser sencillo. El proceso de clasificación hará todo lo posible para convertir los argumentos para que coincidan con las firmas de funciones. Si eso es imposible, verá el siguiente error: Llamada no válida. Función `FunctionName` inexistente.

my_csharp_node.PrintNodeName(self) # myGDScriptNode
# my_csharp_node.PrintNodeName() # This line will fail.

my_csharp_node.PrintNTimes("Hello there!", 2) # Hello there! Hello there!

my_csharp_node.PrintArray(["a", "b", "c"]) # a, b, c
my_csharp_node.PrintArray([1, 2, 3]) # 1, 2, 3

Llamando métodos GDScript desde C#

To call GDScript methods from C# you'll need to use GodotObject.Call(). The first argument is the name of the method you want to call. The following arguments will be passed to said method.

myGDScriptNode.Call("print_node_name", this); // my_csharp_node
// myGDScriptNode.Call("print_node_name"); // This line will fail silently and won't error out.

myGDScriptNode.Call("print_n_times", "Hello there!", 2); // Hello there! Hello there!

string[] arr = new string[] { "a", "b", "c" };
myGDScriptNode.Call("print_array", arr); // a, b, c
myGDScriptNode.Call("print_array", new int[] { 1, 2, 3 }); // 1, 2, 3
// Note how the type of each array entry does not matter as long as it can be handled by the marshaller.

Advertencia

Como puedes ver, si el primer argumento del método llamado es un array, necesitarás lanzarlo como "object". De lo contrario, cada elemento de tu array será tratado como un único argumento y la firma de la función no coincidirá.

Herencia

Un archivo GDSCript no puede heredar de un script C# del mismo en que un script C# no puede heredar de un archivo GDScript. Debido a la complejidad que llevaría implementarla, es poco probable que esta limitación sea cambiada en el futuro. Ver esta issue en GitHub para más información.