Design the GUI — Godot Engine (3.0) documentation in English (2024)

Now that you’ve nailed the basics, we’re going to see how to build aGame User Interface (GUI) with reusable UI components: a life bar, anenergy bar, and bomb and rupee counters. By the end of this tutorial,you’ll have a game GUI, ready to control with GDscript or VisualScript:

Design the GUI — Godot Engine (3.0) documentation in English (1)

The final result

You’ll also learn to:

  1. Create flexible UI components
  2. Use scene inheritance
  3. Build a complex UI

Download the project 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.

Note

You can watch this tutorial as a video on Youtube.

Breaking down the UI

Let’s break down the final UI and plan the containers we’ll use. As inthe Design a title screen, it starts with a MarginContainer.Then, we can see up to three columns:

  1. The life and energy counters on the left
  2. The life and energy bars
  3. The bomb and rupee counters on the right

But the bar’s label and the gauge are two parts of the same UI element.If we think of them this way, we’re left with two columns:

  1. The life and energy bars on the left
  2. The bomb and rupee counters on the right

This makes it easier to nest containers: we have some margins around theborder of the screen using a MarginContainer, followed by anHBoxContainer to manage our two columns. The two bars stack on topof one another inside a VBoxContainer. And we’ll need a lastHBoxContainer in the right column to place the bomb and rupeecounters side-by-side.

Design the GUI — Godot Engine (3.0) documentation in English (2)

We get a clean UI layout with only 4 containers

We will need extra containers inside the individual UI components, butthis 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 inseparate scenes and put them together, or prototype everything in asingle scene and break it down later. I recommend working with a singlescene as you can play with your UI’s placement and proportions fasterthis way. Once it looks good, you can save entire sections of the nodetree 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 andname it GUI. Then save the scene as GUI.tscn. It willcontain the entire GUI.

With the MarginContainer selected, head to the inspector and scrolldown to the custom constants section. Unfold it and click the field nextto each of the Margin properties. Set them all to 20 pixels.Next, add an HBoxContainer node. This one will contain our two barson the left and separate them from the two counters on the right.

We want to stack the bars vertically inside the HBoxContainer. To dothis, let’s add a VBoxContainer. Name it Bars. Select the parentHBoxContainer again and this time, add another HBoxContainer.This one will hold the counters, so call it Counters. With thesefour containers, we have the base for our GUI scene.

Design the GUI — Godot Engine (3.0) documentation in English (3)

You should have 4 containers that look like this

Note

We can work this way because we first broke down our UI designand took a few moments to think about the containers we’d use. When youfollow a tutorial like this, it may seem weird. But once you’re workingon real games, you’ll see it’s an efficient workflow.

Create the bars’ base

Each bar is split into two sub-elements that align horizontally: thelabel with the health count on the left, and the gauge on the right.Once again, the HBoxContainer is the perfect tool for the job.Select the Bars node and add a new HBoxContainer inside of it.Name it Bar.

The label itself requires at least three nodes: a NinePatchRectfor the background, on top of which we’ll add a texture on the left,either HP or EP, and a Label on the right for the value. Wecan nest Control nodes however we want. We could use theNinePatchRect as a parent for the two other elements, as itencompasses them. In general, you want to use containers instead, astheir role is to help organize UI components. We’ll need aMarginContainer later anyway to add some space between the lifecount and the gauge. Select the Bar and add a MarginContainer.Name it Count. Inside of it, add three nodes:

  1. A NinePatchRect named Background
  2. A TextureRect named Title
  3. And a Label named Number

To add the nodes as siblings, always select the Count node first.

Design the GUI — Godot Engine (3.0) documentation in English (4)

Your scene tree should look like this. We’re ready to throw in sometextures

Our scene is still empty. It’s time to throw in some textures. To loadthe textures, head to the FileSystem dock to the left of the viewport.Browse down to the res://assets/GUI folder.

Design the GUI — Godot Engine (3.0) documentation in English (5)

You should see a list of textures that we’ll use to skin ourinterface.

Select the Background in the Scene dock. In the Inspector, youshould see a Texture property. In the FileSystem tab, click and draglabel_HP_bg.png onto the Texture slot. It stays squashed. Theparent MarginContainer will force its size down to 0 until we forceelements inside the container to have a minimum size. Select theBackground node. In the Inspector, scroll down to the Rect section.Set Min Size to (100, 40). You should see the Background resizealong with its parent containers.

Next, select the Title and drag and drop label_HP.png into itsTexture slot. Select the Number node, click the field next tothe Text property and type 10. This way, we can see both nodesin the viewport. They should stack up in the top-left corner of theirparent MarginContainer.

Design the GUI — Godot Engine (3.0) documentation in English (6)

If you select both nodes, you should see something like this

As they have a container as their direct parent, we cannot move themfreely: the Count node will always reset their anchors, their sizeand position. Try to move and resize the nodes in the viewport. Then,select any of the three textures and press Ctrl Up or Ctrl Down toreorder them in the Scene dock. They’ll snap back to their previous sizeand position.

Parent containers control the size, the scale, the margins, and theanchors of their direct children. To modify the nodes, you must nestthem inside a regular Control or another UI element. We’ll use theBackground as a parent for the Title and Number. Select boththe Title and Number, and drag and drop them ontoBackground.

Design the GUI — Godot Engine (3.0) documentation in English (7)

By using the Background node as the two textures’ parent, we takecontrol away from the Count MarginContainer

Select the Title and in the Inspector, change its Stretch Mode propertyto Keep Centered. Next find the Rect category in the Inspector andchange the Size property to (50, 40) so it only takes the left half ofthe background. Next, select the Number node. In the viewport, click theLayout menu and click Full Rect. The node will resize to fitthe Background. Head to the Inspector and change its Alignproperty to Right, and the VAlign property to Center. Thetext should snap to the center of the Background’s right edge.Resize the node horizontally so it takes the right half of theBackground and there’s a bit of padding with the right edge.

Design the GUI — Godot Engine (3.0) documentation in English (8)

Here’s how the nodes’ bounding boxes should look in the viewport.Keep it rough, you don’t need to place them too precisely for now.

Replace the Label’s font

The label’s font is too small. We need to replace it. Select theNumber node and in the Inspector, scroll down to the Controlclass, and find the Custom Font category. Click the field next tothe Font property and click on New Dynamic Font. Click on thefield again and select Edit.

You will enter the Dynamic Font resource. Unfold the Fontcategory and click the field next to Font Data. Click the Loadbutton. In the file browser, navigate down to the assets/font folder anddouble click Comfortaa-Bold.ttf to open it. You should see the fontupdate in the viewport. Unfold the settings category to change the fontsize. Set the Size property to a higher value, like 24 or28.

We now need the text’s baseline, the number’s lower edge, to align withthe HP texture on the left. To do so, still in the DynamicFontresource, you can tweak the Bottom property under theExtra Spacing category. It adds some bottom padding to the text.Click the Number node in the Scene tab to go back to the node’sproperties and change the VAlign to Bottom. To adjust the text’sbaseline, click on the font field under the Custom Font categoryagain and tweak the Bottom property until the text aligns with theTitle node. I used a value of 2 pixels.

Design the GUI — Godot Engine (3.0) documentation in English (9)

With a Bottom value of 2 pixels, the Number aligns with the Title

With this, we finished the hardest part of the GUI.Congratulations! Let’s move on to the simpler nodes.

Add the progress bar

We need one last element to complete our life bar: the gauge itself.Godot ships with a TextureProgress node that has everything we need.

Select the Bar node and add a TextureProgress inside of it. Name itGauge. In the inspector unfold the Textures section. Head to theFileSystem dock and drag and drop the lifebar_bg.png texture ontothe Under slot. Do the same with the lifebar_fill.png image anddrop it onto the Progress slot. Under the Range class in theinspector, change the Value property to 50 to see the gauge fillup.

With only five Control nodes, our first bar is ready to use.

Design the GUI — Godot Engine (3.0) documentation in English (10)

That’s it, our life bar is ready. This last part was quick, wasn’tit? That’s thanks to our robust container setup.

Design the bomb and rupee counters

The bomb and rupee counters are like the bar’s Count node. So we’llduplicate it and use it as a template.

Under the Bar node, select Count and press Ctrl D to duplicateit. Drag and drop the new node under the Counters HBoxContainerat 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.

Rename the Count2 node to Counter. Unlike the bars, we want thenumber to be on the left, and an icon to sit on the right. The setup isthe same: we need a background (a NinePatchRect), the title, and thenumber nodes. The Title node is a TextureRect, so it’s what weneed to display the icon. In the scene tree, select the Title node,and rename it to Icon.

Design the GUI — Godot Engine (3.0) documentation in English (11)

Here’s how your node tree should look so far

With the Icon node selected, in the inspector, scroll to the top tosee the Texture slot. Head to the FileSystem dock on the left andselect the bombs_icon.png. Drag and drop it onto the Textureslot. In the Scene Tab select both the Icon and the Numbernodes. Click the Layout menu in the toolbar at the top of the viewportand select Full Rect. Both nodes will update to fitthe size of the Background.

Design the GUI — Godot Engine (3.0) documentation in English (12)

The nodes anchor to the entire Background, but their position is off

Let’s change the Number’s align properties to move it to the leftand center of the Background. Select the Number node, change itsAlign property to left and the VAlign property to centre. Thenresize its left edge a little bit to add some padding between the leftedge of the Background and the text.

Design the GUI — Godot Engine (3.0) documentation in English (13)

The Number node aligned to the left and centre

To overlap the Icon and the background, we need a few tweaks. First, ourbackground is a bit too tall. It’s because it’s inside a margincontainer that is controlled by the top-most GUI node. Select the GUInode at the top of the scene tree and downsize it vertically so thatit’s as thin as possible. You’ll see the gauge prevents you from makingit too small. A container cannot be smaller than the minimal size of itschildren. The container’s margins also weigh in.

Select the Icon, click the Layout menu, and selectFull Rect to re-center it. We need it to anchor tothe Background’s right edge. Open the Layout menu again and selectCenter Right. Move the icon up so it is centered vertically with theBackground.

Design the GUI — Godot Engine (3.0) documentation in English (14)

The bomb icon anchors to the Background’s right edge. Resize theCounter container to see the Icon node stick to its right side

Because we duplicated the Counter from the bar’s Count, theNumber node’s font is off. Select the Number node again, head tothe Font property, and click it to access the DynamicFontresource. In the Extra Spacing section, change the Bottom valueto 0 to reset the font’s baseline. Our counter now works asexpected.

While we are at it, let’s make it so the Counters snap to the rightedge of the viewport. To achieve this we will set the Bars containerto expand and take all the horizontal space. Select the Bars nodeand scroll down to the Size Flags category. In the Horizontalcategory, check the Expand value. The Bars node should resizeand push the counter to the rightmost of the screen.

Design the GUI — Godot Engine (3.0) documentation in English (15)

An expanding container eats all the space it can from its parent,pushing everything else along the way

Turn the bar and counter into reusable UI components

We have one bar and one counter widget. But we need two of each. We mayneed to change the bars’ design or their functionality later on. It’d begreat 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 withInherited Scenes.

Let’s save both the Counter and the Bar branches as separatescenes that we’ll reduce to create the LifeBar, the EnergyBar,the BombCounter, and the RupeeCounter. Select the BarHBoxContainer. Right click on it and click on Save Branch as Scene.Save the scene as Bar.tscn. You should see the node branch turn itto a single Bar node.

Tip

A scene is a tree of nodes. The topmost node is the tree’sroot, and the children at the bottom of the hierarchy areleaves. Any node other than the root along with one more children isa branch. We can encapsulate node branches into separate scenes, orload and merge them from other scenes into the active one. Right clickon any node in the Scene dock and select Save Branch as Scene orMerge 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 editscene icon appears to the right of the nodes in the scene tree. Click onthe one next to Bar to open the corresponding scene. Resize theBar node so that its bounding box fits its content. The way we namedand place the Control nodes, we’re ready to inherit this template andcreate the life bar. It’s the same for the Counter.

Design the GUI — Godot Engine (3.0) documentation in English (16)

With no extra changes, our Bar is ready to use

Use Scene Inheritance to create the remaining elements

We need two bars that work the same way: they should feature a label onthe left, with some value, and a horizontal gauge on the right. The onlydifference is that one has the HP label and is green, while the other iscalled EP and is yellow. Godot gives us a powerful tool to create acommon base to reuse for all bars in the game: inherited scenes.

Design the GUI — Godot Engine (3.0) documentation in English (17)

Inherited scenes help us keep the GUI scene clean. In the end, wewill only have containers and one node for each UI component.

On an inherited scene, you can change any property of every node in theinspector, aside from its name. If you modify and save the parent scene,all the inherited scenes update to reflect the changes. If you change avalue in the inherited scene, it will always overrides the parent’sproperty. It’s useful for UIs as they often require variations of the sameelements. In general, in UI design, buttons, panels etc. share a commonbase style and interactions. We don’t want to copy it over to allvariations manually.

A reload icon will appear next to the properties you override. Click itto reset the value to the parent scene’s default.

Note

Think of scene inheritance like the node tree, or theextends keyword in GDScript. An inherited scene does everything likeits parent, but you can override properties, resources and add extranodes and scripts to extend its functionality.

Inherit the Bar Scene to build the LifeBar

Go to Scene -> New Inherited Scene to create a new type of Bar.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 Meta+S to save the new inherited scene and name itLifeBar.

Design the GUI — Godot Engine (3.0) documentation in English (18)

You can’t rename grey nodes. This tells you they have a parent scene

First, rename the root or top level node to LifeBar. We always wantthe root to describe exactly what this UI component is. The namedifferentiates this bar from the EnergyBar we’ll create next. Theother nodes inside the scene should describe the component’s structurewith broad terms, so it works with all inherited scenes. Like ourTextureProgress and Number nodes.

Note

If you’ve ever done web design, it’s the same spirit asworking with CSS: you create a base class, and add variations withmodifier classes. From a base button class, you’ll have button-green andbutton-red variations for the user to accept and refuse prompts. The newclass contains the name of the parent element and an extra keyword toexplain how it modifies it. When we create an inherited scene and changethe name of the top level node, we’re doing the same thing.

Design the EnergyBar

We already setup the LifeBar’s design with the main Bar scene.Now we need the EnergyBar.

Let’s create a new inherited scene, and once again select theBar.tscn scene and open it. Double-click on the Bar root node and rename itto EnergyBar. Save the new scene as EnergyBar.tscn.We need to replace the HP texture with EP one, and tochange the textures on the gauge.

Head to the FileSystem dock on the left, select the Title node inthe Scene tree and drag and drop the label_EP.png file onto thetexture slot. Select the Number node and change the Textproperty to a different value like 14.

You’ll notice the EP texture is smaller than the HP one. We shouldupdate the Number’s font size to better fit it. A font is aresource. All the nodes in the entire project that use this resourcewill be affected by any property we change. You can try to change thesize to a huge value like 40 and switch back to the LifeBar orthe Bar scenes. You will see the text increased in size.

Design the GUI — Godot Engine (3.0) documentation in English (19)

If we change the font resource, all the nodes that use it areaffected

To change the font size on this node only, we must create a copy of thefont resource. Select the Number node again and click on the wrenchand screwdriver icon on the top right of the inspector. In the drop-downmenu, select the Make Sub-Resources Unique option. Godot will findall the resources this node uses and create unique copies for us.

Design the GUI — Godot Engine (3.0) documentation in English (20)

Use this option to create unique copies of the resources for one node

Tip

When you duplicate a node from the Scene tree, withMeta+D, it shares its resources with the original node. Youneed to use Make Sub-Resources Unique before you can tweak theresources without affecting the source node.

Scroll down to the Custom Font section and open Font. Lower theSize to a smaller value like 20 or 22. You may also need toadjust the Bottom spacing value to align the text’s baseline withthe EP label on the left.

Design the GUI — Godot Engine (3.0) documentation in English (21)

The EP Count widget, with a smaller font than its HP counterpart

Now, select the TextureProgress node. Drag the energy_bar_bg.pngfile onto the Under slot and do the same for energy_bar_fill.pngand drop it onto the Progress texture slot.

You can resize the node vertically so that its bounding rectangle fitsthe gauge. Do the same with the Count node until its size alignswith that of the bar. Because the minimal size of TextureProgress isset based on its textures, you won’t be able to downsize the Countnode 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 thatmakes it a bit large. Select it and in the Rect section, change theMin Size property down to 80 pixels. It should resizeautomatically and the Title and Number nodes should repositionas well.

Design the GUI — Godot Engine (3.0) documentation in English (22)

The Count looks better now it’s a bit smaller

Tip

The Count node’s size affects the position of theTextureProgress. As we’ll align our bars vertically in a moment, we’rebetter off using the Counter’s left margin to resize our EP label. Thisway both the EnergyBar’s Count and the LifeBar’s Count nodes are onehundred pixels wide, so both gauges will align perfectly.

Prepare the bomb and rupee counters

Let us now take care of the counters. Go toScene -> New Inherited Scene and select the Counter.tscn as abase. Rename the root node as BombCounter too.Save the new scene as BombCounter.tscn. That’s all for this scene.

Design the GUI — Godot Engine (3.0) documentation in English (23)

The bomb counter is the same as the original Counter scene

Go to Scene -> New Inherited Scene again and select Counter.tscnonce more. Rename the root node RupeeCounter and save the scene as RupeeCounter.tscn.For this one, we mainly need to replace the bomb iconwith the rupee icon. In the FileSystem tab, drag the rupees_icon.pngonto the Icon node’s Texture slot. Icon already anchors tothe right edge of the Background node so we can change its positionand it will scale and reposition with the RupeeCounter container.Shift the rupee icon a little bit to the right and down. Use the ArrowKeys on the keyboard to nudge its position. Save, and we’re done withall the UI elements.

Design the GUI — Godot Engine (3.0) documentation in English (24)

The rupee counter should look about like this

Add the UI components to the final GUI

Time to add all the UI elements to the main GUI scene. Open theGUI.tscn scene again, and delete the Bar and Counter nodes.In the FileSystem dock, find the LifeBar.tscn and drag and drop itonto the Bars container in the scene tree. Do the same for theEnergyBar. You should see them align vertically.

Design the GUI — Godot Engine (3.0) documentation in English (25)

The LifeBar and the EnergyBar align automatically

Now, drag and drop the BombCounter.tscn and RupeeCounter.tscn scenes onto theCounters node. They’ll resize automatically.

Design the GUI — Godot Engine (3.0) documentation in English (26)

The nodes resize to take all the available vertical space

To let the RupeeCounter and BombCounter use the size we definedin Counter.tscn, we need to change the Size Flags on theCounters container. Select the Counters node and unfold theSize Flags section in the Inspector. Uncheck the Fill tag forthe Vertical property, and check Shrink Center so the containercenters inside the HBoxContainer.

Design the GUI — Godot Engine (3.0) documentation in English (27)

Now both counters have a decent size

Tip

Change the Min Size property of the Counters containerto control the height of the counters’ background.

We have one small issue left with the EP label on the EnergyBar: the 2bars should align vertically. Click the icon next to the EnergyBarnode to open its scene. Select the Count node and scroll down to theCustom Constant section. Add a Margin Left of 20. Inthe Rect section set the node’s Min Size back to 100, the samevalue as on the LifeBar. The Count should now have some margin onthe left. If you save and go back to the GUI scene, it will be alignedvertically with the LifeBar.

Design the GUI — Godot Engine (3.0) documentation in English (28)

The 2 bars align perfectly

Note

We could have setup the EnergyBar this way a few momentsago. But this shows you that you can go back to any scene anytime, tweakit, 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’smockup scene.

Head to the FileSystem dock and open LevelMockup.tscn.

Drag-and-drop the GUI.tscn scene right below the bg node andabove the Characters. The GUI will scale to fit the entire viewport.Head to the Layout menu and select the Center Top option so it anchorsto the top edge of the game window. Then resize the GUI to make it assmall as possible vertically. Now you can see how the interface looks inthe context of the game.

Congratulations for getting to the end of this long tutorial. You canfind final project here.

Design the GUI — Godot Engine (3.0) documentation in English (29)

The final result

Note

A final note about Responsive Design. If you resize theGUI, 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. Ingames, we don’t need the interface to be as flexible as that of awebsite. You almost never want to support both landscape and portraitscreen 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 oneanother. That’s why it’s enough for the GUI elements to only movehorizontally when we change the window size.

Design the GUI — Godot Engine (3.0) documentation in English (2024)
Top Articles
Latest Posts
Article information

Author: Tish Haag

Last Updated:

Views: 5938

Rating: 4.7 / 5 (67 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Tish Haag

Birthday: 1999-11-18

Address: 30256 Tara Expressway, Kutchburgh, VT 92892-0078

Phone: +4215847628708

Job: Internal Consulting Engineer

Hobby: Roller skating, Roller skating, Kayaking, Flying, Graffiti, Ghost hunting, scrapbook

Introduction: My name is Tish Haag, I am a excited, delightful, curious, beautiful, agreeable, enchanting, fancy person who loves writing and wants to share my knowledge and understanding with you.