跨语言脚本

Godot允许您混合和匹配脚本语言以满足您的需求. 这意味着一个项目可以同时用C#和GDScript定义节点. 本页将介绍用不同语言编写的两个节点之间可能的交互. 以下两个脚本用在整个页面中作为参考. GDScript C#

  1. extends Nodevar str1 : String = "foo"var str2 : String setget ,get_str2func 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_x_times(msg : String, n : int) -> void: for i in range(n): print(msg)
  1. 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); } }}

实例化节点

如果不使用场景树中的节点, 则可能需要直接从代码实例化节点.

在 GDScript 中实例化 C# 节点

类作为资源)脚本就可以使用 new() 进行实例化.

  1. 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

警告 .cs 脚本时, 应始终记住 Godot 将使用和这个 .cs 文件名相同的类. 如果文件中不存在该类, 您将看到以下错误: Invalid call. Nonexistent functionnewin base . 比如,MyCoolNode.cs 应该包含一个名为 MyCoolNode 的类. .csproj 文件中引用了该 .cs 文件的内容. 否则, 将发生相同的错误.

在C#中实例化GDScript节点

GDScript.New().

  1. GDScript MyGDScript = (GDScript) GD.Load("res://path_to_gd_file.gd");Object myGDScriptNode = (Godot.Object) MyGDScript.New(); // This is a Godot.Object

Object , 但是也可以使用类型转换, 如 类型转换和强制转换 章节所述.

访问字段

从 GDScript 中访问 C# 字段

从GDScript访问 C# 字段很简单, 没什么可担心的.

  1. print(my_csharp_node.str1) # barmy_csharp_node.str1 = "BAR"print(my_csharp_node.str1) # BARprint(my_csharp_node.str2) # barbar# my_csharp_node.str2 = "BARBAR" # This line will hang and crash

需要注意的是, 字段定义为属性(property)或特性(attribute)并不重要, 但尝试在未定义 setter 的属性(property)上设置值将导致崩溃.

从 C# 中访问 GDSscript

Object.Get() 和 Object.Set() . 第一个参数是要访问的字段的名称.

  1. GD.Print(myGDScriptNode.Get("str1")); // foomyGDScriptNode.Set("str1", "FOO");GD.Print(myGDScriptNode.Get("str1")); // FOOGD.Print(myGDScriptNode.Get("str2")); // foofoo// myGDScriptNode.Set("str2", "FOOFOO"); // This line won't do anything

GDScript 基础 或者 Object 的扩展类.

调用方法

在GDScript中调用C#方法

Invalid call. Nonexistent functionFunctionName`` .

  1. 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, cmy_csharp_node.PrintArray([1, 2, 3]) # 1, 2, 3

从 C# 中 调用 GDScript 方法

Object.Call() . 第一个参数是想要调用方法的名称. 接下来的其他参数会传递给被调用的方法.

  1. 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, cmyGDScriptNode.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

警告 object。否则数组的每个元素将被当做单个参数传入,这将导致与被调用的函数签名参数不匹配。

继承

这个 GitHub issue .