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 str1 : String = "foo"
var str2 : String setget ,get_str2
func get_str2() -> String:
return "foofoo"
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)
public class MyCSharpNode : Node
{
public String str1 = "bar";
public String str2 { get { return "barbar"; } }
public void PrintNodeName(Node node)
{
GD.Print(node.GetName());
}
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);
}
}
}
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 my_csharp_script = load("res://path_to_cs_file.cs")
var my_csharp_node = my_csharp_script.new()
print(my_csharp_node.str2) # barbar
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.
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().
GDScript MyGDScript = (GDScript) GD.Load("res://path_to_gd_file.gd");
Object myGDScriptNode = (Godot.Object) MyGDScript.New(); // This is a Godot.Object
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.
print(my_csharp_node.str1) # bar
my_csharp_node.str1 = "BAR"
print(my_csharp_node.str1) # BAR
print(my_csharp_node.str2) # barbar
# my_csharp_node.str2 = "BARBAR" # This line will hang and crash
Observe que não importa se o campo é definido como uma propriedade ou um atributo, mas tentar definir um valor em uma propriedade que não tem um setter resultará em um crash.
Acessando campos do GDScript no C#¶
Como C# é estáticamente tipado, acessar os campos de GDScript a partir do C# é um pouco mais complicado, você terá que usar Object.Get() e Object.Set(). O primeiro argumento é o nome do campo que você quer acessar.
GD.Print(myGDScriptNode.Get("str1")); // foo
myGDScriptNode.Set("str1", "FOO");
GD.Print(myGDScriptNode.Get("str1")); // FOO
GD.Print(myGDScriptNode.Get("str2")); // foofoo
// myGDScriptNode.Set("str2", "FOOFOO"); // This line won't do anything
Tenha em mente que ao definir um valor de campo você só deve usar tipos conhecidos pelo GDScript. Essencialmente, você precisa trabalhar com tipos embutidos descritos em Básicos do GDScript ou classes que estendam 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`
.
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
Chamando métodos de GDScript no C#¶
Para chamar os métodos de GDScript a partir do C# você precisará usar Object.Call(). O primeiro argumento é o nome do método que você quer chamar. Os próximos argumentos serão passados para esse método.
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!
// When dealing with functions taking a single array as arguments, we need to be careful.
// If we don't cast it into an object, the engine will treat each element of the array as a separate argument and the call will fail.
String[] arr = new String[] { "a", "b", "c" };
// myGDScriptNode.Call("print_array", arr); // This line will fail silently and won't error out.
myGDScriptNode.Call("print_array", (object)arr); // a, b, c
myGDScriptNode.Call("print_array", (object)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
Aviso
Como você pode ver, se o primeiro argumento do método chamado é um array, você precisará convertê-lo para object
. Caso contrário, cada elemento de seu array será tratado como um único argumento e a assinatura da função não corresponderá.
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.