컨트롤(Control) 노드로 인터페이스를 설계하기

Computer displays, mobile phones, and TV screens come in all shapes and sizes. To ship a game, you'll need to support different screen ratios and resolutions. It can be hard to build responsive interfaces that adapt to all platforms. Thankfully, Godot comes with robust tools to design and manage a responsive User Interface.

../../_images/godot_editor_ui.png

Godot 편집기는 엔진의 UI 프레임 워크로 제작되었습니다

이 강좌는 UI 디자인으로 시작할 것입니다. 당신은 이러한 것들을 배울 겁니다:

  • 게임 인터페이스를 제작하는 유용한 다섯 가지 Control 노드들
  • UI 요소들의 앵커 작업 방법
  • 컨테이너를 사용해서 사용자 인터페이스를 효율적으로 배치하고 배열하는 방법
  • 다섯 가지 가장 일반적인 컨테이너 (나중에 GUI Containers 문서 페이지에서 컨테이너에 대해 더 자세하게 배울 수 있습니다).

인터페이스를 컨트롤하고 다른 스크립트에 연결하는 방법을 배우려면, Build your first game UI in Godot <doc_ui_game_user_interface> 를 읽어주세요.

UI를 설계하기 위해, Control 노드를 사용하게됩니다. 이 노드들은 편집기에서 초록색 아이콘을 갖습니다. 이들을 수 십개가 존재하며, 이걸로 라이프바에서 복잡한 애플리케이션까지 만들 수 있습니다. Godot의 편집기 자체는 Control 노드를 사용하여 만들어졌습니다.

Control 노드는 다른 노드를과 함께 잘 작동하는 독특한 속성들을 갖습니다. Node2D, Sprite와 같은 다른 시각적 노드들은 이런 능력이 없습니다. 따라서 UI를 더 쉽게 작업하고 싶다면, 가능하면 Control 노드를 사용하세요.

모든 컨트롤 노드는 동일한 메인 속성을 공유합니다:

  1. 앵커(Anchor)
  2. 경계 사각형(Bounding rectangle)
  3. 포커스(Focus)와 포커스 이웃(Focus neighbor)
  4. 사이즈 플래그(Size flags)
  5. 마진(Margin)
  6. 선택적인 UI 테마

일단 당신이 컨트롤 노드의 기초를 이해했다면, 노드에서 파생되는 모든 다른 노드들을 이해하는 데 오래 걸리지 않을 겁니다.

가장 일반적인 5개의 UI 요소들

Godot는 수십 개의 컨트롤 노드를 갖고 있습니다. 이들이 당신이 편집기 플러그인과 애플리케이션을 만드는 것을 도와줍니다.

대부분의 게임에, 당신은 오로지 다섯 가지 UI 요소와, 몇 개의 컨테이너들만 필요합니다. 컨트롤 노드들은 이렇습니다:

  1. Label: 문자를 보여주기 위해 사용합니다
  2. TextureRect: 보통은 배경으로 사용되고, 그 외 모든 정적 이미지에 사용합니다
  3. TextureProgress: 체력 막대, 로딩 막대, 가로 형태, 세로 형태, 혹은 방사 형태에 사용합니다
  4. NinePatchRect: 확장 가능한 패널에 사용합니다
  5. TextureButton: 버튼을 만들기 위해 사용합니다
../../_images/five_most_common_nodes.png

UI 디자인을 위한 5개의 가장 일반적인 컨트롤 노드들

TextureRect

TextureRect 은 UI 내에 텍스처나 이미지를 보여줍니다. 이것은 Sprite 노드와 비슷하지만 다중 크기 조절 모드를 제공합니다. Sprite 노드의 동작을 변경하려면 Stretch Mode 속성을 설정하세요:

  • Scale On Expand (compat)expand 속성이 true로 되어 있을 때만 텍스처를 노드의 경계 사각형에 꽉 차도록 크기를 조절합니다; 그렇지 않으면 이것은 Keep 모드와 같습니다. 호환성을 되돌리기 위한 기본 모드.
  • Scale은 텍스처를 노드의 경계 사각형에 꽉 차도록 크기를 조절합니다.
  • Tile은 텍스처를 바둑판으로 배열하고, 크기를 조절하지 않습니다.
  • KeepKeep Centered는 텍스처가 그 크기를 유지하게 합니다, 각각 텍스처를 경계의 좌측 상단과 중심에 두도록 만듭니다.
  • Keep AspectKeep Aspect Centered는 텍스처의 크기를 조절하지만 그것의 크기 비율은 유지합니다, 각각 텍스처를 경계의 좌측 상단과 중심에 두도록 만듭니다.
  • Keep Aspect CoveredKeep Aspect Centered와 비슷하지만 경계 사각형의 짧은 변 쪽은 꽉 차는 반면, 긴 변 쪽은 노드의 경계까지만 보여주고 짤립니다.

Sprite 노드와 마찬가지로, 당신은 TextureRect의 색상을 바꿀 수 있습니다. Modulate 속성을 눌러 색상 선택기를 사용하세요.

../../_images/five_common_nodes_textureframe.png

빨강 색으로 바뀐 TextureRect

TextureButton

TextureButton 은 TextureRect와 비슷하지만, 5개의 텍스처 슬롯을 갖고 있습니다: 이들은 각 버튼의 상태입니다. 대부분은, Normal, Pressed, 그리고 Hover 텍스처를 사용할 겁니다. Focused는 인터페이스가 키보드의 입력을 수신하는 경우에 유용합니다. 여섯 번째 이미지 슬롯인, Click Mask는, 순수한 흰색과 검은색 2-비트를 사용해 클릭할 수 있는 영역을 정의하게 만듭니다.

Base Button 섹션에서, 당신은 버튼이 행동하는 법을 바꾸는 몇 가지 체크 상자를 볼 수 있을 겁니다. Toggle Mode 가 켜지면, 버튼은 당신이 눌렀을 때 활성화와 기본 상태를 껏다 켯다 할 것입니다. Disabled 는 버튼을 기본 상태로 만들고, 이 경우에 Disabled 텍스처를 사용합니다. TextureButton은 앞의 노드와 몇 가지 속성들을 공유합니다: modulate 속성을 갖고 있어서, 색상을 바꿀 수 있고, ResizeStretch 모드로 크기의 변화를 바꿀 수 있습니다.

../../_images/five_common_nodes_texturebutton.png

TextureButton과 5개의 텍스처 슬롯

TextureProgress

TextureProgress 는 진행 막대를 만들기 위해 3개의 스프라이트로 층을 쌓습니다. Under와 Over 텍스처 사이에 막대의 값을 보여줄 Progress를 끼워 넣습니다.

Mode 속성은 어느 방향으로 막대가 자라게 할지 제어합니다: 수평, 수직 아니면 방사형으로 말입니다. 방사형으로 설정하면, Initial AngleFill Degrees 속성으로 당신은 게이지의 범위를 제한할 수 있습니다.

To animate the bar, you'll want to look at the Range section. Set the Min and Max properties to define the range of the gauge. For instance, to represent a character's life, you'll want to set Min to 0, and Max to the character's maximum life. Change the Value property to update the bar. If you leave the Min and Max values to the default of 0 and 100, and set the Value property to 40, 40% of the Progress texture will show up, and 60% of it will stay hidden.

../../_images/five_common_nodes_textureprogress.png

3분의 2가 채워진 TextureProgress 막대

라벨(Label)

Label 은 문자를 화면에 출력합니다. 당신은 이것의 모든 속성을 인스펙터의 Label 섹션에서 찾으실 수 있습니다. Text 속성에서 문자를 쓰고, 텍스트 상자의 크기에 맞추어 자동줄바꿈을 하여 글자가 표시되기를 원한다면 Autowrap을 체크하세요. Autowrap이 체크가 풀려있으면, 노드의 크기를 조절할 수 없습니다. 당신은 Align과 Valign을 사용해서 문자를 가로와 세로로 정렬할 수 있습니다.

../../_images/five_common_nodes_label.png

Label의 사진

NinePatchRect

NinePatchRect 텍스처를 3행과 3열로 분할합니다. 중앙과 가장자리는 텍스처의 크기에 맞추어지지만, 모서리 부분은 크기가 바뀌지 않습니다. 이것은 패널이나 대화 상자, UI에서 크기 조절이 가능한 배경을 만들 때 유용합니다.

../../_images/five_common_nodes_ninepatchrect.png

min_size 속성으로 조절된 NinePatchRect

반응형 UI를 만들기 위한 두 가지 워크플로가 있습니다

Godot에서 확장성 있고 유연한 인터페이스를 만들기 위한 두 가지 워크플로가 있습니다:

  1. 원하는 만큼의 UI 요소들을 확장하고 배치할 수 있는 많은 컨테이너 노드들이 있습니다. 컨테이너는 그들의 자식인 UI 요소들을 제어합니다.
  2. 반대로, 당신은 레이아웃 메뉴가 있습니다. 이것은 UI 요소들을 부모 내에서 부모위치를 기준로 위치를 고정하거나 배치하고 크기 조절하도록 돕습니다.

두 가지 방법(컨테이너와 레이아웃)이 항상 호환되는 것은 아닙니다. 컨테이너는 자식을 제어하기 때문에, 레이아웃 메뉴를 그것들에게 사용할 수 없습니다. 각 컨테이너는 특정한 효과를 갖고 있으므로 당신은 제대로 동작하는 인터페이스를 얻기 위해 그들을 중첩해서 사용할지도 모릅니다. 레이아웃 접근으로는 자식들을 계층상 아래에서 위로 작업합니다. 씬에 추가적인 컨테이너를 사용하지 않으므로 더 깨끗한 계층 구조를 만들 수 있지만, 항목을 행이나 열, 격자 등으로 배열하기는 더 어렵습니다.

게임과 도구를 위해 UI를 만들 때, 당신은 각 상황에서 무엇이 가장 적당한지에 대한 감각을 기르게 될 것입니다.

앵커를 사용하여 UI 요소를 정밀하게 배치하세요

컨트롤 노드는 position과 size를 갖고 있고, anchors와 margins도 있습니다. Anchors는 노드의 Left, Top, Right, Bottom 모서리를 위해 원점이나 기준점을 정의합니다. 4개의 앵커 중 아무거나 바꿔서 margins의 기준점을 변경하세요.

../../_images/anchor_property.png

앵커 속성

앵커를 바꾸는 방법

모든 속성과 마찬가지로, 인스펙터에서 4개의 앵커 포인트를 편집할 수 있습니다만, 가장 편리한 방법은 아닙니다. 컨트롤 노드를 선택할 때, 레이아웃 메뉴가 뷰포트 위의 툴바에 나타납니다. 여기에는 아이콘 목록이 있는데 이것으로 4개의 앵커들을 모두 설정할 수 있습니다, 인스펙터의 4개의 속성을 사용하는 대신 말이죠. 레이아웃 메뉴는 오직 컨트롤 노드를 선택할 때만 보여집니다.

../../_images/layout_menu.png

뷰포트 내의 레이아웃 메뉴

앵커는 부모 컨테이너를 기준로 합니다

각 앵커는 0부터 1사이의 값을 갖습니다. 왼쪽과 위 앵커가 0의 값을 갖는 것은 마진이 없다는 것을 의미하고, 노드의 가장자리는 부모 노드의 왼쪽 위에 정렬됩니다. 오른쪽과 아래 가장자리가 1의 값을 갖는 것은 부모 컨테이너의 오른쪽과 아래 가장자리에 정렬된다는 것을 의미합니다. 한편, 마진은 앵커의 위치에서 거리를 픽셀 단위로 나타냅니다, 반면에 앵커는 부모 컨테이너의 크기와 관련이 있습니다.

../../_images/ui_anchor_and_margins.png

마진은 앵커 위치에 상대적이고, 앵커 위치는 앵커와 상대적입니다. 실제의 경우, 당신은 종종 컨테이너가 마진을 업데이트하도록 할 것입니다

마진은 앵커가 변하면 같이 변합니다

컨트롤 노드를 움직이고 크기를 조정할 때 마진은 자동으로 업데이트 됩니다. 마진은 컨트롤 노드의 모서리에서 앵커까지의 거리를 나타내고, 앵커는 부모 컨트롤 노드나 컨테이너의 위치에 대해 상대적입니다. 이것이 우리가 곧 알게 될, 컨트롤 노드가 항상 컨테이너에 있는 이유입니다. 부모가 없다면, 마진은 인스펙터 내에 Rect 섹션에 설정된, 자신의 경계 사각형에 상대적으로 될 것입니다.

../../_images/control_node_margin.png

CenterContainer에 있는 "Full Rect" 앵커로 설정된 마진

한번 앵커 위치를 바꾸거나 컨트롤 노드를 컨테이너 안에 넣어보세요: 마진은 업데이트 될 것입니다. 당신은 거의 마진을 수동으로 편집하진 않을 것입니다. 항상 당신을 도와줄 컨테이너를 골라보세요; Godot는 모든 일반적인 경우를 해결하기 위한 노드를 제공합니다. 체력 막대와 화면 테두리 사이에 빈 공간이 필요한가요? MarginContainer를 사용하세요. 세로 메뉴를 만들고 싶나요? VBoxContainer를 사용하세요. 아래에서 더 자세히 설명하겠습니다.

UI 요소가 이용 가능한 영역을 채우는 방식을 바꾸기 위해서 사이즈 태그를 사용하세요

모든 컨트롤 노드는 Size Flags를 가지고 있습니다. 이들은 컨테이너가 어떻게 UI 요소들이 크기가 조정될 지를 말합니다. 만약 "Fill" 플래그를 Horizontal이나 Vertical 속성에 추가한다면, 노드의 경계 사각형은 가능한 모든 공간을 차지할 것이지만, 형제 노드를 가리지 않는 한에서 크기를 조절할 겁니다. 만약 HBoxContainer에 3개의 TextureRect 노드가 있고, "Fill" 플래그가 두 방향 모두에 있다면, 그들은 각자의 가능한 공간의 3분의 1을 차지하고 그 외는 사용하지 않을 겁니다. 컨테이너는 노드를 제어하여 크기를 자동으로 조절합니다.

../../_images/textureframe_in_box_container_fill.png

HBoxContainer에 있는 3개의 UI 요소들, 이들은 수평으로 정렬됩니다

"Expand" 플래그는 UI 요소가 가능한 모든 공간을 차지하게 만들고, 형제 노드를 밀어냅니다. 경계 사각형은 부모의 모서리까지, 혹은 다른 UI 노드로 가로막힐 때까지 커집니다.

../../_images/textureframe_in_box_container_expand.png

위와 같은 샘플 예제에서, 가운데 노드는 "Expand" 사이즈 플래그가 설정되어 있습니다

당신이 사이즈 태그를 이해하려면 몇 번의 연습이 필요할 겁니다, 왜냐하면 당신이 인터페이스를 만드는 방식에 따라서 결과가 많이 달라지기 때문입니다.

컨테이너에 컨트롤 노드를 자동으로 배열하기

컨테이너는 자동으로 모든 자식 컨트롤 노드와 자식 컨테이너들을 열이나 행이나 그 밖의 형태로 배열합니다. 컨테이너를 사용해서 이것의 경계 사각형 내에서 인터페이스나 중심 노드 주위에 패딩을 추가합니다. 모든 내장 컨테이너는 편집기 내에서 업데이트 되므로 컨테이너가 작동되는 것을 바로 확인하실 수 있습니다.

컨테이너는 UI 요소들을 배열하는 방법을 제어하기 위한 일부 특별한 속성을 지닙니다. 컨테이너를 변화하기 위해, 인스펙터의 Custom Constants 섹션으로 갑시다.

다섯 가지 가장 유용한 컨테이너들

당신이 도구를 제작하는 것이라면, 모든 컨테이너가 필요할 수도 있겠지만, 대부분의 게임들은, 이정도만 있어도 충분합니다:

  • MarginContainer, UI의 가장자리에 여백을 추가함
  • CenterContainer, 경계 사각형 안에 자식을 중앙에 둠
  • VboxContainer와 HboxContainer, UI 요소들을 행이나 열로 배열함
  • GridContainer, 컨트롤 노드를 바둑판 같은 무늬로 배열함

CenterContainer는 경계 사각형의 안에 모든 자식들을 가운데로 놓습니다. 이것은 당신이 뷰포트의 중앙에 있을 타이틀 화면에 일반적으로 사용합니다. 모든 것을 중앙에 두기 때문에, 내부에 하나의 컨테이너가 중첩되어 있어야 합니다. 대신 텍스처나 버튼을 놓는다면, 그들은 쌓일 것입니다.

../../_images/five_containers_centercontainer.png

실행 중인 CenterContainer. 체력 막대가 부모 컨테이너의 중앙에 있다.

MarginContainer는 자식 노드의 사방에 여백을 추가합니다. 모든 뷰포트를 둘러싸는 MarginContainer를 추가하고 창과 UI의 가장자리 사이에 간격을 두세요. 당신은 컨테이너의 top, left, right, 아니면 bottom 방향에 여백을 설정할 수 있습니다. 체크박스는 건들지 않아도 됩니다: 해당하는 값의 상자를 선택하고 아무 숫자나 치세요. 자동으로 작동합니다.

../../_images/five_containers_margincontainer.png

게임 사용자 인터페이스 주변에 MarginContainer가 40px의 여백을 추가합니다

두 개의 박스컨테이너가 있습니다: VBoxContainer와 HBoxContainer이죠. BoxContainer 노드는 도움을 주는 클래스이므로 그대로 사용하지 못합니다, 하지만 수직이나 수평으로 된 박스컨테이너는 사용할 수 있습니다. 이들은 노드를 행이나 열로 배열합니다. 이들을 사용해서 상점의 아이템을 늘어놓거나, 행과 열을 다른 크기로 하여 복잡한 격자를 만들 수 있고, 이걸로 당신은 마음 속 내용을 만들어낼 수 있습니다.

../../_images/five_containers_boxcontainer.png

HBoxContainer가 UI 요소들을 수평으로 배열합니다

VBoxContainer는 자동으로 자식들을 세로로 배열합니다. 자식들을 차례로 하나 씩 놓습니다. 당신이 separation 한도를 설정하면, 자식들 사이에 틈이 생기게 됩니다. HBoxContainer는 자식들을 가로로 배열합니다. 이것은 VBoxContainer와 유사하게, 스크립트에서 맨 앞이나 맨 뒤에 간격을 띄우는 컨트롤 노드를 추가하는, add_spacer 메서드를 갖고 있습니다.

GridContainer는 UI 요소들을 격자 같은 무늬로 배열합니다. 당신은 오직 세로 열의 숫자만 제어할 수 있는데, 가로 행의 수는 자식의 수에 따라 스스로 설정됩니다. 당신이 9개의 자식을 3열로 배열한다면, 9÷3 = 3행을 가지게 됩니다. 자식이 3개 더 늘어나면 4행을 가지게 됩니다. 이는 즉, 당신이 더 많은 텍스처와 버튼을 추가해 행을 늘릴 수 있습니다. 박스 컨테이너처럼, 이것도 각기 행과 열 사이에 수직과 수평 분리를 설정하는 두 개의 속성이 있습니다.

../../_images/five_containers_gridcontainer.png

2열로 된 GridContainer. 각 행은 자동으로 크기가 조절됩니다.

Godot의 UI 시스템은 복잡하고, 그만큼 많은 것을 제공합니다. 더 좋은 인터페이스를 만드는 방법을 배우기 위해선, 문서의 GUI 섹션으로 가십시오.