Layers are a very common object in FlatRedBall, especially when dealing with UI and HUD. If you’re not familiar with these terms we’ll define them first, because we will use them in the rest of the tutorial:
- UI – this stands for “user interface”. In FlatRedBall we generally use UI to refer to buttons, windows, text boxes, sliders, list boxes, and any other kind of common UI element which the user interacts with.
- HUD – this stands for “heads-up display”. In FlatRedBall we generally use HUD to refer to any type of information display that the user will see when playing a game. This is usually not interactive (such as a health bar). The following image shows health percentages in the game Smash Bros. Melee
When creating a UI or HUD system, Layers provide two main pieces of functionality:
- Sorting above other objects in view regardless of distance from the Camera
- Simplified coordinate system – specifically one matching pixel coordinates
This tutorial covers how to use Layers in combination with an Entity we’ll create called ScoreDisplay which can be used to display the player’s score.
The ScoreDisplay Entity
Creating the Entity
The first step is to create a ScoreDisplay Entity. You will probably find most of the following steps familiar if you’ve worked through the previous tutorials; however, we will highlight the differences necessary to make the Entity use pixel coordinates:
- Right-click on the “Entities” item in the tree view in Glue.
- Select “Add Entity”
- Enter the name “ScoreDisplay”
Creating the Scene File
To add a Scene file to your Entity:
- Right-click on the “Files” item under the “ScoreDisplay” Entity.
- Select “Add File”->”New File”
- Select “Scene (.scnx)” and enter the name “SceneFile” for your Scene’s new name.
- Double-click the newly-created Scene file to open it in the SpriteEditor
At this point the SpriteEditor should open.
This Entity will simply display the player’s Score, so we’ll create a single Text object. In more complicated situations you may want to make multiple Text objects, or perhaps use Sprites or SpriteFrames to place the score Text object on, but for the sake of simplicity we’ll use one Text object in this tutorial.
Before adding to the Scene, we’ll want to make the SpriteEditor use pixel coordinates. To do this:
- Find the Camera property window and press Actions
- Press the Set Pixel Perfect button
If you can’t find the Camera properties window, in the SpriteEditor, select “Window”->”Camera Properties”
Once in pixel perfect mode, the next step is to add the Text to your Scene:
- Select “Add”->”Text”
- You should see a Text that says “Text” in the center of your Screen
Whenever Text is added to the SpriteEditor, it is automatically sized to be “pixel perfect”. Therefore, the location/zoom of your Camera matters when you create Text objects. For more information, see the SpriteEditor Tutorials. Once the Text object has been added, you can save the Scene and exit the SpriteEditor.
Adding a Text Object to your Entity
Now that we have a Scene file with a Text object in it, we can create an Object for the Text in our Entity. This is done the same was as adding other types of objects to your Entity:
- Right-click on your ScoreDisplay’s Objects tree item and select “Add Object”
- Name the new object “TextObject”
- Set the “SourceFile” to be “Content/Entities/ScoreDisplay/SceneFile.scnx”
- Set the “SourceName” to be “Text (Text)”. If you changed the name of your Text object, then the changed name will appear in the drop-down.
Tunneling in to the Text’s object
For convenience you will want to tunnel in to the Text’s DisplayText property so that programmers can easily set this value. To do this:
- Right-click on the Variables tree item under your “ScoreDisplay” Entity.
- Select “Add Variable”
- Select the “Tunneling” tab
- For “Object:”, select “TextObject”
- For “Variable:”, select DisplayText. DisplayText is the variable that controls what the Text actually displays.
- Press OK
You should probably set a default value for the DisplayText. To do this:
- Expand the Variables item under ScoreDisplay
- Select “TextObjectDisplayText (string)”
- Enter “SCORE” as the DefaultValue for this variable.
Entering “SCORE” (or any other value) is very important. Otherwise, the default value will be blank, and the ScoreDisplay object will not be visible.
Adding the ScoreDisplay to your Screen
At this point the ScoreDisplay item is ready to use. Now we need to add it to our GameScreen to have it work. To do this:
- Expand your GameScreen item
- Right-click on the Objects item
- Select “Add Object”
- Name the object “ScoreDisplayInstance”
- Select “Entity” for the SourceType
- Select “Entities\ScoreDisplay” for the SourceClassType
At this point if you run the game your ScoreDisplayInstance should be visible, but you may find something surprising:
The ScoreDisplay is really big! But why is that the case? We didn’t make it that big in the SpriteEditor. The reason is because we created our Entity to be drawn in 2D. That’s why we clicked the Use Pixel Coordinates in the SpriteEditor. However, currently our Camera is in 3D, and in 3D, one unit takes up significantly more than one pixel…at least by default.
This is where Layers come in. Layers will allow us to have some Entities drawn in 3D (like our Character), while others are drawn in 2D (like our ScoreDisplay). So let’s get to adding a Layer!
Adding a Layer to your Screen
Layers are added just like any other Object in Glue, except they don’t have a file associated with them. So, to add a Layer to your Screen:
- Right-click on your Screen’s Objects item
- Select “Add Object”
- Name the Layer “HudLayer2D”. The convention for adding Layers is to append “2D” at the end of their name if they are 2D.
- Press OK
- Set “FlatRedBall Type” as the “Source Type”
- Set “Layer” as the “Source Class Type”
If you de-select your newly-created Layer Object, you will see that it is drawn in a greenish color to represent that it is a Layer.
Finally we need to do two things: Make HudLayer2D actually be 2D, and add the ScoreDisplayInstance to the HudLayer2D Layer. To do this:
- Select HudLayer2D
- Set the “Is2D” property to true
- Select the ScoreDisplayInstance
- Set its “LayerOn” to “HudLayer2D”
Try running the game now and the Text should be regular, but it will probably be overlapping the Character Entity we made last time. Let’s solve that by moving the Entity in our Screen. To do that:
- Expand the ScoreDisplay Entity
- Right-click on the Variables item
- Select “Add Variable”
- Expose X
- Repeat the steps to Expose Y
Now we can position the ScoreDisplayInstance:
- Select the ScoreDisplayInstance in your GameScreen
- Set X to -380
- Set Y to 180
Now if you run your game your Score should be in the right spot
Hey, my text is ugly? We’ve noticed that on some graphics cards pixel-perfect stuff doesn’t quite draw correctly. This seems to be a floating-point issue when Text objects sit right on the pixel. To fix this, try setting your X to a very small number over the exact pixel value, such as -380.01. You may also need to do the same for Y.
A final note about attaching to the Camera
At this point the position of the ScoreDisplayInstance may appear correct; however, if the Camera were to be moved or rotated, the position of the ScoreDisplayInstance would change. It’s usually the case that HUD and UI should be in the same location on screen regardless of Camera behavior. Fortunately, this can be easily accomplished simply by setting the “AttachToCamera” property to true on the ScoreDisplayInstance
Now your ScoreDisplayInstance will be attached to the Camera and will remain in the same place regardless of Camera movement and rotation.