Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Меж-языковые сценарии (скрипты)

Godot позволяет вам смешивать и сопоставлять языки сценариев в соответствии с вашими потребностями. Это означает, что один проект может определять узлы как в C#, так и в GDScript. На этой странице будут рассмотрены возможные взаимодействия между двумя узлами, написанными на разных языках.

Следующие два скрипта будут использоваться в качестве примера на этой странице.

extends Node

var my_field: String = "foo"

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)

Создание экземпляров узлов

Если вы не используете узлы из дерева сцены, вы, вероятно, захотите создать экземпляры узлов непосредственно из кода.

Создание экземпляров узлов C# из GDScript

Использование C# из GDScript не требует особых усилий. После загрузки (см . Классы как ресурсы) сценарий может быть создан с помощью new().

var my_csharp_script = load("res://Path/To/MyCSharpNode.cs")
var my_csharp_node = my_csharp_script.new()

Предупреждение

При создании сценариев`` .cs`` вы всегда должны помнить, что класс, который будет использовать Godot, называется так же, как и сам файл .cs. Если этот класс не существует в файле, вы увидите следующую ошибку: Invalid call. Nonexistent function `new` in base.

Например, MyCoolNode.cs должен содержать класс с именем MyCoolNode.

The C# class needs to derive a Godot class, for example GodotObject. Otherwise, the same error will occur.

Вам также необходимо проверить, что ваш файл .cs указан в файле проекта .csproj. В противном случае произойдет та же ошибка.

Создание узлов GDScript из C#

Со стороны C# все работает точно также. После загрузки GDScript может быть создан с помощью GDScript.New().

GDScript MyGDScript = GD.Load<GDScript>("res://path/to/my_gd_script.gd");
GodotObject myGDScriptNode = (GodotObject)MyGDScript.New(); // This is a GodotObject.

Здесь мы используем Object, но вы можете использовать преобразование типов, как объяснено в Превращение типов и кастинг.

Доступ к полям

Доступ к полям C# из GDScript

Доступ к полям C# из GDScript прост, вам не о чем беспокоиться.

print(my_csharp_node.myField) # bar
my_csharp_node.myField = "BAR"
print(my_csharp_node.myField) # BAR

Доступ к полям GDScript из C#

As C# is statically typed, accessing GDScript from C# is a bit more convoluted, you will have to use GodotObject.Get() and GodotObject.Set(). The first argument is the name of the field you want to access.

GD.Print(myGDScriptNode.Get("my_field")); // foo
myGDScriptNode.Set("my_field", "FOO");
GD.Print(myGDScriptNode.Get("my_field")); // FOO

Имейте в виду, что при установке значения поля вы должны использовать только те типы, о которых знает сторона GDScript. По сути, вы хотите работать со встроенными типами, как описано в Справочник по GDScript, или с классами, расширяющими Object.

Методы вызова

Вызов C# методов из GDScript

Опять же, вызов методов C# из GDScript должен быть простым. Процесс маршаллинга приложит все усилия, чтобы привести ваши аргументы к сигнатурам функций. Если это невозможно, вы увидите следующую ошибку: 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

Вызов методов GDScript из C#

To call GDScript methods from C# you'll need to use GodotObject.Call(). The first argument is the name of the method you want to call. The following arguments will be passed to said method.

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!

string[] arr = new string[] { "a", "b", "c" };
myGDScriptNode.Call("print_array", arr); // a, b, c
myGDScriptNode.Call("print_array", 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.

Предупреждение

Как вы можете видеть, если первый аргумент вызываемого метода является массивом, вам нужно привести его как object. В противном случае каждый элемент вашего массива будет рассматриваться как один аргумент, и сигнатура функции не будет совпадать.

Наследование

Файл GDScript не может быть наследником сценария C#. Точно так же сценарий C# не может наследоваться от файла GDScript. Из-за сложности реализации это ограничение вряд ли удастся снять в будущем. См. эту проблему на GitHub для получения дополнительной информации.