What You’ll Learn in This Hour:
    Displaying text inside the game window
    Important Control nodes properties and signals
    Using Containers to help create an interface
    Using GDScript to make an interactive interface
    Applying a Theme to your controls
    As a game developer, communicating with players is almost unavoidable, whether you need to tell the players how many lives they have
    currently, how many items they possess, what have storytellers been saying to them, where they are, where should they go next, and so on. The
    same could be said for players. They need to tell the game what weapon they would like to use, which difficulty level they prefer, etc. This
    communication happens as soon as the game is launched and is done through the user interface.
    In this hour, you’ll learn how to use nodes designed specifically for user interface, Control. We will start with one of the most basic Control
    nodes, Label, by using it to display text on screen. Then, we get to know some useful properties of Control nodes. We’ll also introduce you to
    Control nodes that are frequently used. Next, you’ll learn about Container nodes and experiment with building a complex interface with them.
    You’ll also learn how to make great interfaces using Theme. If you can’t find a specific Control ready to be used right out-of-the-box, you can
    make your own basic Control.
    Control
    Control is a node inherited from CanvasItem, which means that it can be drawn in 2D. You might remember another class that also inherits
    from CanvasItem: Node2D. The main difference between these two is Control has a rectangular boundary (rect) that contains and sometimes
    crops its content, while Node2D has no such boundary. This is one of the most common concepts that confuses starters because these
    differences might not be obvious. Control sizing is relative to the parent’s boundary, similar to Node2D, which inherits the parent’s transform.
    Basic Control Nodes: Label and ColorRect
    Let’s begin by creating a Label. It’s a simple Control that displays text inside a game window. Creating a Label is done the same way you
    create other nodes. Label directly inherits from Control (see Figure 9.1
    )
    .
    FIGURE 9.1
    A newly created Label node.
    When you’re done adding the Label, give it some text so that you can visualize it better. This can be done in the Inspector (see Figure 9-2).
    FIGURE 9.2
    Editing text property of a label using the Inspector.
    If you want to add text that spans multiple lines, click the paragraph button next to the text box. A dialog with a larger text area will appear
    (Figure 9.3).
    FIGURE 9.3
    A label with text.
    When a Control is selected, it is highlighted by its boundary (see Figure 9.3). You can drag any pink dot to resize the Control. However, you
    may notice you cannot resize the Label to be smaller than the space occupied by text. This is the absolute minimum size of a Control. Controls
    will never have a smaller size than this value. Minimum size varies by Control and its content. For Labels that don’t clip text, their minimum size
    are the area where the text resides.
    Let’s add another Control node as a background of Label. Create a new ColorRect as a child of Label (see Figure 9.4). A white-colored
    rectangle should overlap where the Label is. Set its color property to be whatever you like, preferably not the same as Label’s text color
    because we are going to make it a background. Then, go to the CanvasItem section and check the show_behind_parent property, which
    does exactly what it says. Our Label should visually be on top of the ColorRect now.
    FIGURE 9.4
    Show behind parent property makes a Label visible on top of a ColorRect.
    We will make this ColorRect’s boundary match that of the Label. Select ColorRect node, go to the 2D Editor toolbar, look for “Anchor,” click it,
    and choose “Full Rect and Fit Parent” at the bottom (see Figure 9.5).
    111111111
    22222222FIGURE 9.5
    “Full Rect and Fit Parent” inside the Anchor menu.
    The ColorRect should be the Label’s background now (see Figure 9.6).
    FIGURE 9.6
    A Label with ColorRect background.
    Properties of Control
    We will use the previous Label to introduce you some of the important properties of Control. This is applicable to almost every Control node.
    To follow along, select a Label node and look at the Inspector. Scroll down a bit until the Control section is visible (see Figure 9.7).
    FIGURE 9.7
    “Control” section in the Inspector.
    We will take a look at each one in the following sections.
    Anchor and Margin
    Anchor and Margin both have four subitems: Left, Top, Right, and Bottom. They are related and affect each other. Let’s look at Margin first
    (Figure 9.8).
    FIGURE 9.8
    Effect of Margin property to a Control.
    Margin is a distance in pixels relative to the parent’s boundary. Currently, our Label has Left and Top set to zero. Try changing Left to 15 and
    Top to 30 and then look at the difference.
    You will see the position has changed according to the Margin value. F
    r
    om Figure 9.8, Label is moved 15 pixels to the right and 30 pixels
    lower. If you set Margin to be a negative value, it will move the Control the other direction.
    Anchor affects how Margin is calculated. Currently, all of our Label Anchors are set to “Begin,” which means that Margins are relative
    horizontally to the parent’s Left and vertically to the parent’s Top (see Figure 9.9).
    FIGURE 9.9
    How Margins are calculated relative to Anchor. (Right Anchor set to “Begin.”)
    Let’s try setting Right Anchor to “End.” This will make our Right Margin relative to the parent’s Right (see Figure 9.10).
    FIGURE 9.10
    How Margins are calculated relative to Anchor. (Right Anchor set to “End”) Notice an unchanged boundary and difference in Margin value.
    Anchor also dictates how the Control is resized if the parent is (see Figure 9.11) because Controls try to keep the Margin constant.
    FIGURE 9.11
    Resizing the parent. (Right Anchor set to “End”) Notice an expanded boundary and constant Margin value.
    Try experimenting with other sides too (Control’s Left, Top, and Bottom). You can also use the “Anchor” menu to set Anchors and Margins
    automatically.
    Rect
    This also contains properties related to boundary and sizing. The transformation similar to that of Node2D’s can be found here. Let’s look at
    each one:
    Position: location of the Control relative to its parent.
    Size: size of the Control’s boundary.
    Min Size: how small the Control can be resized. This has no effect if it’s smaller than the intrinsic Control minimum size. You might want
    to set this property manually to keep an interface visible and readable.
    Rotation: Control’s rotation around the pivot in degrees. Positive is clockwise.
    111111111
    22222222Scale: Control’s scale, expanding or shrinking from the pivot.
    Pivot Offset: location of the pivot relative to the upper-left corner.
    Clip Content: whether e content outside the boundary is drawn.
    Hint
    This is the text that appears when players hover their mouse cursor on it for a while. It can be used to tell additional information related to the
    Control, e.g. contents that are too long to be displayed, the purpose of the Control, etc.
    Focus
    This lets you define nearby Controls manually. Note the engine can find another Control automatically when players press tab to focus on the
    next Control. This option lets you override it in case it chooses the wrong Control node.
    Size Flags
    This contains properties related to sizing inside Containers. Flags vary by Container types. In general:
    Fill: Fills the Container along that axis.
    Expand: The Control takes all available space but won’t fill it with content. (as a spacer).
    Fill and Expand: Takes all available space and fills, it with content.
    Shrink Center: The Control keeps itself small and adjusts itself in the center.
    Shrink End: The Control keeps itself small in the right side or bottom.
    Stretch Ratio: The Control’s size is relative to that of its siblings. Imagine two Controls being siblings, one with a Stretch Ratio of “2” and
    another with “1”. The one with a Stretch Ratio “2” has the size doubled of another Control.
    Theme
    Theme is a resource that contains information related to panel drawing. It also contains predefined values for Controls, such as default margin,
    size, color, and font, etc. If a Control is not given its own Theme, it will inherit its Theme from its parent, resulting in an interface with a uniform
    look. Theme is discussed later this hour.
    Custom Values
    This lets you override values defined in Theme individually, in case the predefined ones don’t look good in a specific setting. For our Label,
    you can set a new font, font size, shadow color, shadow offsets, and so
    on. Try giving our Label a shadow by selecting a check box in front of
    the “Font Color Shadow” property.
    Signals of Control
    Like most of the objects of Godot Engine, Control also has signals you can use to execute functions. The following is a nonexhaustive list of
    signals from the base Control class only. There are more signals available in each specific Control.
    focus_entered()/focus_exited(): called when Control has or loses focus
    gui_input(InputEvent ev): called when input event happens inside Control area or while Control has focus for key input
    mouse_entered()/mouse_exited(): called when mouse cursor enters or exits the boundary
    resized(): called whenever the size is changed
    Know Your Controls
    There are many Controls bundled with the engine. In this topic, we will get to know some that are used often in game interfaces.
    Label
    Label is a Control that displays text. Usually, players cannot interact with this Control because it’s used only as a display. Here are some of its
    important properties:
    text: a displayed String.
    align and valign: text alignment in horizontal and vertical axes.
    autowrap: allows resizing, wrap lines that are longer than the width, and adjusts height automatically.
    clip_text: allow resizing, but won’t automatically adjust the height. As a result, displayed text will be truncated to the Control’s height.
    RichTextLabel
    This is a more advanced label that supports styling via BBCode. Edit the text property to use. It’s similar to normal Labels.
    Text Inputs
    Sometimes you want to get text from players. One example is letting players type their character’s name using a keyboard. Following are the
    Controls that provide a text area in which players can type.
    111111111
    22222222LineEdit
    LineEdit is a single-line text area. Here are some of its interesting properties:
    text: text inside the LineEdit that can be edited by players.
    editable: whether players are able to type in the text area.
    secret: whether to display text as asterisks. () This is useful when making a password input box.
    placeholder_text: text that is displayed when the box is empty. It can be used as a hint of what players should enter, for example,
    “Player name,” “Host IP,” etc.
    TextEdit
    TextEdit is a multiple line text area. You may use set_text(String text) or get_text() to change and retrieve text inside.
    Range
    Sometimes you also want to get numeric data from players. In games where characters have hit points, you may want to display it using a
    gauge interface so that it’s easier to understand, and it looks better than plain numbers. In games with a trading feature, you might want to
    know how many items they are going to buy or sell from merchants. This topic discusses Controls that help you get numbers from players while
    providing an easy-to-use interface. But before that, let’s look at some properties these Controls have in common.
    min_value/max_value: minimum and maximum value.
    value: the current value held by the Control. It will not be below min_value and exceed max_value.
    step: a constant number that may be added or subtracted to value.
    ProgressBar
    Also known as a “loading bar,” the ProgressBar is a horizontal control that shows progress as it’s being filled with color. Usually, players cannot
    interact with this Control.
    TextureProgress
    A more customizable variation of ProgressBar. TextureProgress lets you replace the bar with images. A circular progress bar is also
    supported.
    Slider
    Slider is a Control with a dragable button that changes the value.
    SpinBox
    This is a Control similar to what you’ve used in the Inspector. It changes the value by clicking the up and down arrows or by clicking and
    dragging the arrow up or down.
    BaseButton
    Buttons are useful when you want to know how users want to proceed, whether the form is submitted or discarded, which menu is shown, and
    so on. Since BaseButton is an abstract class that all buttons are inherited from, it is important to know some of its properties and signals.
    Some of its interesting properties are listed below:
    disabled: decides whether users can interact with this button.
    toggle_mode: decides whether the button can stay pressed.
    pressed: the current state of the button. It’s mostly useful with toggle_mode on.
    shortcut: an input event that triggers the button’s action.
    group: only one of all buttons in the same group can be selected. This is mostly useful with toggle_mode on.
    Useful signals of BaseButton are listed below:
    button_up()/button_down(): called when the button is released or pressed.
    pressed(): called when the button executes an action, which by default, is when it is unpressed. It can be configured to emit when being
    pressed by setting the action_mode property. However, the signal will be fired before the player has a chance to cancel the action.
    toggled(bool pressed): called when the button executes an action while toggle_mode is on.
    Button
    A simple button has a custom caption and an optional icon.
    TextureButton
    This is a more customizable variation of Button that uses images. You’ll need “normal,” “pressed,” “hovered,” “disabled,” and “focused”
    textures.
    CheckBox and CheckButton
    111111111
    22222222These buttons are set to toggle_mode on by default. CheckBox shows check marks inside a box when pressed. CheckButton looks like a
    switch and displays “ON” when pressed and “OFF” otherwise.
    OptionButton
    OptionButton is a dropdown menu that lets users select an item.
    ColorPickerButton
    ColorPickerButton is a button that shows a color picker when clicked. A chosen color is kept as a property. You can use this Control to easily
    create customization settings for player characters, for example. The color_changed signal is emitted when a new color is chosen.
    Popup
    Popup is a window that displays on top of other Controls. It usually tells users an action is required for another action to complete. Popups are
    hidden during runtime. To display a Popup, use any of the popup
    () methods.
    PopupPanel
    PopupPanel is one of the simpler types of Popups as it only has a panel as a background and nothing else.
    PopupMenu
    PopupMenu displays selectable items. It will emit id_pressed and index_pressed signals upon selection.
    WindowDialog
    WindowDialog is a PopupDialog with a customizable title bar. It can be set to be resizable.
    AcceptDialog
    AcceptDialog is a WindowDialog with an accept button captioned “OK” by default. Confirmed signal is called upon a button press.
    ConfirmationDialog
    ConfirmationDialog is an AcceptDialog with a cancel button.
    FileDialog
    FileDialog is a complex dialog that is used to browse for files and folders. Interesting properties are listed below:
    mode: the dialog’s access mode. The dialog configures its interface to match this setting.
    access: the file path to which the dialog has access. Note that the resource path usually isn’t accessed for writing at runtime, only
    reading.
    filters: only files with one of these extensions is displayed.
    show_hidden_files: whether hidden files and folders are displayed.
    The following lists all signals of FileDialog:
    dir_selected(String dir): called when a folder has been selected
    file_selected(String path): called when a file has been chosen
    files_selected(PoolStringArray paths): called when files are selected while the dialog is set to “Open Many” mode
    ItemList
    ItemList displays items, which can be text or icon, in a nice-looking table. One example is the lower part of the editor’s FileSystem dock. Items
    are interacted with and signals are emitted accordingly.
    TextureRect
    A TextureRect displays an image constrained by its boundary. Image can be set to tiling mode, scaling to fit or fill the area, or fixed in the
    center using the stretch_mode property.
    ColorRect
    This is a simple Control that displays nothing but color inside the boundary. Use the color property to set the color.
    NinePatchRect
    This is an image-displaying Control with unique scaling. The image used should have “corners,” “sides,” and “center.” The Corners size is
    constant. Sides are expanded or tiled in one axis until they meet the other end. The center is expanded or tiled in both axes to fill the middle
    part. This is useful when making a panel using a custom texture.
    Containers
    The Anchor and Margin system can be a bit difficult to use and it takes time to achieve the desired outcome, especially when dealing with
    111111111
    22222222multiple Controls in the same level. Containers are designed for this situation. They are used as a parent for Controls that are in the same level,
    because they automatically adjust their child nodes. Note some Container types squeeze the children into their minimum size unless they are
    set with the appropriate size flags or given a custom minimum size.
    BoxContainer
    BoxContainer is useful when you want a child Control arranged in a row or column. For HBoxContainer, the first child Control will appear on the
    left and subsequent children will go to its right in order. It’s the same thing with VBoxContainer, but working from top to bottom.
    SplitContainer
    SplitContainer contains two children separated by a drag-able bar that resizes both children.
    MarginContainer
    This is a simple Container that gives its child a custom margin. Note these margin values are located in the “Custom Constants,” not “Margin.”
    ScrollContainer
    This Container type automatically shows scroll bars when its child is larger than itself.
    TabContainer
    TabContainer, despite acting similar to other Containers, is not listed as a Container type. It puts its children in a tabbed interface, shows the
    one selected, and hides the others. Note its children can be of any CanvasItem type and are not limited to “Tabs” as most starters mistakenly
    assume from the name.
    Making an Interface
    Let’s make an interactive interface using some of the Controls from previous topics. We will create an AcceptDialog that displays what we’ve
    typed in a LineEdit. Because there is a Popup in the interface, we will set the root node as a generic Control node to keep the Scene Tree
    structure in order. Let’s begin by adding nodes to the Scene Tree as follows in Figure 9.12.
    FIGURE 9.12
    A simple interface.
    The interface preview in the 2D editor looks a bit messy (Figure 9.13).
    D
    on’t worry about it. It can be fixed easily as long as the tree is in order.
    FIGURE 9.13
    An unfinished interface.
    As you’ve learned from previous topics, Control size is relative to the parent’s boundary. To make use of all available space easily, we will set
    the root Control to fill the whole screen using “Full Rect and Fit Parent” in the Anchor menu (see Figure 9.14).
    FIGURE 9.14
    An unfinished interface.
    The changes aren’t visible because the child nodes with contents aren’t affected. Select the HBoxContainer node and do the same (see
    Figure 9.15).
    FIGURE 9.15
    An unfinished interface.
    The LineEdit and Button appear in a vertical shape because of the size flags. Select both Controls and change the vertical size flag to none.
    Then select the LineEdit node and set the horizontal size flag to fill and expand (see Figure 9.16).
    FIGURE 9.16
    An unfinished interface.
    The interface now looks a little more like what we want. Add a placeholder and a caption for both Controls (Figure 9.17).
    FIGURE 9.17
    A simple interface.
    111111111
    22222222All that is left is coding the logic. You can attach a script to any node as long as the node paths are correct. This example in Listing 9.1 uses the
    root node as a script Container. Create and attach a new GDScript to the root node.
    LISTING9.1 Script for the Root Control Node
    Click here to view code image
    extends Control
    func _ready():
    $HBoxContainer/Button.connect(“pressed”, self, “button_pressed”)
    $HBoxContainer/LineEdit.connect(“text_entered”, self, “show_dialog”)
    func show_dialog(name):
    if name == “”: name = “anonymous”
    $AcceptDialog.dialog_text = “You are %s.” % name
    $AcceptDialog.popup()
    func button_pressed():
    show_dialog($HBoxContainer/LineEdit.text)
    We can’t connect both signals to the same function, because they have a different number of parameters. Now save the scene and run it. Type
    some text, then press the button or enter key (see Figure 9.18).
    FIGURE 9.18
    AcceptDialog shows the text inside LineEdit.
    The interface should now work as expected. Also, thanks to the HBoxContainer, the scene should be responsive to window resizing.
    Theme
    It is understandable to want to give your game a unique look and feel. The default user interface theme might not match your game aesthetic.
    Godot Engine provides an easy way to customize the look while keeping it consistent throughout the components. To create a new Theme, go
    to the Inspector and click the “Create new Resource” button. Find “Theme” resource in the list, choose it, and click “Create.” The bottom panel
    will have a “Theme” option available (see Figure 9.19).
    FIGURE 9.19
    Theme configuration panel.
    To add a new entry to the Theme, click the upper-left menu button that says “Theme,” and choose “Add Item” as shown in Figure 9.20.
    FIGURE 9.20
    Theme configuration menu.
    A dialog will appear. Click the “..” button to show the list of available items or manually type an option in the box (Figure 9.21).
    FIGURE 9.21
    Add Theme Item dialog.
    You can find the names and the data type of a Control in the documentation of that Control in the GUI Theme Items section (see Figure 9.22).
    FIGURE 9.22
    GUI Theme Item section inGodot Engine documentation.
    Click “Add” to add it to the Theme resource (see Figure 9.23).
    FIGURE 9.23
    New Theme Item and preview.
    The preview will show how it looks, as shown in Figure 9.24.
    FIGURE 9.24
    The preview.
    111111111
    22222222StyleBox
    StyleBox is also a resource and dictates how panels, boxes, and the like are drawn. There are three types of StyleBox:
    StyleBoxEmpty: draws nothing
    StyleBoxFlat: draws a single color
    StyleBoxTexture: draws an image similar to a NinePatchRect
    We’ll try adding a new StyleBox to a Normal button. Choose “Theme,” then “Add Item.” Pick “Type: Button,” “Name: normal,” “Data Type: Style,”
    then click Add. Click on the new Item, “” and choose “New StyleBoxTexture.” Click on it again to configure it. Try adding a default Robot
    icon as Texture, set all margins to “4,” and set modulate color to R:30, G:30, B:30, and A:255 to darken it (see Figure 9.25).
    FIGURE 9.25
    A configured StyleBoxTexture.
    Go back to the Theme resource by clicking “<” icon in the Inspector. The buttons are replaced by the Robot icon. Note that this only affects the
    “normal” state of buttons (see Figure 9.26).
    FIGURE 9.26
    Button with custom StyleBoxTexture.
    Save the Theme using the “Save Resource” button and then apply it with the root Control of the scene from the previous topic (Figure 9.27).
    FIGURE 9.27
    Button with custom StyleBoxTexture.
    You may notice the button’s appearance changed despite the Theme being put in the root Control and not the button node. This is because
    child Controls inherit their parent’s Theme if they aren’t given one.
    Try using StyleBoxEmpty and StyleBoxFlat with other types of Control.
    Custom Control
    Controls bundled with the engine should fulfill most use cases. But what if you can’t find what you want? In this final topic of this hour, we will
    learn how to make a control that doesn’t come with the engine. We’ll make a ColorRect that changes color according to the cursor position
    inside it.
    The first thing to consider is, “Is there any similar Control to inherit from?” For our example, it is ColorRect. But if there’s none, you can always
    inherit from a generic Control node. Now create a ColorRect node, set it to “Full Rect and Fit Parent,” and attach the following GDScript shown
    in Listing 9.2.
    LISTING9.2 Script for a CustomControl Inheriting fromColorRect
    Click here to view code image
    extends ColorRect
    func _gui_input(ev):
    if ev is InputEventMouse:
    var v = ev.position/rect_size
    color = Color(v.x, v.y, 1, 1)
    The _gui_input works like _input but only when the input event happens inside the boundary or the Control is focused. We use this callback to
    change the color property of the Control.
    Save the scene and give it a meaningful name. To use this custom Control, simply instance that scene. You can instance it multiple times in the
    same scene because the properties won’t interfere with one another.
    Summary
    In this hour, you learned about important Controls, their properties, and signals. You learned about Containers and how they can help build an
    interface. You’ve tried making an interface using various Controls, such as LineEdit, Button, HBoxContainer, AcceptDialog, ColorRect, etc.
    You’ve made a custom Theme and applied it with a Control. And finally, you’ve created a custom Control that makes use of the _gui_input
    callback.
    Q&A
    Q. Can I use drag-and-drop with Controls?
    A. Yes, there are methods for handling dropped data. Drag-and-drop is one of the more advanced implementations of Control. Godot Engine
    Demo repository offers a demo on this feature.
    111111111
    22222222Q. Can I create customContainers using GDScript?
    A. Yes, by inheriting Container and handling the sort_children signal.
    Q. Can I use Controls in 3D?
    A. Controls are 2D-node types. To use them in 3D, you may put them in a Viewport and display as ViewportTexture. To make them
    responsive to input events, you can raycast from the root Viewport, and then pass an input event to the UIViewport using input().
    Workshop
    Answer the following questions to make sure you understand the content of this hour.
    Quiz
    1. True or False: Controls can be rotated.
    2. If you want a Control to stick with the parent’s bottom-right corner, what are the Anchor settings.
    3. True or False: Margin values cannot be negative.
    4. True or False: You are limited with predefined names for Theme Items.
    5. True or False: Controls can be created byGDScript.
    Answers
    1. True. Controls can be rotated using rotation property or inheriting the parent’s transform.
    2. All Anchors are set to “End.”
    3. False. Negative Margin value moves the Control in the opposite direction.
    4. False. You can use any name. A custom-named Theme Item will be ignored by the engine, but you can refer to it using GDScript.
    5. True. Almost every one of Godot Engine’s objects can be created withGDScript. Because Controls are nodes, they need to be added to
    the SceneTree using add_child to be operational.
    Exercises
    Try to execute the following exercises to get more acquainted with the user interface inGodot Engine:
    1. Make a simple Music Player using AudioStreamPlayer node with “Open,” “Play/Pause,” and “Rewind” buttons.
    2. Choose any application on your machine and try to replicate its interface inside Godot Engine. You don’t have to include all of its
    functionality, but make sure the interface can handle window resizing.
    3. Customize parts of the engine using Theme. The Editor Theme can be set in Editor menu > Editor Settings > Interface > Theme >
    CustomTheme.