언어간 스크립팅

Godot에선 여러분에 필요에 맞춰 스크립트 언어를 조합해 사용할 수 있습니다. 따라서 하나의 프로젝트에서 C#과 GDScript 모두로 노드를 정의할 수도 있습니다. 이 페이지에서는 서로 다른 언어로 작성된 노드 사이에서 발생할 수 있는 상호작용을 살펴볼 것입니다.

아래의 두 스크립트를 이 페이지를 진행하는 동안 참조할 것입니다.

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)

노드 인스턴스화 하기

씬 트리에서 노드를 사용하고 있는 것이 아니라면, 아마 노드를 코드에서 직접 인스턴스화 하는 것을 원하실겁니다.

GDScript에서 C# 노드 인스턴스화 하기

C# 노드는 GDScript에서 어렵지 않게 사용할 수 있습니다. 로딩이 끝나면 (:ref:`doc_gdscript_classes_as_resources`를 참고하세요) :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 클래스가 존재해야 합니다.

.cs 파일이 프로젝트의 .csproj 파일 내에서 참조되었는지 역시 확인해야 합니다. 만약 참조되지 않았다면 위와 동일한 에러가 발생합니다.

GDScript 노드를 C#에서 인스턴스화 하기

C#에서의 방법도 위와 크게 다르지 않습니다. 로딩이 완료되면 GDScript를 :ref:`GDScript.New() <class_GDScript_method_new>`로 인스턴스화 할 수 있습니다.

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

여기서는 :ref:`class_Object`을 사용했지만, :ref:`doc_c_sharp_features_type_conversion_and_casting`에 설명된 것처럼 변환할 수도 있습니다.

멤버 변수 접근하기

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

멤버 변수가 속성(property)인지 어트리뷰트인지는 중요하지 않지만, setter가 없는 속성(property)의 값을 바꾸려고 하면 오류가 발생한다는 점을 명심하십시오.

C#에서 GDScript 멤버 변수 접근하기

C#이 정적 언어이기 때문에, C#에서 GDScript에 접근하는 것은 조금 복잡합니다. 첫 번째 인수로 접근할 멤버 변수의 이름을 입력하고 :ref:`Object.Get() <class_Object_method_get>`또는 :ref:`Object.Set() <class_Object_method_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가 인식할 수 있는 타입의 값을 넘겨줘야 합니다. 따라서 :ref:`doc_gdscript`에 있는 내장(built-in) 타입 또는 :ref:`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 메서드를 호출하려면 첫 인자로 호출할 메서드 이름을 입력하고 :ref:`Object.Call() <class_Object_method_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 로 타입 변환해야 합니다. 그렇지 않으면 배열의 각 원소들이 하나의 인자로 취급되어 함수 원형과 맞지 않게 됩니다.

상속(Inheritance)

GDScript 파일이 C# 스크립트를 상속할 수 없고, 그 반대 역시 불가능합니다. 이 동작을 구현하는 것이 매우 까다로우므로, 이 제한은 바뀌지 않을 가능성이 높습니다. 자세한 내용은 이 GitHub issue 를 참고하세요.