Cross-Language-Scripting¶
Godot erlaubt es mehrere Skriptsprachen zu mixen, je nach Anforderung. Ein einzelnes Projekt kann somit Nodes sowohl in C# als auch in GDScript definieren. Diese Seite geht auf die möglichen Interaktionen zwischen zwei Nodes geschrieben in unterschiedlichen Sprachen ein.
Die folgenden beiden Skripte werden durchgehend auf dieser Seite als Referenz genutzt.
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);
}
}
}
Nodes instanziieren¶
Falls keine Nodes aus dem Szenenbaum genutzt werden, können Nodes auch direkt aus dem Code instanziiert werden.
Instanziiere C# Nodes von GDScript¶
C# aus GDScript zu nutzen benötigt nicht viel Aufwand. Einmal geladen (siehe Klassen als Ressourcen) kann das Skript mit :ref:`new() <class_CSharpScript_method_new>`instanziiert werden.
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
Warnung
Wenn Sie .cs
-Skripte erstellen sollten Sie immer bedenken, dass die von Godot verwendete Klasse genauso benannt wird wie die .cs
-Datei selbst. Wenn diese Klasse in der Datei nicht vorhanden ist, wird der folgende Fehler angezeigt: Ungültiger Aufruf. Nicht vorhandene Funktion `neu` in base
.
Zum Beispiel soll MyCoolNode.cs eine Klasse beinhalten namens MyCoolNode.
Sie müssen auch überprüfen ob auf Ihre .cs
-Datei in der .csproj
-Datei des Projekts verwiesen wird. Andernfalls tritt der gleiche Fehler auf.
Instanziiere GDScript Nodes von C#¶
Von der C# Seite aus funktioniert alles auf die gleiche Art. Einmal geladen kann das GDScript instanziiert werden mit GDScript.New().
GDScript MyGDScript = (GDScript) GD.Load("res://path_to_gd_file.gd");
Object myGDScriptNode = (Godot.Object) MyGDScript.New(); // This is a Godot.Object
Hier verwenden wir ein Object, aber Sie können die Typkonvertierung wie in Typumwandlung und Casting beschrieben verwenden.
Auf Felder zugreifen¶
Zugriff auf C# Felder von GDScript¶
Der Zugriff auf C# Felder über GDScript ist unkompliziert, Sie müssen sich keine Sorgen machen.
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
Beachten Sie, dass es keine Rolle spielt, ob das Feld als Eigenschaft oder Attribut definiert ist. Der Versuch einen Wert für eine Eigenschaft die keinen Setter definiert festzulegen, führt jedoch zu einem Absturz.
Zugriff auf GDScript Felder von C#¶
Da C# statisch typisiert ist und der Zugriff auf GDScript von C# aus etwas komplizierter ist, müssen Sie Folgendes verwenden Object.Get() and Object.Set(). Das erste Argument ist der Name des Feldes, auf das Sie zugreifen möchten.
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
Beachten Sie, dass Sie beim Festlegen eines Feldwerts nur Typen verwenden sollten, die der GDScript-Seite bekannt sind. Im Wesentlichen möchten Sie mit integrierten Typen arbeiten, wie in GDScript Grundlagen beschrieben oder Klassenerweiterung von Object .
Methoden aufrufen¶
Aufruf von C# Methoden von GDScript¶
Auch hier sollte das Aufrufen von C# Methoden aus GDScript unkompliziert sein. Der Bereitstellungs-Prozess wird sein Bestes tun, um die Argumente so umzuwandeln, dass sie mit den Funktionssignaturen übereinstimmen. Wenn dies nicht möglich ist wird der folgende Fehler angezeigt: Invalid call. Nonexistent function `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
Aufruf von GDScript Methoden von C#¶
Um GDScript-Methoden von C# aus aufzurufen müssen Sie Folgendes verwenden Object.Call(). Das erste Argument ist der Name der Methode die Sie aufrufen möchten. Die folgenden Argumente werden an diese Methode übergeben.
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
Warnung
Wie Sie sehen können müssen Sie das erste Argument der aufgerufenen Methode als object
umwandeln, wenn es sich um ein Array handelt. Andernfalls wird jedes Element Ihres Arrays als einzelnes Argument behandelt und die Funktionssignatur stimmt nicht überein.
Vererbung¶
Eine GDScript-Datei erbt möglicherweise nicht von einem C# Skript. Ebenso darf ein C# Skript nicht von einer GDScript-Datei erben. Aufgrund der Komplexität der Implementierung ist es unwahrscheinlich, dass diese Einschränkung in Zukunft aufgehoben wird. Weitere Informationen finden Sie unter diesem GitHub-Problem.