Progettare la GUI¶
Ora che hai fissato le basi, vedremo come creare un interfaccia utente (GUI) per il gioco con componenti UI riutilizzabili: una barra della vita, una dell'energia, una bomba e un contatore degli smeraldi. Arrivato alla fine di questo tutorial, avrai una GUI per il gioco, pronto per controllarla con GDScript o VisualScript:
Imparerai anche a:
Creare un componente UI flessibile
Use scene inheritance
Creare una UI complessa
Scarica i file del progetto
ui_gui_design.zip ed estrai l'archivio. Importa il progetto start/ in Godot per seguire questo tutorial. La cartella end/ contiene i risultati finali.
Puoi vedere questo tutorial come video su YouTube.
Scomporre la UI¶
Andiamo ad analizzare l'UI e pianifichiamo i contenitori che useremo. Come in Progetta una schermata del titolo, partiremo con un
MarginContainer. Poi, potremo creare fino a tre colonne:
I contatori della vita e dell'energia a sinistra
Le barre della vita e dell'energia
I contatori delle bombe e degli smeraldi a destra
Ma l'etichetta della barra e l'indicatore sono due parti dello stesso elemento dell'interfaccia utente. Se li pensiamo in questo modo, rimangono due colonne:
Le barre della vita e dell'energia a sinistra
I contatori delle bombe e degli smeraldi a destra
This makes it easier to nest containers: we have some margins around the
border of the screen using a
MarginContainer, followed by an
HBoxContainer to manage our two columns. The two bars stack on top
of one another inside a
VBoxContainer. And we'll need a last
HBoxContainer in the right column to place the bomb and emerald
We will need extra containers inside the individual UI components, but this gives us the main GUI scene's structure. With this plan in place, we can jump into Godot and create our GUI.
Create the base GUI¶
There are two possible approaches to the GUI: we can design elements in separate scenes and put them together, or prototype everything in a single scene and break it down later. I recommend working with a single scene as you can play with your UI's placement and proportions faster this way. Once it looks good, you can save entire sections of the node tree as reusable sub-scenes. We'll do that in a moment.
For now, let's start with a few containers.
Create a new scene and add a
MarginContainer. Select the node and name it
We want our interface to anchor to the top of the screen. Select the
node and click the Layout button at the top of the viewport. Select the
Wide option. The
GUI node will anchor to the top edge of its parent, the
viewport by default. It will resize automatically on the vertical axis to make
space for its child UI components.
Save the scene as
GUI.tscn. We will put the entire GUI in it.
MarginContainer selected, head to the inspector and scroll
down to the custom constants section. Unfold it and click the field next
to each of the
Margin properties. Set them all to
Next, add an
HBoxContainer node. This one will contain our two bars
on the left and separate them from the two counters on the right.
Vogliamo, ora, ordinare le barre in verticale nel
HBoxContainer`. Aggiungiamo un ``VBoxContainer``come figlio di ``HBoxContainer``e rinominiamolo come ``Bars. Selezioniamo il genitore
HBoxContainer nuovamente e questa volta aggiungiamo un nuovo
HBoxContainer``come figlio. Chiamiamolo ``Counters. Con questi quattro contenitori abbiamo la base per la nostra interfaccia utente.
Possiamo procedere in questo modo, dato che prima mettiamo già l'interfaccia grafica e ci prendiamo un momento per pensare a quali contenitori possiamo utilizzare. Quando segui un tutorial come questo, potrebbe sembrarti strano. Ma appena comincerai a lavorare sui veri e propri videogiochi, ti sembrerà una procedura efficiente.
Create the bars' base¶
Ogni barra è divisa in due sub-elementi che allinierai orizzontalmente: La barra della salute sulla sinistra e la barra della forza sulla destra. Ancora una volta il
HBoxContainer``è lo strumento perfetto per questo lavoro. Seleziona il nodo ``Bars e aggiungi un nuovo
HBoxContainer``al suo interno. Rinominalo come ``Bar.
L'etichetta richiede almeno tre nodi: un
NinePatchRect per lo sfondo, nella parte alta dove aggiungeremo una texture a sinistra, sia
EP, e una
Label a destra per i valori. Possiamo innestare un nodo
Control ogni volta che vogliamo. Possiamo usare il
NinePatchRect come genitore per altri due elementi, così da comprimerli. In generale, se al contrario vuoi usare i contenitori, così da aiutarti da organizzare i componenti dell'interfaccia giocatore. Abbiamo bisogno di un
MarginContainer`più tardi per aggiungere uno spazio tra la barra della vita e gli altri indicatori. Seleziona ``Bar e aggiungi un
MarginContainer. Rinominalo``Count``. Al suo interno, aggiungi tre nodi:
To add the nodes as siblings, always select the
Count node first.
La nostra scena è ancora vuota. E' il momento per inserire qualche Texture. Per caricarle, vai sulla sezione File di Sistema alla sinistra della visualizzazione. Cerca in res://assets/GUI folder.
Background in the Scene dock. In the Inspector, you
should see a
Texture property. In the FileSystem tab, click and drag
label_HP_bg.png onto the
Texture slot. It stays squashed. The
parent MarginContainer will force its size down to 0 until we force
elements inside the container to have a minimum size. Select the
Background node. In the Inspector, scroll down to the Rect section.
Min Size to (100, 40). You should see the
along with its parent containers.
Title``e trascina``label_HP.png nel suo slot
Texture. Seleziona il nodo
Number, clicca sul campo dopo le proprietà
Text e digita
10. In questo modo, puoi vedere entrambi i nodi nella visualizzazione. Dovrebbero allinearsi nella parte alta a sinistra del loro genitore
Avendo un contenitore come loro diretto genitore, non possiamo muoverli liberamente: il nodo
Count ripristinerà i suoi punti di ancoraggio, la sua dimensione e posizione. Prova a muovere e ridimensionare i nodi nella viewport. Poi, seleziona una delle tre texture e premi Ctrl + Su o Ctrl + Giù per riordinarli nel riquadro Scena. Torneranno alle dimensioni e posizione precedenti.
Parent containers control the size, the scale, the margins, and the
anchors of their direct children. To modify the nodes, you must nest
them inside a regular Control or another UI element. We'll use the
Background as a parent for the
Number. Select both
Number, and drag and drop them onto
Title and in the Inspector, change its
Stretch Mode property
Keep Centered. Next find the
Rect category in the Inspector and
Size property to (50, 40) so it only takes the left half of
the background. Next, select the
Number node. In the viewport, click the
Layout menu and click
Full Rect. The node will resize to fit
Background. Head to the Inspector and change its
Right, and the
Valign property to
text should snap to the center of the
Background's right edge.
Resize the node horizontally, so it takes the right half of the
Background and there's a bit of padding with the right edge.
Replace the Label's font¶
The label's font is too small. We need to replace it. Select the
Number node and in the Inspector, scroll down to the
class, and find the
Custom Font category. Click the field next to
Font property and click on
New Dynamic Font. Click on the
field again and select Edit.
You will enter the
Dynamic Font resource. Unfold the
category and click the field next to
Font Data. Click the
button. In the file browser, navigate down to the assets/font folder and
Comfortaa-Bold.ttf to open it. You should see the font
update in the viewport. Unfold the settings category to change the font
size. Set the
Size property to a higher value, like
We now need the text's baseline, the number's lower edge, to align with
the HP texture on the left. To do so, still in the
resource, you can tweak the
Bottom property under the
Extra Spacing category. It adds some bottom padding to the text.
Number node in the Scene tab to go back to the node's
properties and change the
Bottom. To adjust the text's
baseline, click on the font field under the
Custom Font category
again and tweak the
Bottom property until the text aligns with the
Title node. I used a value of
Con questo, abbiamo finito la parte più difficile della GUI. Congratulazioni! Passiamo ai nodi più semplici.
Aggiungi la barra di avanzamento¶
Abbiamo bisogno di un ultimo elemento per completare la nostra barra della vita: l'indicatore stesso. Godot fornisce un nodo
TextureProgress che ha tutto ciò di cui abbiamo bisogno.
Select the Bar node and add a
TextureProgress inside of it. Name it
Gauge. In the inspector unfold the
Textures section. Head to the
FileSystem dock and drag and drop the
lifebar_bg.png texture onto
Under slot. Do the same with the
lifebar_fill.png image and
drop it onto the
Progress slot. Under the
Range class in the
inspector, change the
Value property to
50 to see the gauge fill
Con solo cinque nodi
Control, la nostra prima barra è pronta all'uso.
Progettare i contatori di bombe e smeraldi¶
I contatori delle bombe e degli smeraldi sono come il nodo
Count della barra. Quindi lo duplicheremo e lo useremo come modello.
Bar node, select
Count and press Ctrl + D to duplicate
it. Drag and drop the new node under the
at the bottom of the scene tree. You should see it resize automatically.
Don't worry about this for now, we'll fix the size soon.
Count2 node to
Counter. Unlike the bars, we want the
number to be on the left, and an icon to sit on the right. The setup is
the same: we need a background (a
NinePatchRect), the title, and the
number nodes. The
Title node is a
TextureRect, so it's what we
need to display the icon. In the scene tree, select the
and rename it to
Icon node selected, in the inspector, scroll to the top to
Texture slot. Head to the FileSystem dock on the left and
bombs_icon.png. Drag and drop it onto the
slot. In the Scene Tab select both the
Icon and the
nodes. Click the Layout menu in the toolbar at the top of the viewport
Full Rect. Both nodes will update to fit
the size of the
Let's change the
Number's align properties to move it to the left
and center of the
Background. Select the
Number node, change its
Align property to left and the
Valign property to center. Then
resize its left edge a bit to add some padding between the left
edge of the
Background and the text.
To overlap the Icon and the background, we need a few tweaks. First, our background is a bit too tall. It's because it's inside a margin container that is controlled by the top-most GUI node. Select the GUI node at the top of the scene tree and downsize it vertically so that it's as thin as possible. You'll see the gauge prevents you from making it too small. A container cannot be smaller than the minimal size of its children. The container's margins also weigh in.
Select the Icon, click the Layout menu, and select
Full Rect to re-center it. We need it to anchor to
Background's right edge. Open the Layout menu again and select
Center Right. Move the icon up so it is centered vertically with the
Because we duplicated the
Counter from the bar's
Number node's font is off. Select the
Number node again, head to
Font property, and click it to access the
resource. In the
Extra Spacing section, change the
0 to reset the font's baseline. Our counter now works as
Let's make the
Counters anchor to the right edge of the viewport. To do so,
we need to set the
Bars container take all the available horizontal space it
can. Select the
Bars node and scroll down to the
Size Flags category. In
Horizontal category, check the
Expand value. The
should resize and push the counter to the right side of the screen.
Trasformare la barra e il contatore in componenti UI riutilizzabili¶
We have one bar and one counter widget. But we need two of each. We may need to change the bars' design or their functionality later on. It'd be great if we could have a single scene to store a UI element's template, and child scenes to work on variations. Godot lets us do this with Inherited Scenes.
Let's save both the
Counter and the
Bar branches as separate
scenes that we'll reduce to create the
BombCounter, and the
EmeraldCounter. Select the
HBoxContainer. Right click on it and click on
Save Branch as Scene.
Save the scene as
Bar.tscn. You should see the node branch turn it
to a single
A scene is a tree of nodes. The topmost node is the tree's
root, and the children at the bottom of the hierarchy are
leaves. Any node other than the root along with one or more children is
a branch. We can encapsulate node branches into separate scenes, or
load and merge them from other scenes into the active one. Right click
on any node in the Scene dock and select
Save Branch as Scene or
Merge from Scene.
Then, select the
Counter node and do the same. Right click,
Save Branch as Scene, and save it as
Counter.tscn. A new edit
scene icon appears to the right of the nodes in the scene tree. Click on
the one next to
Bar to open the corresponding scene. Resize the
Bar node so that its bounding box fits its content. The way we named
and placed the Control nodes, we're ready to inherit this template and
create the life bar. It's the same for the
Usare l'ereditarietà della scena per creare i restanti elementi¶
We need two bars that work the same way: they should feature a label on the left, with some value, and a horizontal gauge on the right. The only difference is that one has the HP label and is green, while the other is called EP and is yellow. Godot gives us a powerful tool to create a common base to reuse for all bars in the game: inherited scenes.
On an inherited scene, you can change any property of every node in the inspector, aside from its name. If you modify and save the parent scene, all the inherited scenes update to reflect the changes. If you change a value in the inherited scene, it will always override the parent's property. It's useful for UIs, as they often require variations of the same elements. In general, in UI design, buttons, panels etc. share a common base style and interactions. We don't want to copy it over to all variations manually.
Un'icona di ricarica apparirà accanto alle proprietà che sovrascrivi. Fai clic su di essa per ripristinare il valore di default della scena madre.
Think of scene inheritance like the node tree, or the
extends keyword in GDScript. An inherited scene does everything like
its parent, but you can override properties, resources and add extra
nodes and scripts to extend its functionality.
Ereditare la scena della Barra per costruire la Barra della Vita¶
Scene -> New Inherited Scene to create a new type of
Select the Bar scene and open it. You should see a new [unsaved] tab,
that's like your
Bar, but with all nodes except the root in grey.
Press Ctrl + S (Cmd + S on macOS) to save the new inherited scene and name it
First, rename the root or top level node to
LifeBar. We always want
the root to describe exactly what this UI component is. The name
differentiates this bar from the
EnergyBar we'll create next. The
other nodes inside the scene should describe the component's structure
with broad terms, so it works with all inherited scenes. Like our
If you've ever done web design, it's the same spirit as working with CSS: you create a base class, and add variations with modifier classes. From a base button class, you'll have button-green and button-red variations for the user to accept and refuse prompts. The new class contains the name of the parent element and an extra keyword to explain how it modifies it. When we create an inherited scene and change the name of the top level node, we're doing the same thing.
Progettare la Barra dell'Energia¶
We already setup the
LifeBar's design with the main
Now we need the
Let's create a new inherited scene, and once again select the
Bar.tscn scene and open it. Double-click on the
Bar root node and rename it
EnergyBar. Save the new scene as
We need to replace the HP texture with EP one, and to
change the textures on the gauge.
Head to the FileSystem dock on the left, select the
Title node in
the Scene tree and drag and drop the
label_EP.png file onto the
texture slot. Select the
Number node and change the
property to a different value like
You'll notice the EP texture is smaller than the HP one. We should
Number's font size to better fit it. A font is a
resource. All the nodes in the entire project that use this resource
will be affected by any property we change. You can try to change the
size to a huge value like
40 and switch back to the
Bar scenes. You will see the text increased in size.
To change the font size on this node only, we must create a copy of the
font resource. Select the
Number node again and click on the wrench
and screwdriver icon on the top right of the inspector. In the drop-down
menu, select the
Make Sub-Resources Unique option. Godot will find
all the resources this node uses and create unique copies for us.
When you duplicate a node from the Scene tree, with
Ctrl + D (Cmd + D on macOS), it shares its resources with the original node. You
need to use
Make Sub-Resources Unique before you can tweak the
resources without affecting the source node.
Scroll down to the
Custom Font section and open
Font. Lower the
Size to a smaller value like
22. You may also need to
Bottom spacing value to align the text's baseline with
the EP label on the left.
Now, select the
TextureProgress node. Drag the
file onto the
Under slot and do the same for
and drop it onto the
Progress texture slot.
You can resize the node vertically so that its bounding rectangle fits
the gauge. Do the same with the
Count node until its size aligns
with that of the bar. Because the minimal size of
set based on its textures, you won't be able to downsize the
node below that. That is also the size the
Bar container will have.
You may downscale this one as well.
Last but not least, the
Background container has a minimum size that
makes it a bit large. Select it and in the
Rect section, change the
Min Size property down to
80 pixels. It should resize
automatically and the
Number nodes should reposition
The Count node's size affects the position of the TextureProgress. As we'll align our bars vertically in a moment, we're better off using the Counter's left margin to resize our EP label. This way both the EnergyBar's Count and the LifeBar's Count nodes are one hundred pixels wide, so both gauges will align perfectly.
Prepare the bomb and emerald counters¶
Let us now take care of the counters. Go to
Scene -> New Inherited Scene and select the
Counter.tscn as a
base. Rename the root node as
Save the new scene as
BombCounter.tscn. That's all for this scene.
Scene -> New Inherited Scene again and select
once more. Rename the root node
EmeraldCounter and save the scene as
For this one, we mainly need to replace the bomb icon
with the emerald icon. In the FileSystem tab, drag the
Icon already anchors to
the right edge of the
Background node so we can change its position
and it will scale and reposition with the
Shift the emerald icon a bit to the right and down. Use the Arrow
Keys on the keyboard to nudge its position. Save, and we're done with
all the UI elements.
Add the UI components to the final GUI¶
Time to add all the UI elements to the main GUI scene. Open the
GUI.tscn scene again, and delete the
In the FileSystem dock, find the
LifeBar.tscn and drag and drop it
Bars container in the scene tree. Do the same for the
EnergyBar. You should see them align vertically.
Now, drag and drop the
EmeraldCounter.tscn scenes onto the
Counters node. They'll resize automatically.
To let the
BombCounter use the size we defined
Counter.tscn, we need to change the
Size Flags on the
Counters container. Select the
Counters node and unfold the
Size Flags section in the Inspector. Uncheck the
Fill tag for
Vertical property, and check
Shrink Center so the container
centers inside the
Min Size property of the
to control the height of the counters' background.
We have one small issue left with the EP label on the EnergyBar: the 2
bars should align vertically. Click the icon next to the
node to open its scene. Select the
Count node and scroll down to the
Custom Constants section. Add a
Margin Left of
Rect section set the node's
Min Size back to 100, the same
value as on the LifeBar. The
Count should now have some margin on
the left. If you save and go back to the GUI scene, it will be aligned
vertically with the
We could have set up the
EnergyBar this way a few moments
ago. But this shows you that you can go back to any scene anytime, tweak
it, and see the changes propagate through the project!
Place the GUI onto the game's mockup¶
To wrap up the tutorial we're going to insert the GUI onto the game's mockup scene.
Head to the FileSystem dock and open
GUI.tscn scene right below the
bg node and
Characters. The GUI will scale to fit the entire viewport.
Head to the Layout menu and select the
Center Top option so it anchors
to the top edge of the game window. Then resize the GUI to make it as
small as possible vertically. Now you can see how the interface looks in
the context of the game.
Congratulations for getting to the end of this long tutorial. You can
find the final project here:
A final note about Responsive Design. If you resize the GUI, you'll see the nodes move, but the textures and text won't scale. The GUI also has a minimum size, based on the textures inside of it. In games, we don't need the interface to be as flexible as that of a website. You almost never want to support both landscape and portrait screen orientations. It's one or the other. In landscape orientation, the most common ratios range from 4:3 to 16:9. They are close to one another. That's why it's enough for the GUI elements to only move horizontally when we change the window size.