Características de C#¶
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
El operador as
retorna null
si el nodo no puede ser convertido a Sprite, y por esta razón no puede ser usado en tipos "valor".
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 Lenguaje de 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);
Estas señales pueden ser conectadas en el editor o desde el código con "Connect". Si quieres conectar una señal en el editor, necesitas (re)construir los ensamblajes del proyecto para ver la nueva señal. Esta construcción puede ser activada manualmente haciendo clic en el botón "Build" en la esquina superior derecha de la ventana del 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");
}
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 array de Godot.
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 Godot.Collections.Array { 1 });
minusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { -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");
}
Defines de preprocesador¶
Godot tiene un conjunto de definiciones que le permiten cambiar su código C# dependiendo del entorno en el que esté compilando.
Nota
Si creaste tu proyecto antes de Godot 3.2, tienes que modificar o regenerar tu archivo csproj para usar esta característica (compara <DefineConstants>
con un nuevo proyecto 3.2+).
Ejemplos¶
Por ejemplo, puedes cambiar el código basado en la plataforma:
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
}
O puedes detectar en qué motor está tu código, útil para hacer bibliotecas de motores cruzados:
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
}
A continuación está la lista completa de hints¶
"GODOT" siempre está definido para los proyectos de Godot.
Uno de
GODOT_64
oGODOT_32
se define dependiendo de si la arquitectura es de 64 o 32 bits.Uno de
GODOT_X11
,GODOT_WINDOWS
,GODOT_OSX
,GODOT_ANDROID
,GODOT_IOS
,GODOT_HTML5
, oGODOT_SERVER
, dependiendo del sistema operativo. Estos nombres pueden cambiar en el futuro. Se crean desde el métodoget_name()
del singleton :ref:OS <class_OS>
, pero no todos los sistemas operativos posibles que el método devuelve son sistemas operativos en los que funciona Godot con Mono.
Cuando se exporta, también se puede definir lo siguiente dependiendo de las características de la exportación:
Una de
GODOT_PC
,GODOT_MOBILE
, oGODOT_WEB
dependiendo del tipo de plataforma.Uno de
GODOT_ARM64_V8A
oGODOT_ARMEABI_V7A
en Android sólo dependiendo de la arquitectura.Uno de
GODOT_ARM64
oGODOT_ARMV7
en iOS sólo dependiendo de la arquitectura.Cualquiera de
GODOT_S3TC
,GODOT_ETC
yGODOT_ETC2
dependiendo del tipo de compresión de textura.Cualquier característica personalizada añadida en el menú de exportación se escribirá en mayúsculas y con el prefijo:
foo
->GODOT_FOO
.
Para ver un proyecto de ejemplo, revisa la demo de pruebas de SO: https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test