The text box and text display

Visual novels are heavy on text, so the starting point will be designing the dialogue box.

We will make it display the character’s name, the text body, and make it interactive: we will be able to press enter to display all the text and press enter again to go to the next reply.

Designing the text box

Open the start project if you haven’t already and create a new scene with a TextureRect named TextBox as its root node.

We will assign the background texture to that node as, being the root note, it will display behind its children.

You can find all the text box’s sprites in the TextBox/ directory of the project. You want to assign the text-box.png file to the node’s texture property.

We want to anchor the background at the bottom of the screen, so apply the Layout -> Bottom Wide option.

Add a new TextureRect for the character name’s background and name it NameBackground. You’ll want to assign the character-name-box.png texture to it.

We want this sprite to sit along the top edge of our box’s background, so we’ll leave the default top-left anchor. We can then hold the Shift key down and repeatedly press the right and up arrow keys to nudge the sprite. Holding Shift moves the node by 10 pixel increments instead of 1.

At this point, your scene should look like this.

We can now add the text. Add a new label node as a child of the NameBackground and name it NameLabel.

We want to give it some placeholder text to preview the character’s name.

To keep the text centered in the sprite, I invite you to use the Layout -> Center Option and resize the label’s bounding box to cover its parent. We don’t use Layout -> Full Rect here because the sprite has some drop shadow baked in, and the bounding box would get a bit too large vertically.

Then, with the NameLabel node selected, set its Align and Valign properties to Center.

The text looks ugly right now. We will add a more readable font after we finished setting up the scene.

We are missing the text body and the arrow that indicates we can move forward in the conversation.

Select the root text box node and add a RichTextLabel node as a child of it. You can write some placeholder text in its Text property to see where the characters appear.

In the Inspector, we want to configure it to be suited to the game we’re making. Turn of the Meta Underlined and Scroll Active properties to not highlight URLs and hide the scrollbar.

To add support for bold, italics, and more, turn on BBCode -> Enabled. This property allows us to format the text by adding good old BBCode, which maybe shows Godot’s age a bit!

Note you’ll have to copy your placeholder text into the BBCode -> Text field for it to appear.

You can use the Layout -> Center option to center the RichTextLabel in the text box and resize it to leave large horizontal margins around the text. You don’t want the text to span the player’s whole display because it makes it hard for them to read if they play on a large screen, like 25 inches or more.

The last element to add is the blinking arrow. We will make it a control node with a TextureRect child to make it easy to animate it. We will make it bounce using animation to attract the player’s eye to it.

To add a Control node named BlinkingArrow as a child of the RichTextLabel. As a child of it, add a TextureRect and assign the arrow.png texture to it.

Select the TextureRect node, and to make the arrow resizable, turn on Expand and set its Stretch Mode to Keep Aspect. That way, you can click and drag on the texture’s size handle to scale it down.

Let’s anchor it in the bottom-right of the RichTextLabel. To do so, select the BlinkingArrow and apply Layout -> Bottom Right.

We will save the blinking arrow to a dedicated scene so we can animate it later. Right-click on the node and select Save Branch As Scene.

Your scene should look like this.

Adding a theme and a default font to the game

I included the Montserrat extrabold font in the Theme/ directory.

We will use it to define our project’s default font and replace the full text we have in our scene.

To do so, we will create a theme resource. If you are new to themes, check out the theme intro lesson we included in the simulation game UI series.

In short, a theme allows you to override many properties of your control nodes in Godot, including setting text fonts, changing their background color and style, and more. The main advantage of themes is that you can assign the resource to the topmost control node in some user interface, and the styles will cascade down to every child.

In the FileSystem dock, right-click on the theme folder and select New Resource. Create a new DynamicFont and name it montserrat_extrabold.tres.

Double-click on the newly created file to open it in the Inspector.

When creating a font resource, you have to assign a font file in either the TTF or the OTF format for the text to render. You can do so by setting the Font -> Font Data. Assign the Montserrat-ExtraBold.ttf file to it.

Then, you can set the Settings -> Size to a large value. I went with 44.

To make the font extra readable, I also decided to use an outline size of 4 pixels with a transparent outline color, a deep blue with a low alpha value. This makes the text pop a tiny bit over the text box without being too visible.

You can also turn on the Use Filter setting to soften the text’s edges.

We can now create the theme resource itself. In the FileSystem, right-click on the theme folder again and select New Resource. This time, create a Theme and save it as theme.tres.

The file should open in the Inspector and you should see the theme preview in the bottom panel. In the Inspector, you can see it has an empty Default Font. Drag-and-drop the montserrat_extrabold.tres resource on the field to set the default font.

You should see the theme preview update.

Now, back to our scene, select the TextBox root node and set its Theme -> Theme property to our new resource. If the RichTextLabel looks off, toggle its visibility or tweak its Text to update its drawing.

The text should now look a lot better.

Animating the text box

We’ll design some animations we can play on the text box scene. To do so, we add an AnimationPlayer as a child of the TextBox node.

We will create three animations: one to fade in, one to fade out, and a setup animation whose role is to reset the scene’s visibility.

Create a new fade_in animation that will animate the TextBox node, the NameBackground, and the RichTextLabel. We will animate their Modulate color from a transparent white to an opaque one.

Here is a screenshot of my animation timeline. As in the rest of Godot 2D secrets, I assume you are comfortable creating keyframes and will explain the animation in general. If you want to see and play with the result, You can find it in the TextBox scene in the final demo.

We first make the TextBox node fade in. To do so, we create keyframes on its Self Modulate property. Using the Modulate property instead would affect all its children, and we don’t want that: we want only to animate the TextBox.

You can also see that I created a keyframe for its Visible property to ensure that the node is visible when we play this animation. While prototyping, it’s a property I was changing from code as I was building the system. Creating a defensive keyframe like that ensures that the node is visible when playing the animation and is something I often do.

The RichTextLabel fades in with a delay of several frames. The total animation length is 0.5 seconds, so there’s little room for large delays. The idea is to make the text box appear in a more appealing way than toggling its visibility, but to do this quickly so it doesn’t slow down the player and the story.

The NameBackground appears last, and using its Modulate property, the NameLabel fades in with it. I also animated its Margin Left and Margin Right to make it move in from the left a bit, giving the animation a little extra motion.

You could key the node’s Rect Position instead, but I got into the habit of using margins for UI nodes because keying their position does not always work in Godot 3.2. As control nodes depend on their parent’s position and can sometimes be controlled by containers, animating them can be a little inconvenient compared to 2D nodes.

Let us now look at the fade_out animation.

It is similar to the fade-in but without any margin animation and reversed. The NameBackground disappears first, followed by the RichTextLabel, and finally the TextBox.

I tried to animate the NameBackground’s position, but I felt it didn’t look as good when fading out. This way, the animations are also more varied.

Note that this animation is several frames shorter than the fade-in, with a total duration of 0.43 seconds.

Finally, the setup animation has a duration of 0 seconds and has one key on each of the channels affected by the fade_in animation. It resets the Modulate properties to an opaque white, as well as the NameBackground node’s margins.

Whenever we want to tweak our scene’s design, we can select the setup animation to reset every node’s position and look to its default.

If you decide to update the nodes’ position, as animations in Godot directly change the nodes’ properties, you may also have to update the keys in your setup animation.

I invite you to take the time and create those animations, and with that, our TextBox scene is ready to get some code.

In the next lesson, we will start coding the text box to display text progressively and make it interactive.