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)

Nodes in­s­tan­zi­ie­ren

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.