Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Scripting entre linguagens
O Godot permite que você misture e combine linguagens de script para atender às suas necessidades. Isso significa que um único projeto pode definir nós tanto em C# quanto em GDScript. Esta página passará pelas possíveis interações entre dois nós escritos em diferentes linguagens.
Os dois scripts a seguir serão usados como referências ao longo desta página.
extends Node
var my_property: String = "my gdscript value":
get:
return my_property
set(value):
my_property = value
signal my_signal
signal my_signal_with_params(msg: String, n: int)
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)
func my_signal_handler():
print("The signal handler was called!")
func my_signal_with_params_handler(msg: String, n: int):
print_n_times(msg, n)
using Godot;
public partial class MyCSharpNode : Node
{
public string MyProperty { get; set; } = "my c# value";
[Signal] public delegate void MySignalEventHandler();
[Signal] public delegate void MySignalWithParamsEventHandler(string msg, int n);
public void PrintNodeName(Node node)
{
GD.Print(node.Name);
}
public void PrintArray(string[] arr)
{
foreach (string element in arr)
{
GD.Print(element);
}
}
public void PrintNTimes(string msg, int n)
{
for (int i = 0; i < n; ++i)
{
GD.Print(msg);
}
}
public void MySignalHandler()
{
GD.Print("The signal handler was called!");
}
public void MySignalWithParamsHandler(string msg, int n)
{
PrintNTimes(msg, n);
}
}
Instanciando nós
Se você não estiver usando nós da árvore da cena, provavelmente vai querer instanciar os nós diretamente do código.
Instanciando nós C# a partir do GDScript
Usar C# a partir do GDScript não precisa de muito trabalho. Uma vez carregado (veja Classes como recursos) o script pode ser instanciado com new().
var MyCSharpScript = load("res://Path/To/MyCSharpNode.cs")
var my_csharp_node = MyCSharpScript.new()
Aviso
Ao criar scripts .cs você deve sempre ter em mente que a classe que o Godot usará é a nomeada como o próprio arquivo .cs. Se essa classe não existir no arquivo, você verá o seguinte erro: Chamada inválida. Função inexistente `new` na base.
Por exemplo, MyCoolNode.cs deve conter uma classe chamada MyCoolNode.
A classe C# precisa derivar de uma classe Godot, por exemplo GodotObject. Caso contrário, o mesmo erro ocorrerá.
Você também precisa verificar se seu arquivo .cs é referenciado no arquivo .csproj do projeto. Caso contrário, o mesmo erro ocorrerá.
Instanciando nós GDScript a partir do C#
Do lado C#, tudo funciona da mesma maneira. Uma vez carregado, um GDScript pode ser instanciado com GDScript.New().
var myGDScript = GD.Load<GDScript>("res://path/to/my_gd_script.gd");
var myGDScriptNode = (GodotObject)myGDScript.New(); // This is a GodotObject.
Aqui estamos usando um Object mas você pode usar conversão de tipo como explicado em Conversão de Tipos e Casting.
Acessando campos
Acessando campos C# a partir do GDScript
Acessar os campos do C# no GDScript é simples, você não deve ter nada com que se preocupar.
# Output: "my c# value".
print(my_csharp_node.MyProperty)
my_csharp_node.MyProperty = "MY C# VALUE"
# Output: "MY C# VALUE".
print(my_csharp_node.MyProperty)
Acessando campos do GDScript no C#
Como C# é estaticamente tipado, acessar GDScript a partir de C# é um pouco mais complexo. Você terá que usar GodotObject.Get() e GodotObject.Set(). O primeiro argumento é o nome do campo que você deseja acessar.
// Output: "my gdscript value".
GD.Print(myGDScriptNode.Get("my_property"));
myGDScriptNode.Set("my_property", "MY GDSCRIPT VALUE");
// Output: "MY GDSCRIPT VALUE".
GD.Print(myGDScriptNode.Get("my_property"));
Tenha em mente que, ao definir o valor de um campo, você deve usar apenas tipos que o lado do GDScript conhece. Essencialmente, você quer trabalhar com tipos nativos conforme descrito em Tipos definidos por padrão ou classes que estendem Object.
Chamando métodos
Chamando métodos C# a partir do GDScript
Novamente, chamar métodos de C# no GDScript deve ser simples. O processo de marshalling fará o seu melhor para converter seu argumento para bater com as assinaturas de funções. Se isso for impossível, você verá o seguinte erro: Chamada inválida. Função inexistente `FunctionName`.
# Output: "my_gd_script_node" (or name of node where this code is placed).
my_csharp_node.PrintNodeName(self)
# This line will fail.
# my_csharp_node.PrintNodeName()
# Outputs "Hello there!" twice, once per line.
my_csharp_node.PrintNTimes("Hello there!", 2)
# Output: "a", "b", "c" (one per line).
my_csharp_node.PrintArray(["a", "b", "c"])
# Output: "1", "2", "3" (one per line).
my_csharp_node.PrintArray([1, 2, 3])
Chamando métodos de GDScript no C#
Para chamar métodos de GDScript a partir de C#, você precisará usar GodotObject.Call(). O primeiro argumento é o nome do método que você deseja chamar. Os argumentos a seguir serão passados para o referido método.
// Output: "MyCSharpNode" (or name of node where this code is placed).
myGDScriptNode.Call("print_node_name", this);
// This line will fail silently and won't error out.
// myGDScriptNode.Call("print_node_name");
// Outputs "Hello there!" twice, once per line.
myGDScriptNode.Call("print_n_times", "Hello there!", 2);
string[] arr = ["a", "b", "c"];
// Output: "a", "b", "c" (one per line).
myGDScriptNode.Call("print_array", arr);
// Output: "1", "2", "3" (one per line).
myGDScriptNode.Call("print_array", new int[] { 1, 2, 3 });
// Note how the type of each array entry does not matter
// as long as it can be handled by the marshaller.
Conectando-se a sinais
Conectando a sinais C# a partir de GDScript
Conectar-se a um sinal de C# a partir do GDScript é o mesmo que se conectar a um sinal definido no GDScript:
my_csharp_node.MySignal.connect(my_signal_handler)
my_csharp_node.MySignalWithParams.connect(my_signal_with_params_handler)
Conectando a sinais GDScript a partir de C#
Conectar-se a um sinal de GDScript a partir do C# só funciona com o método Connect porque não existem tipos estáticos em C# para sinais definidos pelo GDScript:
myGDScriptNode.Connect("my_signal", Callable.From(MySignalHandler));
myGDScriptNode.Connect("my_signal_with_params", Callable.From<string, int>(MySignalWithParamsHandler));
Herança
Um arquivo GDscript não pode herdar de um script em C#. De forma semelhante, um script C# também não pode herdar de um arquivo GDscript. Devido a complexidade de sua implementação, essa limitação tem poucas chances de permanecer no futuro. Veja esse problema na plataforma GitHub para mais informações.