유니티(Unity)에서 Godot 엔진까지

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

차이점

  유니티(Unity) Godot(Godot)
라이선스 수익 상한과 사용 제한이 있는 독점적이고 폐쇄적인 무료 라이선스 MIT 라이선스로, 어떤 제한 없이 무료이고 완전한 오픈 소스
OS (에디터) 윈도우, macOS, 리눅스 (비공식이고 지원되지 않음) 윈도우, macOS, X11 (리눅스, *BSD)
OS (내보내기)
  • 데스크톱: 윈도우, macOS, 리눅스
  • 모바일: 안드로이드, iOS, 윈도우 폰, 타이젠(Tizen)
  • 웹: WebAssembly이나 asm.js
  • 콘솔: PS4, PS Vita, Xbox One, Xbox 360, Wii U, Nintendo 3DS
  • VR: 오큘러스 리프트, SteamVR, 구글 카드보드, 플레이스테이션 VR, Gear VR, HoloLens
  • TV: 안드로이드 TV, 삼성 스마트 TV, tvOS
  • 데스크톱: 윈도우, macOS, X11
  • 모바일: 안드로이드, iOS
  • 웹: WebAssembly
  • 콘솔: Godot의 콘솔 지원 을 확인하세요
  • VR: 오큘러스 리프트, SteamVR
씬 시스템
  • 컴포넌트/씬(GameObject > Component)
  • 프리펩
Scene tree and nodes, 씬을 중첩하거나 다른 씬을 상속할 수 있습니다
타사 도구 비주얼 스튜디오 혹은 VS Code
킬러 기능
  • 거대한 커뮤니티
  • 넓은 에셋 스토어

에디터

Godot 엔진은 당신이 게임을 만들기 위한 풍부한 기능을 가진 에디터를 제공합니다. 아래의 그림은 두 에디터 간 공통 기능을 표시하는 색칠된 사각형을 보여줍니다.

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

Godot 에디터는 당신이 원하는 씬 에디터 옆에 각 패널을 고정할 수 있습니다.

두 에디터가 비슷해 보이지만, 외양 아래에 많은 차이가 있습니다. 둘 다 파일 시스템을 사용해서 프로젝트를 조직할 수 있지만, Godot의 접근은 하나의 구성 파일, 미니멀리스트 텍스트 형식, 그리고 메타데이터가 없는 것으로 더 간단합니다. 이 모든 것이 Godot가 Git, Subversion, Mercurial와 같은 버전 관리 시스템에 훨씬 더 친숙한 데 기여합니다.

Godot의 씬 패널은 유니티의 계층 패널과 비슷하지만,각 노드는 특정 기능을 갖고 있기 때문에, Godot에서 사용하는 접근은 더 시작적으로 묘사됩니다. 즉, 특정 씬이 한눈에 무엇을 하는지 더 쉽게 이해할 수 있습니다.

Godot의 인스펙터는 더 미니멀리스트하고 속성 만을 보여주기 위해 설계되었습니다. 덕분에, 객체는 언어 API에서 기능성을 숨길 필요 없이 훨씬 더 넓은 유용한 매개 변수를 사용자에게 내보낼 수 있습니다. 거기에, Godot는 어떤 시각적 속성도 애니메이트 할 수 있기 때문에, 색상이나 텍스쳐, 열거, 혹은 심지어 리소스 링크를 실시간으로 변경하는 것이 코드 없이 가능합니다.

마지막으로, 화면 위의 툴바는 프로젝트 재생을 다루는 의미 상 비슷해 보입니다. 하지만 Godot의 프로젝트는 편집기 내부에서 실행되지 않고, 분리된 창에서 실행됩니다 (하지만 디버거 창에서 트리와 객체를 계속 탐구할 수 있습니다).

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

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

마지막으로, 상단 툴바는 원격 디버깅을 위한 메뉴가 있습니다. 이 설정은 기기에 배포하기 쉽도록 만듭니다 (핸드폰, 태블릿, 혹은 HTML5를 통한 브라우저를 연결), 그리고 게임을 내보낸 후 디버그/실시간 편집을 거기서 하도록 만듭니다.

씬 시스템

유니티와 Godot와의 가장 중요한 차이점이자, Godot 사용자들이 가장 좋아하는 기능입니다.

유니티의 씬 시스템은 필요한 씬에 모든 에셋을 포함하고 구성 요소와 스크립트를 설정함으로써 그들을 연결하도록 구성되어 있습니다.

Godot의 씬 시스템은 다릅니다: 사실 노드로 이루어진 트리를 구성하고 있습니다. 각 노드는 용도를 지니고 있습니다: 스프라이트, 메시, 빛 등. 기본적으로 유니티의 씬 시스템과 유사합니다. 하지만, 각 노드는 여러 개의 자식을 가질 수 있습니다, 그리고 그 자식들을 각기 다른 하위 씬으로 만들 수 있습니다. 즉, 서로 다른 파일에 저장된 여러 씬으로 전체 씬을 작업할 수 있습니다.

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

  • 벽돌
  • 동전
  • 플레이어

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

Godot에서, 전체 씬을 3개의, 더 작은 씬으로 나누고, 그들을 메인 씬에 인스턴스 합니다.

  1. 먼저, 플레이어만 있는 씬입니다.

플레이어를 다른 레벨에도 재 사용 가능한 요소라고 생각해보세요. 특히 하나의 노드로 구성됩니다: 다양한 애니메이션을 구성하기 위한 스프라이트 텍스쳐를 가진 AnimatedSprite 노드 (예를 들면, 걷는 애니메이션)

  1. 두 번째, 적을 위한 씬입니다.

역시, 적은 다른 레벨에서 재 사용 가능합니다. Player 노드와 거의 똑같습니다 - 유일한 차이는 스크립트 입니다 (주로 AI를 다룹니다) 그리고 AnimatedSprite가 사용되는 스프라이트 텍스쳐입니다.

  1. 마지막으로, 레벨 씬입니다.

이것은 (플랫폼을 위한)블럭, (플레이어가 집을)동전 그리고 이전의 Enemy 씬의 일정한 수의 인스턴스로 구성되어 있습니다. 이들은 다른, 분리된 적으로, 행동과 양상은 같은 Enemy 씬에서 정의된 것과 같을 것입니다. 각 인스턴스는 이제 레벨 씬 트리의 노드로 취급됩니다. 물론, 각 Enemy 노드 마다 다른 속성을 설정할 수 있습니다 (예를 들어, 색상을 바꾸는 것).

마지막으로, 메인 씬은 이제 한 루트 노드와 2개의 자식으로 구성될 것입니다: Player 인스턴스 노드, 그리고 레벨 인스턴스 노드입니다. 루트 노드는 어떤 것도 될 수 있지만, 일반적으로 "루트" 타입은 가장 전역 타입인 "Node"나, (모든 2D 관련 노드의 루트 타입인) "Node2D", (모든 3D 관련 노드의 루트 타입인) "Spatial", (모든 GUI 관련 노드의 루트 타입인) "Control"이 됩니다.

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

  • 문제: 이 시스템의 장점은 무엇일까요? 이 시스템이 잠재적으로 씬 트리의 깊이를 증가시키지 않을까요? 게다가, 유니티는 비어있는 GameObjects에 그들을 넣어서 GameObjects를 조직할 수 있습니다.

    • 먼저, 이 시스템은 잘 알려진 객체 기반 어형 변화표와 근접합니다: Godot는 분명하지 않은 "Game Objects"인 여러 노드들을 제공합니다, 하지만 그들은 자식에게 자신의 능력을 제공합니다: 이것이 상속입니다.
    • 두 번째로, 씬의 하위 트리를 추출하여 고유의 씬을 만들 수 있습니다, 이걸로 두 번째와 세 번째 문제에 답할 수 있습니다: 비록 씬 트리가 너무 깊어지더라도, 더 작은 하위 트리로 나눌 수 있습니다. 또한 하위 트리가 어떤 노드의 자식이든지 추가될 수 있다는 점에서 재 사용 가능성에 더 좋은 해결책이 됩니다. 유니티에서 빈 GameObject에 많은 노드를 넣는 것으로는 시각적인 조직과는 별개로, 이와 같은 가능성을 제공하진 못합니다.

기억해야 할 가장 중요한 개념들 입니다: "노드", "부모 노드" 그리고 "자식 노드".

프로젝트 조직

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

우리는 이전에 프로젝트 구조를 설정하는 완벽한 해결책이 없다는 것을 인지하였습니다. 어떤 해결책이든 유니티와 Godot를 위해 작동할 것이기에, 이 점은 덜 중요합니다.

하지만, 우리는 종종 유니티 프로젝트를 위한 공통 구조를 발견합니다, 하나의 Assets 폴더가 루트 디렉토리로 하여 타입에 맞는 다양한 폴더를 가지고 있습니다: Audio, Graphics, Models, Materials, Scripts, Scenes 등.

앞에서 설명한 것처럼, Godot 씬 시스템은 씬을 더 작은 씬으로 분리합니다. 각 씬과 하위 씬은 사실 프로젝트에서 하나의 씬 파일이기 때문에, 우리는 프로젝트를 약간 다르게 구성하기를 추천합니다. 이 위키는 이것을 위한 페이지를 제공합니다: 프로젝트 조직.

프리펩은 어디갔나요?

유니티가 제공하는 프리펩의 개념은 씬의 '템플릿' 요소입니다. 그것은 씬에 존재하는 재 사용이 가능하며 씬에 존재하는 프리펩의 각 인스턴스는 주체성이 있지만, 이 모두는 프리펩에 의해 정의된 같은 속성을 지닙니다.

Godot는 그러한 프리펩을 제공하진 않지만, 씬 시스템 덕분에 그 기능이 있습니다: 우리가 씬 시스템이 트리처럼 조직된 것을 보셨습니다. Godot는 씬의 하위 트리를 자체 씬으로 저장하여 자체 파일로 저장합니다. 이 새로운 씬은 그 뒤 원하는 만큼 인스턴스 될 수 있습니다. 이 새로운 씬에 준 변화는 모든 인스턴스에 적용될 것입니다. 하지만 그 변화가 '템플릿' 씬에 영향을 주지는 않을 것입니다.

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

정확하게 말하면, 당신은 인스펙터 패널에서 인스턴스의 매개 변수를 수정할 수 있습니다. 하지만, 비록 당신이 씬 트리에서 인스턴스를 우클릭하고 "자식노드 편집 가능"를 선택하여 인스턴스를 잠금 해제할 수 있지만 이 인스턴스를 만드는 노드는 잠겨있습니다. 새 자식 노드를 추가하려고 이 작업을 할 필요는 없지만 가능은 합니다. 새 자식 은 인스턴스에 속해 있습니다, '템플릿' 씬이 아닙니다. '템플릿' 씬의 모든 인스턴스에 새 자식을 추가하려면, '템플릿' 씬에 새 자식을 추가해야 합니다.

../../_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와 밀접하고 배우기 쉽습니다: 숙련된 프로그래머든지 막 개발을 시작한 사람이든지 말입니다.

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

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

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

보시다시피 씬 트리를 뒤죽박죽으로 만드는 것은 쉽습니다. 그렇기 때문에 실제 상황을 반영하고 복잡한 씬을 여러 개의 작은 분기로 나누는 것이 중요합니다.

연결: 그룹과 시그널

You can control nodes by accessing them via script and calling built-in or user-defined functions on them. You can also place nodes in a group and call functions on all nodes in this group. See more in the scripting documentation.

Nodes can send a signal when a specified action occurs. A signal can be set to call any function. You can define custom signals and specify when they are triggered. See more in the signals documentation.

스크립트 직렬화

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

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

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

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

C++로 Godot 사용하기

Godot allows you to develop your project directly in C++ by using its API, which is not possible with Unity at the moment. As an example, you can consider Godot Engine's editor as a "game" written in C++ using the Godot API.

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