クロスランゲージでのスクリプト作成

Godot を使用すると、必要に応じてスクリプト言語を組み合わせて使用する事が出来ます。つまり、1つのプロジェクトでC#とGDScriptの両方でノードを定義できます。このページでは、異なる言語で記述される2つのノード間で可能な相互作用について説明します。

次の2つのスクリプトは、このページ全体で参照として使用されます。

extends Node

var str1 : String = "foo"
var str2 : String setget ,get_str2

func 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)
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#ノードのインスタンス化

GDScriptからC#を使用する場合、多くの作業は必要ありません。ロードされると(リソースとしてのクラス を参照)、スクリプトは :ref:`new()<class_CSharpScript_method_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という名前のクラスが含まれている必要があります。

また、プロジェクトの.csprojファイルで.csファイルが参照されていることを確認する必要があります。そうしないと、同じエラーが発生します。

C#からのGDScriptノードのインスタンス化

C#側から見ても、すべてが同じように機能します。ロードされると、GDScriptは GDScript.New() でインスタンス化できます。

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

ここでは class_Object を使用していますが、型変換とキャスト で説明したような型変換を使用できます。

フィールドへのアクセス

GDScriptからC#フィールドにアクセスする

GDScriptからC#フィールドにアクセスするのは簡単です。心配する必要はありません。

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

print(my_csharp_node.str2) # barbar
# my_csharp_node.str2 = "BARBAR" # This line will hang and crash

フィールドがプロパティまたは属性として定義されているかどうかは関係ありませんが、セッターを定義していないプロパティに値を設定しようとするとクラッシュすることに注意してください。

C#からGDScriptフィールドにアクセスする

C#は静的に型指定されるため、C#からGDScriptにアクセスするのはもう少し複雑です。 Object.Get() および Object.Set() を使用する必要があります。最初の引数は、アクセスするフィールドの名前です。

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

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

フィールド値を設定するときは、GDScript側が知っている型のみを使用する必要があることに注意してください。基本的に、GDScriptの基本 または class_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メソッドの呼び出し

C#からGDScriptメソッドを呼び出すには、Object.Call() を使用する必要があります。最初の引数は呼び出すメソッドの名前です。次の引数以降が上記のメソッドに渡されます。

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, c
myGDScriptNode.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 としてキャストする必要があります。そうでない場合、配列の各要素は単一の引数として扱われ、関数シグネチャは一致しません。