Unity에서 Godot 엔진까지

이 가이드는 Unity 사용자의 관점에서 Godot 엔진의 개요를 제공합니다, 그리고 존재하는 Unity 경험을 Godot라는 세상에 옮기도록 돕는 것에 중점을 둡니다.

주석

이 문서는 예전 버전의 Unity에 대해 말하고 있습니다. 중첩할 수 있는 프리펩('중첩된 프리펩')은 Unity 2018.3에 추가되었습니다. 중첩할 수 있는 프리펩은 Godot의 씬과 유사합니다. 그리고 Godot와 유사하게 씬 조직으로 접근할 수 있습니다.

차이점

  Unity Godot
라이선스 수익 상한과 사용 제한이 있는 독점적이고 폐쇄적인 무료 라이선스 MIT 라이선스로, 어떤 제한 없이 무료이고 완전한 오픈 소스
OS (편집기) Windows, macOS, Linux (비공식이고 지원되지 않음) Windows, macOS, X11 (Linux, *BSD)
OS (내보내기)
  • 데스크톱: Windows, macOS, Linux
  • 모바일: Android, iOS, Windows 폰, Tizen
  • 웹: WebAssembly이나 asm.js
  • 콘솔: PS4, PS Vita, Xbox One, Xbox 360, Wii U, Nintendo 3DS
  • VR: Oculus Rift, SteamVR, Google Cardboard, Playstation VR, Gear VR, HoloLens
  • TV: Android TV, Samsung SMART TV, tvOS
  • 데스크톱: Windows, macOS, X11
  • 모바일: Android, iOS
  • 웹: WebAssembly
  • 콘솔: Godot의 콘솔 지원 을 확인하세요
  • VR: Oculus Rift, SteamVR
씬 시스템
  • 컴포넌트/씬(GameObject > Component)
  • 프리펩
Scene tree and nodes, 씬을 중첩하거나 다른 씬을 상속할 수 있습니다
타사 도구 Visual Studio 혹은 VS Code
주목할만한 이점:
  • 거대한 커뮤니티
  • 넓은 애셋 스토어

편집기

Godot 엔진은 게임을 제작하기 위한 풍부한 기능을 가진 편집기를 제공합니다. 밑의 사진은 두 편집기의 기본 레이아웃을 보여줍니다. 같은 기능에는 같은 색으로 된 블록으로 표시했습니다.

../../_images/unity-gui-overlay.png ../../_images/godot-gui-overlay.png

두 편집기 모두 비슷해 보이지만, 내부를 보면 많은 차이점이 있습니다. 두 편집기 모두 파일 시스템으로 프로젝트를 조직할 수 있게 해줍니다. 하지만 Godot의 접근법은 더 간단합니다. 하나의 구성 파일, 최대한 간략하게 만든 문자 형식, 그리고 메타데이터가 없죠. 이 점이 Godot를 Git, Subversion, Mercurial과 같은 버전 관리 시스템(VCS)에 더 친근하게 만들어줍니다.

Godot의 씬 패널은 Unity의 계층 구조 패널과 유사합니다. 하지만 각 노드가 특정 기능을 갖고 있는 Godot의 특성 상, 이 접근법은 Godot에서 더 시각적으로 이해하기 좋습니다. 씬이 어떤 일을 하는 지 한눈에 이해하기가 더 쉽다는 뜻입니다.

Godot의 인스펙터(Inspector)는 더 간략합니다. 오직 속성만 보여주죠. 덕분에 객체는 언어 API에서 기능을 숨길 필요없이 더 유용한 매개변수를 사용자에게 보여줄 수 있습니다. 게다가 Godot는 모든 속성을 시각적으로 애니메이션을 줄 수 있습니다. 색상을 바꾸거나, 텍스처, 열거, 심지어 리소스에 연결하는 것도 코드를 작성할 필요없이 실시간으로 가능합니다.

화면 상단의 툴바는 두 편집기 모두 유사합니다. 프로젝트 실행을 제어합니다. Godot에서는 프로젝트가 편집기 내에서가 아닌 별개의 창에서 실행됩니다 (하지만 트리와 객체는 디버거 창에서 탐색할 수 있습니다).

이 접근은 실행 중인 게임을 다른 각도롤 볼 수 없다는 단점이 있습니다 (이 기능을 향후 지원할지도 모르고 실행 중인 게임에 충돌 기즈모를 보여주는 것이 이미 가능합니다), 하지만 그 대가로 몇 가지 이점을 갖습니다:

  • 프로젝트를 실행하고 종료하는 것이 빠릅니다 (Unity는 저장하고, 프로젝트를 실행하고, 프로젝트를 종료하고, 그리고 이전 상태를 다시 불러와야 합니다).
  • 실시간 편집은 편집기에서 변경한 사항이 게임에 즉시 적용되고 게임을 끌 때 (동기화 할 필요도 없이) 사라지지 않으니 훨씬 더 유용합니다. 이것으로 플레이 도중 레벨을 만드는 등의 환상적인 워크플로가 가능합니다.
  • 게임이 별도의 프로세스에서 실행되기 때문에 편집기는 더 안정적입니다.

마지막으로 Godot의 상단 툴바에는 원격 디버그를 위한 메뉴가 있습니다. 이 설정으로 (폰, 태블릿에 연결된, 혹은 HTML5를 통한 브라우저와 같은) 기기 환경에서 개발을 할 수 있습니다. 그리고 게임을 내보낸 후 디버깅/실시간 편집이 가능합니다.

씬 시스템

Unity와 Godot의 가장 큰 차이점이자 Godot 사용자가 가장 좋아하는 기능입니다.

Unity에서 'Level'에서 작업한다는 것은 보통 모든 필요한 에셋을 한 씬에 묶고, 구성 요소와 스크립트로 함께 연결하는 것을 의미합니다.

Godot의 씬 시스템은 Unity와 겉으로는 유사합니다. 'Level'은 노드 모음을 갖고 있으면서, 각 노드는 용도를 지니고 있습니다: Sprite, Mesh, Light 등. 하지만 Godot에서 노드는 트리로 정렬할 수 있습니다. 각 노드는 여러 자식을 가질 수 있고, 자식은 메인 씬의 하위 씬으로 이루어질 수 있습니다. 이는 즉, 다른 파일에 저장된 다른 씬으로 전체 씬을 작업할 수 있다는 것입니다.

예를 들어, 플랫포머 레벨을 생각해보자. 당신은 여러 요소들을 가지고 작업할 것입니다:

  • 벽돌
  • 동전
  • 플레이어

Unity에서, 모든 GameObjects를 씬에 넣을 것입니다: 플레이어, 여러 인스턴스 된 적, 레벨을 만드는 벽돌, 그리고 모든 레벨에 있는 여러 인스턴스 된 동전입니다. 그런 다음 각 요소들을 연결하고 레벨의 타당성을 주기 위한 다양한 구성 요소를 추가할 것입니다: 예를 들어 모든 요소에 BoxCollider2D를 추가해서 씬의 모든 요소가 충돌할 수 있도록 합니다. 이 원리가 Godot에서는 다릅니다.

Godot에서는 전체 씬을 별개의, 더 작은 세 개의 씬으로 나눕니다. 그리고 메인 씬으로 그 씬들을 인스턴스합니다.

  1. 플레이어만 있는 씬

플레이어를 다른 부모 씬에서도 사용할 수 있는 요소라고 생각해보세요 (예를 들어 'level' 씬이죠). 이 경우에는 플레이어 요소는 적어도 하나의 AnimatedSprite 노드가 필요합니다. 이 노드는 다양한 애니메이션을 주기 위해 스프라이트 텍스처가 반드시 필요합니다 (예를 들어 걷는 애니메이션).

  1. 적을 위한 씬

적도 마찬가지로 다양한 씬에서 사용할 수 있는 요소입니다. 플레이어 노드랑 거의 일치합니다. 유일한 차이점은 스크립트입니다 (적의 행동을 만드는 'AI' 루틴이 필요하죠). 그리고 AnimatedSprite 노드에 쓰이는 스프라이트도 다를 것입니다.

  1. 레벨 씬.

레벨 씬은 (플랫폼 용도) 블럭과, (플레이어가 모으는) 코인, 그리고 많은 양의 적 씬 인스턴스로 제작됩니다. 각 인스턴스는 레벨 씬 트리의 노드입니다. 이 인스턴스는 개별적인 적으로, 적 씬에서 정의한 대로 초기 값으로 행동과 모습을 공유합니다. 각 적 노드마다 다른 속성을 설정할 수 있습니다 (예를 들어, 색상을 바꾸는 것이 있죠).

4. A Main scene. The Main scene would be composed of one root node with 2 children: a Player instance node, and a Level instance node. The root node can be anything, generally a "root" type such as "Node" which is the most global type, or "Node2D" (root type of all 2D-related nodes), "Spatial" (root type of all 3D-related nodes) or "Control" (root type of all GUI-related nodes).

보시다시피, 모든 씬이 트리로 조직됩니다. 노드의 속성도 동일합니다: Unity처럼 노드가 충돌 가능하도록 충돌 구성 요소를 추가 할 수는 없습니다. 대신 충돌 속성을 가진 새로운 특정 노드를 자식 으로 만들 수 있습니다. Godot는 사용법에 따른 다양한 충돌 타입 노드가 있습니다 (물리 소개를 참고하세요).

  • 이 시스템의 장점은 뭐가 있나요? 이 시스템이 잠재적으로 씬 트리의 깊이를 늘리진 않을까요? 그리고 Unity는 이미 빈 GameObject에 GameObject를 넣는 것으로 이를 조직하는 것이 가능할텐데요?

    • Godot의 시스템은 잘 알려진 객체 기반 패러다임과 근접합니다: Godot는 많은 노드를 제공하지만 그것이 "Game Objects"라고 정의하기는 어렵습니다. 하지만 노드는 자신의 자식에게 자신의 기능을 제공합니다: 이것이 상속입니다.
    • Godot는 씬의 하위 씬을 추출해서 자체적인 씬을 만드는 것이 가능합니다. 따라서 씬 트리가 너무 깊어지면, 더 작은 하위 씬으로 분리하는 것이 가능합니다. 이 점으로 노드와 자식이 있으면 하위 씬을 만들 수 있기 때문에 재활용성에 더 좋습니다. Unity에서 빈 GameObject에 여러 GameObject를 넣는 방식은 같은 기능을 제공하지 못합니다.

프로젝트 조직

../../_images/unity-project-organization-example.png

완벽한 프로젝트 구조라는 것은 없습니다. 어떤 구조라도 Unity와 Godot에서 작업을 위해 만들 수 있습니다.

하지만 Unity 프로젝트를 위한 일반적인 구조는 루트 디렉토리에 하나의 Assets 폴더를 갖는 것입니다. 여기에는 다양한 폴더가 있으며 각 폴더마다 하나의 유형의 파일이 있습니다: 오디오, 그래픽, 모델, 머티리얼, 스크립트, 장면 등.

Godot는 씬을 더 작은 씬으로 분리할 수 있으므로, 프로젝트에서 각 씬과 하위 씬은 하나의 파일로 존재합니다. 프로젝트를 조금 다르게 조직하는 것을 추천합니다. 여기서는 프로젝트 조직을 알려주는 페이지를 알려 드리겠습니다: 프로젝트 조직.

프리펩은 어디갔나요?

Unity가 제공하는 프리펩의 개념은 씬의 '템플릿' 요소입니다. 다시 사용할 수 있고, 장면에서 프리펩의 각 인스턴스는 스스로 존재합니다. 하지만 모든 인스턴스는 프리펩에서 정의한 똑같은 속성을 갖고 있습니다.

Godot에서는 그러한 프리펩을 제공하지 않지만, 씬 시스템으로 같은 기능을 제공합니다: 씬 시스템은 트리로 조직됩니다. Godot는 씬의 하위 트리를 씬 파일로 저장할 수 있습니다. 이 새로운 씬은 노드의 자식으로 원하는 만큼 인스턴스할 수 있습니다. 앞에서 만든 하위 트리로 만든 씬에서 일어난 변경 사항은 인스턴스로 적용될 것입니다. 하지만 인스턴스에서 일어난 변경 사항은 '템플릿' 씬에게 영향을 주지 않을 것입니다.

../../_images/save-branch-as-scene.png

정확히는, 인스펙터(Inspector) 패널에서 인스턴스의 매개변수를 수정할 수 잇습니다. 이 인스턴스를 만든 노드는 초기값이 고정되어 있습니다. 고정 값을 풀고 싶다면 씬 트리에서 인스턴스를 우클릭한 뒤, 메뉴에서 "편집할 수 있는 자식(Editable children)"을 선택하세요. 이 노드에 새로운 자식 노드를 추가할 필요가 없습니다. 모든 새 자식은 인스턴스에 속하는 것이지, 디스크에 있는 '템플릿' 씬에 속하는 것이 아님을 명심하세요. '템플릿' 씬의 모든 인스턴스에게 새 자식을 추가하고 싶다면, 자식은 '템플릿' 씬에 추가해야 할 것입니다.

../../_images/editable-children.png

어휘 일치

  • GameObject -> 노드
  • 컴포넌트 추가 -> 상속
  • 프리펩 -> 다시 사용할 수 있는 씬 파일

스크립팅: GDScript, C# and Visual Script

디자인

Unity는 C#을 지원합니다. C#은 Visual Studio와의 통합의 이점이 있고 정적 타이핑과 같은 바람직한 기능을 갖고 있습니다.

Godot는 독자적인 스크립트 언어를 제공합니다, GDScriptVisual Script, 그리고 doc_c_sharp. GDScript는 Python의 문법을 빌려왔지만 관련은 없습니다. 왜 맞춤 스크립트 언어에 대해 궁금하다면, GDScript 기초자주 묻는 질문들(FAQ) 페이지를 참고해주세요. GDScript는 Godot API와 강하게 연결되어 있으면서도 배우는데 오래 걸리지 않습니다: 전문적인 프로그래머와 저번 주에 막 시작한 컴퓨터 초보자에게도 말이죠.

Unity는 GameObject에 원하는 만큼의 스크립트를 붙일 수 있습니다. 각 스크립트는 GameObject에 행동을 추가합니다: 예를 들어 스크립트를 붙여서 플레이어의 조작이나 특정 게임을 조작하는 다른 것을 넣을 수 있습니다.

Godot에서, 우리는 각 노드에 하나의 스크립트만 붙일 수 있습니다. 외부 GDScript 파일이나 노드에 스크립트를 직접 넣어서 사용할 수 있습니다. 한 노드에 더 많은 스크립트를 붙이고 싶다면, 씬이랑 원하는 것을 얻기 위해, 두 가지 방안을 고려하셔야 합니다:

  • 대상 노드와 현재 부모 노드 사이에 새 노드를 추가 한 다음, 이 노드에 스크립트를 추가합니다.
  • 또는, 대상 노드를 여러 자식 노드로 분할하고 각각마다 하나의 스크립트를 붙일 수 있습니다.

보다시피, 씬 트리는 쉽게 엉망이 될 수 있습니다. 복잡한 씬을 여러 개의, 더 작은 분기로 나누는 것을 생각해보세요.

연결: 그룹과 시그널

스크립트를 통해 노드에 접근하고 노드에서 내장 함수나 사용자가 정의한 함수를 호출하여 노드를 제어할 수 있습니다. 그리고 노드를 그룹에 배치하거나 이 그룹에 있는 모든 노드에서 함수를 호출할 수도 있습니다. 자세한 것은 스크립팅 문서를 참고하세요.

노드는 특정 동작이 발생할 때 시그널을 보냅니다. 시그널은 함수를 호출하도록 설정될 수 있습니다. 맞춤 시그널을 정의하고 언제 시그널을 보낼 지를 지정할 수 있습니다. 자세한 설명은 시그널 문서를 참고하세요.

스크립트 직렬화

Unity는 두 가지 방법으로 스크립트 직렬화를 다룰 수 있습니다:

  • Implicit(암시적): 한 클래스의 모든 퍼블릭 필드가 직렬화 할 수 있는 타입이면 (Dictionary는 직렬화 할 수 없음) 자동으로 직렬화 됩니다.
  • Explicit(명시적): 비 퍼블릭 필드를 [SerializeField] 속성을 사용하여 직렬화 되도록 할 수 있습니다.

Godot 또한 내장 스크립트 직렬화 시스템을 갖추고 있지만, 오직 명시적으로만 작동합니다. 어떤 직렬화 가능한 타입이라도 (class_Arrayclass_Dictionary를 포함한, 내장 그리고 다양한 엔진 타입) export 키워드를 사용해 직렬화 할 수 있습니다. 자세한 설명은 내보내기 문서를 참고하세요.

Unity 또한 맞춤 애셋 객체를 직렬화 하기 위해 사용되는 ScriptableObject 라는 데이터 타입을 갖고 있습니다. Godot에서 이것은 모든 리소스의 기본 클래스에 해당합니다: class_Resource. class_Resource를 상속하는 스크립트를 만드는 것으로 맞춤 직렬화 가능한 객체를 만들 수 있게 됩니다. 리소스에 관한 더 많은 정보는 여기서 볼 수 있습니다.

C++로 Godot 사용하기

Godot는 API를 사용하여 C++로 프로젝트를 직접 개발할 수 있게 해줍니다, 이는 현재 Unity에서는 불가능합니다. 예를 들어 Godot 엔진의 편집기를 Godot API를 사용하는 C++로 작성된 "게임"으로 간주할 수 있습니다.

C++로 Godot를 사용하는 것에 관심이 있으시다면, C++로 개발하기 페이지를 읽고 시작하시면 됩니다.