ui_game_user_interface.rst 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. .. _doc_ui_game_user_interface:
  2. Design the GUI
  3. ==============
  4. Now that you've nailed the basics, we're going to see how to build a
  5. game Graphical User Interface (GUI) with reusable UI components: a life bar, an
  6. energy bar, and bomb and emerald counters. By the end of this tutorial,
  7. you'll have a game GUI, ready to control with GDscript or VisualScript:
  8. .. figure:: img/ui_gui_design_final_result.png
  9. The final result
  10. You'll also learn to:
  11. 1. Create flexible UI components
  12. 2. Use scene inheritance
  13. 3. Build a complex UI
  14. Download the project files: :download:`ui_gui_design.zip <files/ui_gui_design.zip>` and extract the archive. Import the `start/` project in Godot to follow this tutorial. The `end/` folder contains the final result.
  15. .. note::
  16. You can watch this tutorial as a `video on YouTube <https://www.youtube.com/watch?v=y1E_y9AIqow>`_.
  17. Breaking down the UI
  18. --------------------
  19. Let's break down the final UI and plan the containers we'll use. As in
  20. the :doc:`ui_main_menu`, it starts with a ``MarginContainer``.
  21. Then, we can see up to three columns:
  22. 1. The life and energy counters on the left
  23. 2. The life and energy bars
  24. 3. The bomb and emerald counters on the right
  25. But the bar's label and the gauge are two parts of the same UI element.
  26. If we think of them this way, we're left with two columns:
  27. 1. The life and energy bars on the left
  28. 2. The bomb and emerald counters on the right
  29. This makes it easier to nest containers: we have some margins around the
  30. border of the screen using a ``MarginContainer``, followed by an
  31. ``HBoxContainer`` to manage our two columns. The two bars stack on top
  32. of one another inside a ``VBoxContainer``. And we'll need a last
  33. ``HBoxContainer`` in the right column to place the bomb and emerald
  34. counters side-by-side.
  35. .. figure:: img/ui_gui_step_tutorial_containers_structure.png
  36. We get a clean UI layout with only 4 containers
  37. We will need extra containers inside the individual UI components, but
  38. this gives us the main GUI scene's structure. With this plan in place,
  39. we can jump into Godot and create our GUI.
  40. Create the base GUI
  41. -------------------
  42. There are two possible approaches to the GUI: we can design elements in
  43. separate scenes and put them together, or prototype everything in a
  44. single scene and break it down later. I recommend working with a single
  45. scene as you can play with your UI's placement and proportions faster
  46. this way. Once it looks good, you can save entire sections of the node
  47. tree as reusable sub-scenes. We'll do that in a moment.
  48. For now, let's start with a few containers.
  49. Create a new scene and add a ``MarginContainer``. Select the node and name it
  50. ``GUI``.
  51. We want our interface to anchor to the top of the screen. Select the ``GUI``
  52. node and click the Layout button at the top of the viewport. Select the ``Top
  53. Wide`` option. The ``GUI`` node will anchor to the top edge of its parent, the
  54. viewport by default. It will resize automatically on the vertical axis to make
  55. space for its child UI components.
  56. Save the scene as ``GUI.tscn``. We will put the entire GUI in it.
  57. With the ``MarginContainer`` selected, head to the inspector and scroll
  58. down to the custom constants section. Unfold it and click the field next
  59. to each of the ``Margin`` properties. Set them all to ``20`` pixels.
  60. Next, add an ``HBoxContainer`` node. This one will contain our two bars
  61. on the left and separate them from the two counters on the right.
  62. We want to stack the bars vertically inside the ``HBoxContainer``.
  63. Add a ``VBoxContainer`` as a child of ``HBoxContainer`` and name it ``Bars``. Select the parent
  64. ``HBoxContainer`` again and this time, add another ``HBoxContainer`` as a child of it.
  65. Call it ``Counters``. With these four containers, we have the base for our GUI scene.
  66. .. figure:: img/ui_gui_containers_structure_in_godot.png
  67. You should have 4 containers that look like this
  68. .. note::
  69. We can work this way because we first broke down our UI design
  70. and took a few moments to think about the containers we'd use. When you
  71. follow a tutorial like this, it may seem weird. But once you're working
  72. on real games, you'll see it's an efficient workflow.
  73. Create the bars' base
  74. ~~~~~~~~~~~~~~~~~~~~~
  75. Each bar is split into two sub-elements that align horizontally: the
  76. label with the health count on the left, and the gauge on the right.
  77. Once again, the ``HBoxContainer`` is the perfect tool for the job.
  78. Select the ``Bars`` node and add a new ``HBoxContainer`` inside of it.
  79. Name it ``Bar``.
  80. The label itself requires at least three nodes: a ``NinePatchRect``
  81. for the background, on top of which we'll add a texture on the left,
  82. either ``HP`` or ``EP``, and a ``Label`` on the right for the value. We
  83. can nest ``Control`` nodes however we want. We could use the
  84. ``NinePatchRect`` as a parent for the two other elements, as it
  85. encompasses them. In general, you want to use containers instead, as
  86. their role is to help organize UI components. We'll need a
  87. ``MarginContainer`` later anyway to add some space between the life
  88. count and the gauge. Select the ``Bar`` and add a ``MarginContainer``.
  89. Name it ``Count``. Inside of it, add three nodes:
  90. 1. A ``NinePatchRect`` named ``Background``
  91. 2. A ``TextureRect`` named ``Title``
  92. 3. And a ``Label`` named ``Number``
  93. To add the nodes as siblings, always select the ``Count`` node first.
  94. .. figure:: img/ui_gui_step_tutorial_bar_template_1.png
  95. Your scene tree should look like this. We're ready to throw in some
  96. textures
  97. Our scene is still empty. It's time to throw in some textures. To load
  98. the textures, head to the FileSystem dock to the left of the viewport.
  99. Browse down to the res://assets/GUI folder.
  100. .. figure:: img/ui_gui_step_tutorial_textures_in_FileSystem_tab.png
  101. You should see a list of textures that we'll use to skin our
  102. interface.
  103. Select the ``Background`` in the Scene dock. In the Inspector, you
  104. should see a ``Texture`` property. In the FileSystem tab, click and drag
  105. ``label_HP_bg.png`` onto the ``Texture`` slot. It stays squashed. The
  106. parent MarginContainer will force its size down to 0 until we force
  107. elements inside the container to have a minimum size. Select the
  108. ``Background`` node. In the Inspector, scroll down to the Rect section.
  109. Set ``Min Size`` to (100, 40). You should see the ``Background`` resize
  110. along with its parent containers.
  111. Next, select the ``Title`` and drag and drop ``label_HP.png`` into its
  112. ``Texture`` slot. Select the ``Number`` node, click the field next to
  113. the ``Text`` property and type ``10``. This way, we can see both nodes
  114. in the viewport. They should stack up in the top-left corner of their
  115. parent ``MarginContainer``.
  116. .. figure:: img/ui_gui_step_tutorial_bar_label_stacked.png
  117. If you select both nodes, you should see something like this
  118. As they have a container as their direct parent, we cannot move them
  119. freely: the ``Count`` node will always reset their anchors, their size
  120. and position. Try to move and resize the nodes in the viewport. Then,
  121. select any of the three textures and press :kbd:`Ctrl + Up` or :kbd:`Ctrl + Down` to
  122. reorder them in the Scene dock. They'll snap back to their previous size
  123. and position.
  124. Parent containers control the size, the scale, the margins, and the
  125. anchors of their direct children. To modify the nodes, you must nest
  126. them inside a regular Control or another UI element. We'll use the
  127. ``Background`` as a parent for the ``Title`` and ``Number``. Select both
  128. the ``Title`` and ``Number``, and drag and drop them onto
  129. ``Background``.
  130. .. figure:: img/ui_gui_step_tutorial_bar_nesting_inside_background.png
  131. By using the Background node as the two textures' parent, we take
  132. control away from the Count MarginContainer
  133. Select the ``Title`` and in the Inspector, change its ``Stretch Mode`` property
  134. to ``Keep Centered``. Next find the ``Rect`` category in the Inspector and
  135. change the ``Size`` property to (50, 40) so it only takes the left half of
  136. the background. Next, select the ``Number`` node. In the viewport, click the
  137. ``Layout`` menu and click ``Full Rect``. The node will resize to fit
  138. the ``Background``. Head to the Inspector and change its ``Align``
  139. property to ``Right``, and the ``Valign`` property to ``Center``. The
  140. text should snap to the center of the ``Background``'s right edge.
  141. Resize the node horizontally, so it takes the right half of the
  142. ``Background`` and there's a bit of padding with the right edge.
  143. .. figure:: img/ui_gui_step_tutorial_bar_placed_title_and_label.png
  144. Here's how the nodes' bounding boxes should look in the viewport.
  145. Keep it rough, you don't need to place them too precisely for now.
  146. Replace the Label's font
  147. ~~~~~~~~~~~~~~~~~~~~~~~~
  148. The label's font is too small. We need to replace it. Select the
  149. ``Number`` node and in the Inspector, scroll down to the ``Control``
  150. class, and find the ``Custom Font`` category. Click the field next to
  151. the ``Font`` property and click on ``New Dynamic Font``. Click on the
  152. field again and select Edit.
  153. You will enter the ``Dynamic Font`` resource. Unfold the ``Font``
  154. category and click the field next to ``Font Data``. Click the ``Load``
  155. button. In the file browser, navigate down to the assets/font folder and
  156. double click ``Comfortaa-Bold.ttf`` to open it. You should see the font
  157. update in the viewport. Unfold the settings category to change the font
  158. size. Set the ``Size`` property to a higher value, like ``24`` or
  159. ``28``.
  160. We now need the text's baseline, the number's lower edge, to align with
  161. the HP texture on the left. To do so, still in the ``DynamicFont``
  162. resource, you can tweak the ``Bottom`` property under the
  163. ``Extra Spacing`` category. It adds some bottom padding to the text.
  164. Click the ``Number`` node in the Scene tab to go back to the node's
  165. properties and change the ``Valign`` to ``Bottom``. To adjust the text's
  166. baseline, click on the font field under the ``Custom Font`` category
  167. again and tweak the ``Bottom`` property until the text aligns with the
  168. ``Title`` node. I used a value of ``2`` pixels.
  169. .. figure:: img/ui_gui_step_tutorial_number_baseline.png
  170. With a Bottom value of 2 pixels, the Number aligns with the Title
  171. With this, we finished the hardest part of the GUI.
  172. Congratulations! Let's move on to the simpler nodes.
  173. Add the progress bar
  174. ~~~~~~~~~~~~~~~~~~~~
  175. We need one last element to complete our life bar: the gauge itself.
  176. Godot ships with a ``TextureProgress`` node that has everything we need.
  177. Select the Bar node and add a ``TextureProgress`` inside of it. Name it
  178. ``Gauge``. In the inspector unfold the ``Textures`` section. Head to the
  179. FileSystem dock and drag and drop the ``lifebar_bg.png`` texture onto
  180. the ``Under`` slot. Do the same with the ``lifebar_fill.png`` image and
  181. drop it onto the ``Progress`` slot. Under the ``Range`` class in the
  182. inspector, change the ``Value`` property to ``50`` to see the gauge fill
  183. up.
  184. With only five ``Control`` nodes, our first bar is ready to use.
  185. .. figure:: img/ui_gui_step_tutorial_bar_final.png
  186. That's it, our life bar is ready. This last part was quick, wasn't
  187. it? That's thanks to our robust container setup.
  188. Design the bomb and emerald counters
  189. ------------------------------------
  190. The bomb and emerald counters are like the bar's ``Count`` node. So we'll
  191. duplicate it and use it as a template.
  192. Under the ``Bar`` node, select ``Count`` and press :kbd:`Ctrl + D` to duplicate
  193. it. Drag and drop the new node under the ``Counters`` ``HBoxContainer``
  194. at the bottom of the scene tree. You should see it resize automatically.
  195. Don't worry about this for now, we'll fix the size soon.
  196. Rename the ``Count2`` node to ``Counter``. Unlike the bars, we want the
  197. number to be on the left, and an icon to sit on the right. The setup is
  198. the same: we need a background (a ``NinePatchRect``), the title, and the
  199. number nodes. The ``Title`` node is a ``TextureRect``, so it's what we
  200. need to display the icon. In the scene tree, select the ``Title`` node,
  201. and rename it to ``Icon``.
  202. .. figure:: img/ui_gui_step_tutorial_counter_design_1.png
  203. Here's how your node tree should look so far
  204. With the ``Icon`` node selected, in the inspector, scroll to the top to
  205. see the ``Texture`` slot. Head to the FileSystem dock on the left and
  206. select the ``bombs_icon.png``. Drag and drop it onto the ``Texture``
  207. slot. In the Scene Tab select both the ``Icon`` and the ``Number``
  208. nodes. Click the Layout menu in the toolbar at the top of the viewport
  209. and select ``Full Rect``. Both nodes will update to fit
  210. the size of the ``Background``.
  211. .. figure:: img/ui_gui_step_tutorial_counter_design_2.png
  212. The nodes anchor to the entire Background, but their position is off
  213. Let's change the ``Number``'s align properties to move it to the left
  214. and center of the ``Background``. Select the ``Number`` node, change its
  215. ``Align`` property to left and the ``Valign`` property to center. Then
  216. resize its left edge a bit to add some padding between the left
  217. edge of the ``Background`` and the text.
  218. .. figure:: img/ui_gui_step_tutorial_counter_design_3.png
  219. The Number node aligned to the left and center
  220. To overlap the Icon and the background, we need a few tweaks. First, our
  221. background is a bit too tall. It's because it's inside a margin
  222. container that is controlled by the top-most GUI node. Select the GUI
  223. node at the top of the scene tree and downsize it vertically so that
  224. it's as thin as possible. You'll see the gauge prevents you from making
  225. it too small. A container cannot be smaller than the minimal size of its
  226. children. The container's margins also weigh in.
  227. Select the Icon, click the Layout menu, and select
  228. ``Full Rect`` to re-center it. We need it to anchor to
  229. the ``Background``'s right edge. Open the Layout menu again and select
  230. ``Center Right``. Move the icon up so it is centered vertically with the
  231. ``Background``.
  232. .. figure:: img/ui_gui_step_tutorial_counter_design_4.png
  233. The bomb icon anchors to the Background's right edge. Resize the
  234. Counter container to see the Icon node stick to its right side
  235. Because we duplicated the ``Counter`` from the bar's ``Count``, the
  236. ``Number`` node's font is off. Select the ``Number`` node again, head to
  237. the ``Font`` property, and click it to access the ``DynamicFont``
  238. resource. In the ``Extra Spacing`` section, change the ``Bottom`` value
  239. to ``0`` to reset the font's baseline. Our counter now works as
  240. expected.
  241. Let's make the ``Counters`` anchor to the right edge of the viewport. To do so,
  242. we need to set the ``Bars`` container take all the available horizontal space it
  243. can. Select the ``Bars`` node and scroll down to the ``Size Flags`` category. In
  244. the ``Horizontal`` category, check the ``Expand`` value. The ``Bars`` node
  245. should resize and push the counter to the right side of the screen.
  246. .. figure:: img/ui_gui_step_tutorial_counter_design_5.png
  247. An expanding container eats all the space it can from its parent,
  248. pushing everything else along the way
  249. Turn the bar and counter into reusable UI components
  250. ----------------------------------------------------
  251. We have one bar and one counter widget. But we need two of each. We may
  252. need to change the bars' design or their functionality later on. It'd be
  253. great if we could have a single scene to store a UI element's template,
  254. and child scenes to work on variations. Godot lets us do this with
  255. Inherited Scenes.
  256. Let's save both the ``Counter`` and the ``Bar`` branches as separate
  257. scenes that we'll reduce to create the ``LifeBar``, the ``EnergyBar``,
  258. the ``BombCounter``, and the ``EmeraldCounter``. Select the ``Bar``
  259. HBoxContainer. Right click on it and click on ``Save Branch as Scene``.
  260. Save the scene as ``Bar.tscn``. You should see the node branch turn it
  261. to a single ``Bar`` node.
  262. .. tip::
  263. A scene is a tree of nodes. The topmost node is the tree's
  264. **root**, and the children at the bottom of the hierarchy are
  265. **leaves**. Any node other than the root along with one or more children is
  266. a **branch**. We can encapsulate node branches into separate scenes, or
  267. load and merge them from other scenes into the active one. Right click
  268. on any node in the Scene dock and select ``Save Branch as Scene`` or
  269. ``Merge from Scene``.
  270. Then, select the ``Counter`` node and do the same. Right click,
  271. ``Save Branch as Scene``, and save it as ``Counter.tscn``. A new edit
  272. scene icon appears to the right of the nodes in the scene tree. Click on
  273. the one next to ``Bar`` to open the corresponding scene. Resize the
  274. ``Bar`` node so that its bounding box fits its content. The way we named
  275. and placed the Control nodes, we're ready to inherit this template and
  276. create the life bar. It's the same for the ``Counter``.
  277. .. figure:: img/ui_gui_step_tutorial_bar_template_scene.png
  278. With no extra changes, our Bar is ready to use
  279. Use scene inheritance to create the remaining elements
  280. ------------------------------------------------------
  281. We need two bars that work the same way: they should feature a label on
  282. the left, with some value, and a horizontal gauge on the right. The only
  283. difference is that one has the HP label and is green, while the other is
  284. called EP and is yellow. Godot gives us a powerful tool to create a
  285. common base to reuse for all bars in the game: **inherited scenes**.
  286. .. figure:: img/gui_step_tutorial_gui_scene_hierarchy.png
  287. Inherited scenes help us keep the GUI scene clean. In the end, we
  288. will only have containers and one node for each UI component.
  289. On an inherited scene, you can change any property of every node in the
  290. inspector, aside from its name. If you modify and save the parent scene,
  291. all the inherited scenes update to reflect the changes. If you change a
  292. value in the inherited scene, it will always override the parent's
  293. property. It's useful for UIs, as they often require variations of the same
  294. elements. In general, in UI design, buttons, panels etc. share a common
  295. base style and interactions. We don't want to copy it over to all
  296. variations manually.
  297. A reload icon will appear next to the properties you override. Click it
  298. to reset the value to the parent scene's default.
  299. .. note::
  300. Think of scene inheritance like the node tree, or the
  301. ``extends`` keyword in GDScript. An inherited scene does everything like
  302. its parent, but you can override properties, resources and add extra
  303. nodes and scripts to extend its functionality.
  304. Inherit the Bar Scene to build the LifeBar
  305. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  306. Go to ``Scene -> New Inherited Scene`` to create a new type of ``Bar``.
  307. Select the Bar scene and open it. You should see a new [unsaved] tab,
  308. that's like your ``Bar``, but with all nodes except the root in grey.
  309. Press :kbd:`Ctrl + S` (:kbd:`Cmd + S` on macOS) to save the new inherited scene and name it
  310. ``LifeBar``.
  311. .. figure:: img/ui_gui_step_tutorial_inherited_scene_parent.png
  312. You can't rename grey nodes. This tells you they have a parent scene
  313. First, rename the root or top level node to ``LifeBar``. We always want
  314. the root to describe exactly what this UI component is. The name
  315. differentiates this bar from the ``EnergyBar`` we'll create next. The
  316. other nodes inside the scene should describe the component's structure
  317. with broad terms, so it works with all inherited scenes. Like our
  318. ``TextureProgress`` and ``Number`` nodes.
  319. .. note::
  320. If you've ever done web design, it's the same spirit as
  321. working with CSS: you create a base class, and add variations with
  322. modifier classes. From a base button class, you'll have button-green and
  323. button-red variations for the user to accept and refuse prompts. The new
  324. class contains the name of the parent element and an extra keyword to
  325. explain how it modifies it. When we create an inherited scene and change
  326. the name of the top level node, we're doing the same thing.
  327. Design the EnergyBar
  328. ~~~~~~~~~~~~~~~~~~~~
  329. We already setup the ``LifeBar``'s design with the main ``Bar`` scene.
  330. Now we need the ``EnergyBar``.
  331. Let's create a new inherited scene, and once again select the
  332. ``Bar.tscn`` scene and open it. Double-click on the ``Bar`` root node and rename it
  333. to ``EnergyBar``. Save the new scene as ``EnergyBar.tscn``.
  334. We need to replace the HP texture with EP one, and to
  335. change the textures on the gauge.
  336. Head to the FileSystem dock on the left, select the ``Title`` node in
  337. the Scene tree and drag and drop the ``label_EP.png`` file onto the
  338. texture slot. Select the ``Number`` node and change the ``Text``
  339. property to a different value like ``14``.
  340. You'll notice the EP texture is smaller than the HP one. We should
  341. update the ``Number``'s font size to better fit it. A font is a
  342. resource. All the nodes in the entire project that use this resource
  343. will be affected by any property we change. You can try to change the
  344. size to a huge value like ``40`` and switch back to the ``LifeBar`` or
  345. the ``Bar`` scenes. You will see the text increased in size.
  346. .. figure:: img/ui_gui_step_tutorial_design_EnergyBar_1.png
  347. If we change the font resource, all the nodes that use it are
  348. affected
  349. To change the font size on this node only, we must create a copy of the
  350. font resource. Select the ``Number`` node again and click on the wrench
  351. and screwdriver icon on the top right of the inspector. In the drop-down
  352. menu, select the ``Make Sub-Resources Unique`` option. Godot will find
  353. all the resources this node uses and create unique copies for us.
  354. .. figure:: img/ui_gui_step_tutorial_design_EnergyBar_2.png
  355. Use this option to create unique copies of the resources for one node
  356. .. tip::
  357. When you duplicate a node from the Scene tree, with
  358. :kbd:`Ctrl + D` (:kbd:`Cmd + D` on macOS), it shares its resources with the original node. You
  359. need to use ``Make Sub-Resources Unique`` before you can tweak the
  360. resources without affecting the source node.
  361. Scroll down to the ``Custom Font`` section and open ``Font``. Lower the
  362. ``Size`` to a smaller value like ``20`` or ``22``. You may also need to
  363. adjust the ``Bottom`` spacing value to align the text's baseline with
  364. the EP label on the left.
  365. .. figure:: img/ui_gui_step_tutorial_design_EnergyBar_3.png
  366. The EP Count widget, with a smaller font than its HP counterpart
  367. Now, select the ``TextureProgress`` node. Drag the ``energy_bar_bg.png``
  368. file onto the ``Under`` slot and do the same for ``energy_bar_fill.png``
  369. and drop it onto the ``Progress`` texture slot.
  370. You can resize the node vertically so that its bounding rectangle fits
  371. the gauge. Do the same with the ``Count`` node until its size aligns
  372. with that of the bar. Because the minimal size of ``TextureProgress`` is
  373. set based on its textures, you won't be able to downsize the ``Count``
  374. node below that. That is also the size the ``Bar`` container will have.
  375. You may downscale this one as well.
  376. Last but not least, the ``Background`` container has a minimum size that
  377. makes it a bit large. Select it and in the ``Rect`` section, change the
  378. ``Min Size`` property down to ``80`` pixels. It should resize
  379. automatically and the ``Title`` and ``Number`` nodes should reposition
  380. as well.
  381. .. figure:: img/ui_gui_step_tutorial_design_EnergyBar_4.png
  382. The Count looks better now it's a bit smaller
  383. .. tip::
  384. The Count node's size affects the position of the
  385. TextureProgress. As we'll align our bars vertically in a moment, we're
  386. better off using the Counter's left margin to resize our EP label. This
  387. way both the EnergyBar's Count and the LifeBar's Count nodes are one
  388. hundred pixels wide, so both gauges will align perfectly.
  389. Prepare the bomb and emerald counters
  390. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  391. Let us now take care of the counters. Go to
  392. ``Scene -> New Inherited Scene`` and select the ``Counter.tscn`` as a
  393. base. Rename the root node as ``BombCounter`` too.
  394. Save the new scene as ``BombCounter.tscn``. That's all for this scene.
  395. .. figure:: img/ui_gui_step_tutorial_design_counters_1.png
  396. The bomb counter is the same as the original Counter scene
  397. Go to ``Scene -> New Inherited Scene`` again and select ``Counter.tscn``
  398. once more. Rename the root node ``EmeraldCounter`` and save the scene as ``EmeraldCounter.tscn``.
  399. For this one, we mainly need to replace the bomb icon
  400. with the emerald icon. In the FileSystem tab, drag the ``emeralds_icon.png``
  401. onto the ``Icon`` node's ``Texture`` slot. ``Icon`` already anchors to
  402. the right edge of the ``Background`` node so we can change its position
  403. and it will scale and reposition with the ``EmeraldCounter`` container.
  404. Shift the emerald icon a bit to the right and down. Use the Arrow
  405. Keys on the keyboard to nudge its position. Save, and we're done with
  406. all the UI elements.
  407. .. figure:: img/ui_gui_step_tutorial_design_counters_2.png
  408. The emerald counter should look something like this
  409. Add the UI components to the final GUI
  410. --------------------------------------
  411. Time to add all the UI elements to the main GUI scene. Open the
  412. ``GUI.tscn`` scene again, and delete the ``Bar`` and ``Counter`` nodes.
  413. In the FileSystem dock, find the ``LifeBar.tscn`` and drag and drop it
  414. onto the ``Bars`` container in the scene tree. Do the same for the
  415. ``EnergyBar``. You should see them align vertically.
  416. .. figure:: img/ui_gui_step_tutorial_assemble_final_gui_1.png
  417. The LifeBar and the EnergyBar align automatically
  418. Now, drag and drop the ``BombCounter.tscn`` and ``EmeraldCounter.tscn`` scenes onto the
  419. ``Counters`` node. They'll resize automatically.
  420. .. figure:: img/ui_gui_step_tutorial_assemble_final_gui_2.png
  421. The nodes resize to take all the available vertical space
  422. To let the ``EmeraldCounter`` and ``BombCounter`` use the size we defined
  423. in ``Counter.tscn``, we need to change the ``Size Flags`` on the
  424. ``Counters`` container. Select the ``Counters`` node and unfold the
  425. ``Size Flags`` section in the Inspector. Uncheck the ``Fill`` tag for
  426. the ``Vertical`` property, and check ``Shrink Center`` so the container
  427. centers inside the ``HBoxContainer``.
  428. .. figure:: img/ui_gui_step_tutorial_assemble_final_gui_3.png
  429. Now both counters have a decent size
  430. .. tip::
  431. Change the ``Min Size`` property of the ``Counters`` container
  432. to control the height of the counters' background.
  433. We have one small issue left with the EP label on the EnergyBar: the 2
  434. bars should align vertically. Click the icon next to the ``EnergyBar``
  435. node to open its scene. Select the ``Count`` node and scroll down to the
  436. ``Custom Constants`` section. Add a ``Margin Left`` of ``20``. In
  437. the ``Rect`` section set the node's ``Min Size`` back to 100, the same
  438. value as on the LifeBar. The ``Count`` should now have some margin on
  439. the left. If you save and go back to the GUI scene, it will be aligned
  440. vertically with the ``LifeBar``.
  441. .. figure:: img/ui_gui_step_tutorial_assemble_final_gui_4.png
  442. The 2 bars align perfectly
  443. .. note::
  444. We could have set up the ``EnergyBar`` this way a few moments
  445. ago. But this shows you that you can go back to any scene anytime, tweak
  446. it, and see the changes propagate through the project!
  447. Place the GUI onto the game's mockup
  448. ------------------------------------
  449. To wrap up the tutorial we're going to insert the GUI onto the game's
  450. mockup scene.
  451. Head to the FileSystem dock and open ``LevelMockup.tscn``.
  452. Drag-and-drop the ``GUI.tscn`` scene right below the ``bg`` node and
  453. above the ``Characters``. The GUI will scale to fit the entire viewport.
  454. Head to the Layout menu and select the ``Center Top`` option so it anchors
  455. to the top edge of the game window. Then resize the GUI to make it as
  456. small as possible vertically. Now you can see how the interface looks in
  457. the context of the game.
  458. Congratulations for getting to the end of this long tutorial. You can
  459. find the final project here: :download:`ui_gui_design.zip <files/ui_gui_design.zip>`.
  460. .. figure:: img/ui_gui_design_final_result.png
  461. The final result
  462. .. note::
  463. **A final note about Responsive Design**. If you resize the
  464. GUI, you'll see the nodes move, but the textures and text won't scale.
  465. The GUI also has a minimum size, based on the textures inside of it. In
  466. games, we don't need the interface to be as flexible as that of a
  467. website. You almost never want to support both landscape and portrait
  468. screen orientations. It's one or the other. In landscape orientation,
  469. the most common ratios range from 4:3 to 16:9. They are close to one
  470. another. That's why it's enough for the GUI elements to only move
  471. horizontally when we change the window size.