ui_game_user_interface.rst 27 KB

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