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.

C# 기초

소개

이 페이지는 C#에 대한 간단한 소개와 그것이 무엇인지, 그리고 그것을 Godot에서 사용하는 방법을 제공합니다. 그런 다음, 특정 기능을 사용하는 방법을 원한다면, C# 과 GDScript API의 차이점에 대해 읽고 단계별 튜토리얼의 스크립팅 섹션을 (다시) 확인하세요.

C#은 Microsoft에서 개발한 고급 프로그래밍 언어입니다. Godot에서는 최신 .NET 런타임으로 구현됩니다.

주의

Godot 4를 사용하여 C#으로 작성된 프로젝트는 현재 웹 플랫폼으로 내보낼 수 없습니다. 웹 플랫폼에서 C#을 사용하려면 대신 Godot 3를 고려하세요. Android 및 iOS 플랫폼 지원은 Godot 4.2부터 사용 가능하지만 실험적이며 :ref:`몇 가지 제한 사항이 적용 <doc_c_sharp_platforms>`입니다.

참고

이것은 C# 언어 전체에 대한 본격적인 튜토리얼이 아닙니다. 문법이나 기능에 익숙하지 않다면 Microsoft C# 가이드를 보거나 다른 적합한 설명을 찾아보세요.

준비사항

Godot는 이미 컴파일된 게임을 실행하기 위해 필요한 .NET를 포함하고 있습니다. 하지만 MSBuild와 C#처럼 게임을 빌드 및 컴파일 할 수 있는 도구는 포함하고 있지 않으므로 위와 같은 도구들은 따로 설치해야 합니다. MSBuild도 .NET SDK에 포함되어 있지만, 별도로 설치해야 합니다.

요약하자면, .NET SDK와 .NET를 사용할 수 있는 버전의 Godot를 둘 다 설치해야 합니다.

.NET 다운로드 페이지에서 SDK의 최신 안정 버전을 다운로드하여 설치하세요.

중요

64비크 버전의 Godot를 사용하고 있다면 64비트 버전의 SDK를 설치해야 합니다.

소스에서 Godot를 빌드하려면 .NET으로 컴파일하기 페이지에 설명된 대로 빌드에서 .NET 지원을 활성화하는 단계를 따르세요.

외부 편집기 구성하기

Godot의 내장 스크립트 편집기에서 C# 지원은 최소한입니다. Visual Studio Code 또는 Visual Studio와 같은 외부 IDE나 편집기를 사용하는 것을 고려해 보세요. 이러한 편집기는 C#을 위한 자동완성, 디버깅 및 기타 유용한 기능을 제공합니다. Godot에서 외부 편집기를 선택하려면 편집기 → 편집기 설정을 클릭하고 Dotnet으로 스크롤하세요. Dotnet 아래에 편집기를 클릭하고 원하는 외부 편집기를 선택하세요. Godot는 현재 다음과 같은 외부 편집기를 지원합니다:

  • Visual Studio 2022

  • Visual Studio Code

  • MonoDevelop

  • Mac용 Visual Studio

  • JetBrains Rider

외부 편집기를 구성하는 방법은 아래 섹션을 참고하세요:

JetBrains Rider

"요구 사항" 섹션을 읽은 후, JetBrains Rider를 다운로드하고 설치할 수 있습니다.

Godot의 편집기 → 편집기 설정 메뉴에서:

  • Dotnet -> 편집기 -> 외부 편집기JetBrains Rider로 설정합니다.

Rider에서:

  • MSBuild 버전.NET Core로 설정합니다.

  • Rider 2024.2 이전 버전을 사용 중이라면 Godot 지원 플러그인을 설치하세요. 이 기능은 이제 Rider에 내장되어 있습니다.

Visual Studio Code

"요구 사항" 섹션을 읽은 후, Visual Studio Code(즉 VS Code)를 다운로드하고 설치할 수 있습니다.

Godot의 편집기 → 편집기 설정 메뉴에서:

  • Dotnet -> 편집기 -> 외부 편집기Visual Studio Code로 설정합니다.

Visual Studio Code에서:

  • C# 확장을 설치하세요.

디버깅을 위해 프로젝트를 구성하려면 필요한 구성이 있는 .vscode 폴더에 tasks.jsonlaunch.json 파일이 필요합니다.

launch.json의 예시입니다:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Play",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${env:GODOT4}",
            "args": [],
            "cwd": "${workspaceFolder}",
            "stopAtEntry": false,
        }
    ]
}

이 실행 구성을 작동시키려면 Godot 실행 파일을 가리키는 GODOT4 환경 변수를 설정하거나 program 매개변수를 Godot 실행 파일로의 경로로 바꿔야 합니다.

tasks.json의 예시입니다:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "command": "dotnet",
            "type": "process",
            "args": [
                "build"
            ],
            "problemMatcher": "$msCompile"
        }
    ]
}

이제 Visual Studio Code에서 디버거를 시작할 때 Godot 프로젝트가 실행됩니다.

Visual Studio (Windows 전용)

Visual Studio의 최신 버전을 다운로드하여 설치하세요. 올바른 워크로드를 선택하면 Visual Studio에 필요한 SDK가 포함되어 있으므로 "요구 사항" 섹션에 나열된 것을 수동으로 설치할 필요가 없습니다.

Visual Studio를 설치할 때, 이 워크로드를 선택하세요:

  • .NET 데스크톱 개발

Godot의 편집기 → 편집기 설정 메뉴에서:

  • Dotnet -> 편집기 -> 외부 편집기Visual Studio로 설정합니다.

참고

"Godot.NET.Sdk 패키지를 찾을 수 없습니다"와 같은 오류가 보이면 NuGet 구성이 잘못되었을 수 있으며 고쳐야 합니다.

NuGet 구성 파일을 고치는 간단한 방법은 파일을 다시 생성하는 것입니다. 파일 탐색기 창에서 %AppData%\NuGet으로 이동합니다. NuGet.Config 파일의 이름을 바꾸거나 삭제합니다. Godot 프로젝트를 다시 빌드할 때 파일이 디폴트 값으로 자동으로 만들어집니다.

Visual Studio를 사용하여 C# 스크립트를 디버깅하려면 편집기에서 첫 번째 C# 스크립트를 연 후 생성된 .sln 파일을 엽니다. 디버그 메뉴에서 프로젝트에 대해 디버그 속성 메뉴 항목으로 이동합니다. 새 프로필 만들기 버튼을 클릭하고 실행 파일을 선택합니다. 실행 파일 필드에서 Godot 편집기의 C# 버전의 경로를 찾아보거나 Godot 실행 파일 경로에 대한 환경 변수를 만든 경우 %GODOT4%를 입력합니다. '콘솔' 버전이 아닌 메인 Godot 실행 파일로의 경로여야 합니다. 작업 디렉터리에 현재 디렉터리를 의미하는 단일 마침표 .를 입력합니다. 또한 네이티브 코드 디버깅 활성화 체크박스를 선택합니다. 이제 이 창을 닫고 디버그 프로필 드롭다운에서 아래쪽 화살표를 클릭한 다음 새 시작 프로필을 선택할 수 있습니다. 초록 시작 버튼을 누르면 게임이 디버그 모드에서 플레이되기 시작합니다.

C# 스크립트 만들기

Godot용 C#을 성공적으로 설정한 후, 씬에서 노드의 컨텍스트 메뉴에서 스크립트 붙이기를 선택할 때 다음 옵션이 표시되어야 합니다:

../../../_images/attachcsharpscript.webp

일부 세부 사항이 변경되는 동안, 대부분의 작업은 스크립팅을 C#으로 하는 것과 동일합니다. Godot를 처음 접해보신다면, 이 시점에서 씬 스크립팅하기 튜토리얼을 정독하시는 것이 좋습니다. 문서의 일부는 C# 예제가 부족하지만, 대부분은 일찍이 GDScript에서 옮길 수 있습니다.

프로젝트 설정과 작업 흐름

첫 C# 스크립트를 생성하면, Godot는 Godot 프로젝트를 위한 C# 프로젝트 파일을 초기화합니다. 여기에는 C# 솔루션 (.sin)이나 프로젝트 파일 (.csproj) 뿐만 아니라, 일부 유용 파일과 폴더들 (.monoProperties/AssemblyInfo.cs)을 생성하는 것도 포함합니다. .mono를 제외하고는 모두 중요하므로 버전 관리 시스템에 유지해 두어야 합니다. .mono는 버전 관리 시스템의 무시 목록에 쉽게 추가할 수 있습니다. 문제를 해결할 때, .mono 폴더를 삭제하고 다시 생성하는 것이 때로는 도움이 됩니다.

예제

여기 동작을 설명하는 주석이 붙은 C# 스크립트가 있습니다.

using Godot;

public partial class YourCustomClass : Node
{
    // Member variables here, example:
    private int _a = 2;
    private string _b = "textvar";

    public override void _Ready()
    {
        // Called every time the node is added to the scene.
        // Initialization here.
        GD.Print("Hello from C# to Godot :)");
    }

    public override void _Process(double delta)
    {
        // Called every frame. Delta is time since the last frame.
        // Update game logic here.
    }
}

보시다시피, Godot의 print 함수와 마찬가지로 GDScript에서 함수는 기본적으로 전역 범위에 있기 때문에 Godot 네임스페이스의 일부분인 GD 클래스에서 사용 가능합니다. GD 클래스에서의 메서드 목록을 보려면, @GDScript@GlobalScope에서 클래스 참조 페이지를 참고하세요.

참고

노드에 붙이고 싶은 클래스의 이름은 .cs 파일과 동일해야 한다는 점을 명심하세요. 그렇지 않으면 다음 오류를 얻습니다:

"스크립트 res://XXX.cs에 대한 클래스 XXX를(을) 찾을 수 없음"

C#과 GDScript와의 일반적인 차이

GDScript/C++에서는 snake_case를 쓰지만 C# API는 PascalCase를 씁니다. 가능하면 공백과 getters/setters이 속성으로 변환됩니다. 일반적으로 C# Godot API는 합리적으로 가능한 것처럼 관용적이도록 노력합니다.

자세한 정보는 C# API와 GDScript의 차이점 페이지를 참조하세요.

경고

여러분이 C#을 사용한다면, 새로운 외부변수(export variables)나 시그널을 보기 위해서 프로젝트 구성물(assemblies)을 다시 빌드할 필요가 있습니다. 이 컴파일은 편집기 밑의 "Mono" 단어를 클릭해 Mono 패널이 나타나게 한 후 "프로젝트 빌드(Build Project)" 버튼을 눌러서 수동으로 진행됩니다.

../../../_images/build_dotnet.webp

또한 "도구" 스크립트의 변경 사항을 적용하려면 프로젝트 어셈블리를 다시 빌드해야 합니다.

현재 문제와 알려진 문제

C# 지원이 Godot에서 꽤 새롭기 때문에, 성장통이 있고 다듬어야 할 곳이 여전히 있습니다. 아래에는 중요한 문제 목록으로 Godot에서 C#으로 갈아탈 때 명심해야 합니다, 하지만 의심스러운 점이 있다면 공식 Mono 이슈를 위한 이슈 트래커를 살펴보세요.

  • 편집기 플러그인을 작성하는 것은 가능하지만, 현재로썬 상당히 복잡합니다.

  • 내보낸 변수를 제외하고, 현재 상태는 핫 리로드 중일 때 저장되고 복원되지 않습니다.

  • 붙여진 C# 스크립트가 파일 이름과 일치하는 클래스 이름을 가진 클래스를 참조해야 합니다.

  • Godot 의 ``snake_case" API 명명 규칙에 의존하는 ``Get ()"/"Set()" "Call()"/"CallDeferred()"와" 시그널 연결 메서드 ``Connect()"와 같은 방법이 있습니다. 그러므로 예를 들어 ``CallDeferred"("AddChild")를 사용할 때 ``AddChild"는 API가 원래의 ``snake_case" 버전의 ``add_child"를 기대하기 때문에 작동하지 않을 것입니다. 그러나 당신은 이러한 제한 없이 모든 커스텀 속성이나 메서드를 사용할 수 있습니다.

Mono 프로젝트를 내보내는 것은 데스크톱 플랫폼 (Linux, Windows, 그리고 macOS)만 지원합니다. Android, iOS, HTML5 그리고 UWP는 현재는 지원하지 않습니다 (#20267, #20268 #20270 #20271).

주석

Godot 객체의 일부 값을 수정하려고 할 때 다음 오류가 발생할 수 있습니다. ``Node2D``의 X 좌표를 변경하려고 할 때:

public partial class MyNode2D : Node2D
{
    public override void _Ready()
    {
        Position.X = 100.0f;
        // CS1612: Cannot modify the return value of 'Node2D.Position' because
        // it is not a variable.
    }
}

이것은 완전히 정상입니다. C#의 구조체(이 예에서는 Vector2)는 할당 시 복사됩니다. 즉, 속성이나 인덱서에서 이러한 개체를 검색할 때 개체 자체가 아닌 해당 개체의 복사본을 가져옵니다. 나중에 다시 할당하지 않고 해당 복사본을 수정하면 아무 효과가 없습니다.

해결 방법은 간단합니다. 전체 구조체를 검색하고, 수정하려는 값을 수정하고, 속성을 다시 할당하는 것입니다.

var newPosition = Position;
newPosition.X = 100.0f;
Position = newPosition;

C# 10부터는 구조체에 ` 표현식 <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/with-expression>`_을 사용하여 동일한 작업을 한 줄로 수행할 수도 있습니다.

Position = Position with { X = 100.0f };

`C# 언어 참조 <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs1612>`_에서 이 오류에 대한 자세한 내용을 읽을 수 있습니다.

Godot에서 C#의 퍼포먼스

더 보기

Godot가 지원하는 언어의 성능 비교는 :ref:`doc_faq_which_programming_language_is_fastest`를 참조하세요.

GodotObject``(예: ``Control``와 같은 ``Node 또는 Camera3D``와 같은 ``Node3D)를 기반으로 하는 Godot C# 개체의 대부분 속성은 Godot의 C++ 코어와 통신할 때 기본(상호 운용) 호출이 필요합니다. 단일 코드 위치에서 속성을 여러 번 수정하거나 읽어야 하는 경우 해당 속성의 값을 로컬 변수에 할당하는 것을 고려하세요.

using Godot;

public partial class YourCustomClass : Node3D
{
    private void ExpensiveReposition()
    {
        for (var i = 0; i < 10; i++)
        {
            // Position is read and set 10 times which incurs native interop.
            // Furthermore the object is repositioned 10 times in 3D space which
            // takes additional time.
            Position += new Vector3(i, i);
        }
    }

    private void Reposition()
    {
        // A variable is used to avoid native interop for Position on every loop.
        var newPosition = Position;
        for (var i = 0; i < 10; i++)
        {
            newPosition += new Vector3(i, i);
        }
        // Setting Position only once avoids native interop and repositioning in 3D space.
        Position = newPosition;
    }
}

원시 배열(예: byte[]) 또는 ``string``를 Godot의 C# API에 전달하려면 비교적 비용이 많이 드는 마샬링이 필요합니다.

string``에서 ``NodePath 또는 ``StringName``로의 암시적 변환은 ``string``가 마샬링되고 해당 네이티브 생성자에 전달되어야 하므로 네이티브 상호 운용성과 마샬링 비용이 모두 발생합니다.

Godot에서 NuGet 패키지 사용하기

NuGet 패키지를 설치하여 프로젝트처럼, Godot와 사용할 수 있습니다. 많은 IDE는 직접 패키지를 추가할 수 있습니다. 또한 프로젝트 루트에 있는 .csproj 파일에 패키지 참조를 수동으로 추가할 수 있습니다:

    <ItemGroup>
        <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
    </ItemGroup>
    ...
</Project>

Godot 버전 3.2.3부터는 프로젝트를 빌드한 후 새로 추가된 NuGet 패키지를 자동으로 다운로드 및 설정합니다.

C# 코드 프로파일링

관리 코드의 성능 및 메모리 프로파일링에 다음 도구를 사용할 수 있습니다.

  • dotTrace/dotMemory 플러그인이 포함된 JetBrains Rider.

  • 독립형 JetBrains dotTrace/dotMemory.

  • Visual Studio.

JetBrains 도구와 Visual Studio 모두에서 관리 코드와 비관리 코드를 동시에 프로파일링하는 것이 가능하지만 Windows로 제한됩니다.