Up to date
This page is up to date for Godot 4.3.
If you still find outdated information, please open an issue.
跨語言腳本撰寫
在 Godot 中可以依照需求來混合使用不同的腳本語言。這表示,單一專案內可以同時以 C# 與 GDScript 來定義節點。本頁將介紹如何讓兩個以不同語言撰寫的節點該如何互動。
下列兩個腳本會在本頁中都會用來作為參考。
extends Node
var my_property: String = "my gdscript value":
get:
return my_property
set(value):
my_property = value
signal my_signal
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)
func my_signal_handler():
print("The signal handler was called!")
using Godot;
public partial class MyCSharpNode : Node
{
public string MyProperty { get; set; } = "my c# value";
[Signal] public delegate void MySignalEventHandler();
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);
}
}
public void MySignalHandler()
{
GD.Print("The signal handler was called!");
}
}
實體化節點
若不使用場景樹中的節點,則可以直接從程式碼中實體化節點。
在 GDScript 中實體化 C# 節點
從 GDScript 中使用 C# 並不需花費額外功夫。載入後 (請參見 以類別當作資源) 便可以使用 new() 來實體化腳本。
var MyCSharpScript = load("res://Path/To/MyCSharpNode.cs")
var my_csharp_node = MyCSharpScript.new()
警告
建立 .cs 腳本後,請記得 Godot 類別與 .cs 檔案本身的名字。若與檔名相同的類別不存在與檔案中,則會看到這個錯誤:Invalid call. Nonexistent function `new` in base 。
舉例來說,MyCoolNode.cs 應該包含名為 MyCoolNode 的類別。
你也需要檢查 .cs 檔案是否在專案中的 .csproj 檔案中參照。否則也會出現相同的錯誤。
你也需要檢查 .cs 檔案是否在專案中的 .csproj 檔案中參照。否則也會出現相同的錯誤。
在 C# 中實體化 GDScript 節點
在 C# 這邊,所有東西的運作方式都一樣。載入後,GDScript 便可以使用 GDScript.New() 來實體化。
var myGDScript = GD.Load<GDScript>("res://path/to/my_gd_script.gd");
var myGDScriptNode = (GodotObject)myGDScript.New(); // This is a GodotObject.
存取欄位
在 GDScript 中存取 C# 欄位
要從 GDScript 存取 C# 欄位很簡單,沒什麼好擔心的。
# Output: "my c# value".
print(my_csharp_node.MyProperty)
my_csharp_node.MyProperty = "MY C# VALUE"
# Output: "MY C# VALUE".
print(my_csharp_node.MyProperty)
在 C# 中存取 GDScript 欄位
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.
// Output: "my gdscript value".
GD.Print(myGDScriptNode.Get("my_property"));
myGDScriptNode.Set("my_property", "MY GDSCRIPT VALUE");
// Output: "MY GDSCRIPT VALUE".
GD.Print(myGDScriptNode.Get("my_property"));
請記得當設定欄位值時,使用的型別應該是 GDScript 那段能認得的型別。特別是在使用如 doc_gdscript` 中說明的內建型別或擴充了 Object 的類別時。
呼叫方法
在 GDScript 中呼叫 C# 方法
同樣地,從 GDScript 中呼叫 C# 方法應該很簡單。封送處理程式會儘可能地將參數的型別轉換為符合函式簽章的型別。若無法自動轉換,則會看到這個錯誤: Invalid call. Nonexistent function `FunctionName` 。
# Output: "my_gd_script_node" (or name of node where this code is placed).
my_csharp_node.PrintNodeName(self)
# This line will fail.
# my_csharp_node.PrintNodeName()
# Outputs "Hello there!" twice, once per line.
my_csharp_node.PrintNTimes("Hello there!", 2)
# Output: "a", "b", "c" (one per line).
my_csharp_node.PrintArray(["a", "b", "c"])
# Output: "1", "2", "3" (one per line).
my_csharp_node.PrintArray([1, 2, 3])
在 C# 中呼叫 GDScript 方法
從 C# 中呼叫 GDScript 方法則需要使用 Object.Call() 。第一個參數為欲呼叫的函式名稱,接下來的參數則會被傳入該方法中。
// Output: "MyCSharpNode" (or name of node where this code is placed).
myGDScriptNode.Call("print_node_name", this);
// This line will fail silently and won't error out.
// myGDScriptNode.Call("print_node_name");
// Outputs "Hello there!" twice, once per line.
myGDScriptNode.Call("print_n_times", "Hello there!", 2);
string[] arr = new string[] { "a", "b", "c" };
// Output: "a", "b", "c" (one per line).
myGDScriptNode.Call("print_array", arr);
// Output: "1", "2", "3" (one per line).
myGDScriptNode.Call("print_array", new int[] { 1, 2, 3 });
// Note how the type of each array entry does not matter
// as long as it can be handled by the marshaller.
Connecting to signals
Connecting to C# signals from GDScript
Connecting to a C# signal from GDScript is the same as connecting to a signal defined in GDScript:
my_csharp_node.MySignal.connect(my_signal_handler)
Connecting to GDScript signals from C#
Connecting to a GDScript signal from C# only works with the Connect method
because no C# static types exist for signals defined by GDScript:
myGDScriptNode.Connect("my_signal", Callable.From(MySignalHandler));
繼承
GDScript 檔案不能繼承 C# 腳本。同樣地,C# 腳本也不能繼承 GDScript 檔案。由於要實作這個功能會很複雜,此一限制應該也會延續到未來的版本中。 請參考 這個 GitHub Issue (英文) 來瞭解詳情。