C# 기능¶
이 페이지는 C#과 Godot에서 일반적으로 사용되는 기능과 어떻게 이 둘이 함께 사용되는 지에 대한 개요입니다.
형 변환(Type conversion)과 캐스팅(casting)¶
C#은 정적으로 타입형 언어입니다. 그러므로 다음을 할 수 없습니다:
var mySprite = GetNode("MySprite");
mySprite.SetFrame(0);
Node
인스턴스를 반환하는 GetNode()
메서드. Sprite
의 경우, 원하는 파생 타입을 명시적으로 변환해야 합니다.
이를 위해, C#에서는 다양한 설정이 있습니다.
캐스트(Cast)와 타입 체크(Type Check)하기
반환된 노드를 Sprite로 캐스트 할 수 없는 경우 InvalidCastException
을 발생시킵니다. 실패하지 않는다고 확신하면 as
연산자 대신에 그것을 사용할 것입니다.
Sprite mySprite = (Sprite)GetNode("MySprite");
mySprite.SetFrame(0);
AS 연산자 사용하기
노드가 Sprite로 캐스트 될 수 없다면 as
연산자는 null을 반환합니다, 그렇기 때문에 값 타입과는 함께 사용될 수 없습니다.
Sprite mySprite = GetNode("MySprite") as Sprite;
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);
일반 메서드 사용하기
일반 메서드는 이 타입 변환을 투명하게 만들기 위해 제공됩니다.
GetNode<T>()
은 반환하기 전에 노드를 캐스트 합니다. 노드가 원하는 타입으로 캐스트 되지 않는다면 InvalidCastException
을 발생시킵니다.
Sprite mySprite = GetNode<Sprite>("MySprite");
mySprite.SetFrame(0);
GetNodeOrNull<T>()
는 as
연산자를 사용하고 노드가 원하는 타입으로 캐스트 되지 않는다면 null
을 반환합니다.
Sprite mySprite = GetNodeOrNull<Sprite>("MySprite");
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);
IS 연산자를 사용하여 타입 체크하기
노드가 Sprite로 캐스트 되도록 체크하기 위해, is
연산자를 사용할 수 있습니다. Sprite가 캐스트 되지 않는다면 is
연산자는 거짓을 반환하고, 그렇지 않으면 참을 반환합니다.
if (GetNode("MySprite") is Sprite)
{
// Yup, it's a sprite!
}
더 많은 고급 타입 체크하기의 경우, 패턴 일치에서 찾아볼 수 있습니다.
C# 시그널¶
완전한 C# 예제를 위해, 단계별 Scripting languages 튜토리얼에서 시그널 다루기를 참고하세요.
C#에서 시그널 선언은 델리게이트(delegate)에서 [Signal]
속성으로 됩니다.
[Signal]
delegate void MySignal();
[Signal]
delegate void MySignalWithArguments(string foo, int bar);
위 시그널들은 에디터 혹은 코드 내에서 Connect
메소드를 이용해 연결할 수 있습니다. 에디터에서 시그널을 연결할 때, 프로젝트 구성물(assembly) 를 다시 빌드해야 추가된 시그널을 확인할 수 있습니다. 에디터 창 우측 상단 모퉁이의 "Build" 버튼을 눌러 직접 빌드할 수 있습니다.
public void MyCallback()
{
GD.Print("My callback!");
}
public void MyCallbackWithArguments(string foo, int bar)
{
GD.Print("My callback with: ", foo, " and ", bar, "!");
}
public void SomeFunction()
{
instance.Connect("MySignal", this, "MyCallback");
instance.Connect(nameof(MySignalWithArguments), this, "MyCallbackWithArguments");
}
EmitSignal
메서드로 시그널을 방출할 수 있습니다.
public void SomeFunction()
{
EmitSignal(nameof(MySignal));
EmitSignal("MySignalWithArguments", "hello there", 28);
}
nameof
키워드로 항상 시그널 이름을 참조할 수 있다는 것을 명심하세요 델리게이트 자체에 적용됨).
It is possible to bind values when establishing a connection by passing a Godot array.
public int Value { get; private set; } = 0;
private void ModifyValue(int modifier)
{
Value += modifier;
}
public void SomeFunction()
{
var plusButton = (Button)GetNode("PlusButton");
var minusButton = (Button)GetNode("MinusButton");
plusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { 1 });
minusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { -1 });
}
시그널은 매개변수를 지원하고, 모든 내장 타입의 값들과 Godot.Object에서 파생된 클래스들을 묶습니다. 결과적으로, 모든 Node
나 Reference
는 자동으로 호환될 것이지만, 맞춤 데이터 오브젝트는 Godot.Object나 그 하위 클래스에서 확장해야 할 것입니다.
public class DataObject : Godot.Object
{
public string Field1 { get; set; }
public string Field2 { get; set; }
}
마침내, 시그널은 AddUserSignal
로 호출하는 것으로 생성될 수 있지만, 시그널을 사용하기 전에 실행되어야 한다는 것을 명심하세요 (Connect
나 EmitSignal
로 말이죠).
public void SomeFunction()
{
AddUserSignal("MyOtherSignal");
EmitSignal("MyOtherSignal");
}
전처리기 지시문¶
Godot은 컴파일하는 환경에 따라 C# 코드를 변경할 수 있도록 여러 전처리기 지시문을 제공합니다.
참고
Godot 3.2 버전 이전에 프로젝트를 생성했다면, csproj 파일을 수정하거나 재생성해야 이 기능(<DefineConstants>
를 3.2 이후의 프로젝트와 비교해보십시오)을 사용할 수 있습니다.
예제¶
예를 들어, 다음과 같이 플랫폼에 따라 코드를 변경할 수 있습니다:
public override void _Ready()
{
#if GODOT_SERVER
// Don't try to load meshes or anything, this is a server!
LaunchServer();
#elif GODOT_32 || GODOT_MOBILE || GODOT_WEB
// Use simple objects when running on less powerful systems.
SpawnSimpleObjects();
#else
SpawnComplexObjects();
#endif
}
혹은 여러분의 코드를 실행하는 엔진의 상태를 확인하는데 사용할 수도 있습니다. 크로스-엔진 라이브러리를 제작하는데 유용한 기능입니다:
public void MyPlatformPrinter()
{
#if GODOT
GD.Print("This is Godot.");
#elif UNITY_5_3_OR_NEWER
print("This is Unity.");
#else
throw new InvalidWorkflowException("Only Godot and Unity are supported.");
#endif
}
모든 지시문¶
GODOT
은 항상 Godot 프로젝트를 정의합니다.컴퓨터 환경이 64-bit인지 32-bit인지에 따라서
GODOT_64
와GODOT_32
중 하나가 정의됩니다.사용중인 운영체제의 종류에 따라서
GODOT_X11
,GODOT_WINDOWS
,GODOT_OSX
,GODOT_ANDROID
,GODOT_IOS
,GODOT_HTML5
, 또는GODOT_SERVER
중 하나가 정의됩니다. 위 이름들은 후에 변경될 수 있습니다. 이들은 OS 싱글턴의get_name()
메서드로 생성될 수 있지만, 메서드가 반환하는 모든 OS에서 Mono 버전 Godot이 실행될 수 있는 것은 아닙니다.
내보내기 를 할 때, 내보내기 기능에 따라서 아래의 것들이 정의될 수 있습니다:
플랫폼에 따라서
GODOT_PC
,GODOT_MOBILE
, 또는GODOT_WEB
중 하나가 정의됩니다.Android 아키텍처에 따라서
GODOT_ARM64_V8A
와GODOT_ARMEABI_V7A
중 하나가 정의됩니다.iOS의 아키텍처에 따라서
GODOT_ARM64
와GODOT_ARMV7
중 하나가 정의됩니다.텍스처 압축 타입에 따라서
GODOT_S3TC
,GODOT_ETC
, 그리고GODOT_ETC2
가 정의될 수 있습니다.내보내기 메뉴에서 추가된 커스텀 기능은 다음과 같이 대문자화 된 후 접두사가 붙습니다:
foo
->GODOT_FOO
.
예제 프로젝트를 확인하려면 OS 테스트 데모를 확인하세요: https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test