クロスランゲージでのスクリプト作成
Godot を使用すると、必要に応じてスクリプト言語を組み合わせて使用する事が出来ます。つまり、1つのプロジェクトでC#とGDScriptの両方でノードを定義できます。このページでは異なる言語で書かれた2つのノード間で可能な相互作用について説明します。
次の2つのスクリプトは、このページ全体で参照として使用されます。
extends Node
var my_property: String = "my gdscript value":
get:
return my_property
set(value):
my_property = value
signal my_signal
signal my_signal_with_params(msg: String, n: int)
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!")
func my_signal_with_params_handler(msg: String, n: int):
print_n_times(msg, n)
using Godot;
public partial class MyCSharpNode : Node
{
public string MyProperty { get; set; } = "my c# value";
[Signal] public delegate void MySignalEventHandler();
[Signal] public delegate void MySignalWithParamsEventHandler(string msg, int n);
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!");
}
public void MySignalWithParamsHandler(string msg, int n)
{
PrintNTimes(msg, n);
}
}
ノードのインスタンス化
シーンツリーのノードを使用していない場合は、コードから直接ノードをインスタンス化することをお勧めします。
GDScriptからのC#ノードのインスタンス化
GDScriptからC#を使用する場合、多くの作業は必要ありません。ロードされると(リソースとしてのクラス を参照)、スクリプトは :ref:`new() <class_CSharpScript_method_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という名前のクラスが含まれている必要があります。
C#クラスは、Godotクラス (たとえば GodotObject) を派生する必要があります。それ以外の場合は、同じエラーが発生します。
また .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"));
Keep in mind that when setting a field value you should only use types the GDScript side knows about. Essentially, you want to work with built-in types as described in 組み込み型 or classes extending 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メソッドを呼び出すには、GodotObject.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 = ["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.
シグナルに接続する
GDScript から C# のシグナルに接続する
GDScript から C# のシグナルに接続することは、GDScript で定義されたシグナルに接続することと同じです:
my_csharp_node.MySignal.connect(my_signal_handler)
my_csharp_node.MySignalWithParams.connect(my_signal_with_params_handler)
C# から GDScript シグナルに接続する
GDScript で定義されたシグナルには C# の静的型が存在しないため、C# から GDScript のシグナルへの接続は Connect メソッドを使用します。
myGDScriptNode.Connect("my_signal", Callable.From(MySignalHandler));
myGDScriptNode.Connect("my_signal_with_params", Callable.From<string, int>(MySignalWithParamsHandler));
継承
GDScript ファイルは C# スクリプトから継承できない場合があります。同様に C# スクリプトは GDScript ファイルから継承できない場合があります。これを実装するのは非常に複雑であるため、この制限が将来的に解除される可能性は低いです。詳細については、GitHub のIssue を参照してください。