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_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# 노드 인스턴스화 하기
C# 노드는 GDScript에서 어렵지 않게 사용할 수 있습니다. 일단 불러오면 (리소스로 취급되는 클래스 참조) 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 파일에서 참조되는지 확인해야 합니다. 그렇지 않으면 같은 오류가 발생할 것입니다.
GDScript 노드를 C#에서 인스턴스화 하기
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.
여기서는 :ref:`class_Object`을 사용했지만, :ref:`doc_c_sharp_features_type_conversion_and_casting`에 설명된 것처럼 변환할 수도 있습니다.
멤버 변수 접근하기
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 멤버 변수 접근하기
C#이 정적 언어이기 때문에, C#에서 GDScript에 접근하는 것은 조금 복잡합니다. 첫 번째 인수로 접근할 멤버 변수의 이름을 입력하고 :ref:`Object.Get() <class_Object_method_get>`또는 :ref:`Object.Set() <class_Object_method_set>`을 사용해야 합니다.
// 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가 인식할 수 있는 타입의 값을 넘겨줘야 합니다. 따라서 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 메서드를 호출하려면 첫 인자로 호출할 메서드 이름을 입력하고 :ref:`Object.Call() <class_Object_method_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.
메인에 HUD를 연결하기
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# 스크립트를 상속할 수 없고, 그 반대 역시 불가능합니다. 이 동작을 구현하는 것이 매우 까다로우므로, 이 제한은 바뀌지 않을 가능성이 높습니다. 자세한 정보는 이 GitHub 이슈를 참조하세요.