Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
跨语言脚本¶
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)
using Godot;
public partial class MyCSharpNode : Node
{
public string myField = "bar";
public void PrintNodeName(Node node)
{
GD.Print(node.Name);
}
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# 节点¶
从GDScript中使用C#并不麻烦. 加载后(见 类作为资源)脚本就可以使用 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
警告
创建 .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.
您还需要检查在项目的 .csproj
文件中引用了该 .cs
文件的内容. 否则, 将发生相同的错误.
在C#中实例化GDScript节点¶
在 C# 端, 所有的工作方式相同. 加载后,GDScript 可以被示例化, 使用 GDScript.New().
GDScript MyGDScript = (GDScript)GD.Load("res://path_to_gd_file.gd");
GodotObject myGDScriptNode = (GodotObject)MyGDScript.New(); // This is a GodotObject
访问字段¶
从 GDScript 中访问 C# 字段¶
从GDScript访问 C# 字段很简单, 没什么可担心的.
print(my_csharp_node.myField) # bar
my_csharp_node.myField = "BAR"
print(my_csharp_node.myField) # BAR
从 C# 中访问 GDSscript¶
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 的内置类型 GDScript reference 或者 Object 的扩展类.
调用方法¶
在GDScript中调用C#方法¶
从 GDScript 调用 C# 方法同样是很简单的. 调用过程将尽力强制转换你的参数类型去匹配函数签名. 如果失败则会看到以下错误 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
从 C# 中 调用 GDScript 方法¶
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 issue .