In-world hologram UI - Showing a tooltip in game (Part 1)

ui tutorials

12/17/2024

Kaloyan Geshev

In this tutorial series, we’ll build a game featuring in-world UI elements similar to the one used in Dead Space. To provide a comprehensive guide and a fully functional game, the tutorial is split into multiple parts.

You can find the complete Hologram UI series here.

Showcase Overview

To give you a better idea of what we’ll create, let’s briefly review the game and its UI features:

  1. The main player will use the Third Person Character from Unreal Engine.
  2. A trigger box will display a tooltip when the player enters, instructing them on which key to press to open an inventory menu. The inventory will appear directly in the game world.
  3. A message screen above the trigger box will be visible for the player notifying that inventory access is available when they approach the area.
  4. A 3D inventory UI will pop up when the player presses P while inside the trigger box.

Getting started

In the first part of the series, we’ll cover points 1 and 2:

  • Adding the Third Person Character to the project.
  • Creating a trigger box that displays a tooltip when activated.

Setting up Gameface and game level in Unreal

To get started, we need to integrate Gameface with Unreal Engine. Follow the steps in our official documentation . You can add Gameface to an existing project or create a new one.

For this tutorial, we’ll use the sample project from the Gameface plugin and create a new level named HologramUI.

Adding third person to our project

To include the Third Person Character in your project:

  1. Open the Content Browser.
  2. Click the Add button and select Add Feature or Content Pack.
  3. Choose Third Person from the list.
  4. Click Add to Project.

Once added, you’ll see a new folder for the Third Person Character in your project structure.

Creating a HUD class

Next, we will create a HUD class to set up a new Gameface view for displaying tooltips.

To do that we will create a new hud blueprint class.

  1. Navigate to the Content/MapAssets folder in the Content Browser.
  2. Click the Add button and select Blueprint Class.
  3. Search for Gameface GameHud or CohtmlGameHUD, and select it.
  4. Name the class CoherentSampleHologramBP.

Setting up a Gameface view

Once the HUD class is created, configure it in the Event Graph of CoherentSampleHologramBP.

  • Ensure Receive Input is unchecked, as the HUD view will only display tooltips without user interaction.
  • Add a Setup Input function to spawn the CohtmlInputActor when the game starts, enabling input control for other in-world UI elements. This will be used in later parts of the series.

The Setup Input function will have the following implementaion in the blueprint:

Next, create an HTML page for the HUD in the Content/uiresources/HologramUI folder. Name the file hud.html. We’ll modify it in later steps.

Setting a game mode override

Before implementing the tooltip UI, we will set up a Game Mode Override.

  1. Create a new blueprint class in the Content/MapAssets/HologramUI folder, similar to the HUD class.

  1. Assign the following values:

    • HUD Class: CoherentSampleHologramBP
    • Default Pawn Class: BP_ThirdPersonCharacter
  2. Save the settings and select the new Game Mode Override in the World Settings.

Implementing the tooltip UI

The tooltip UI will be implemented in the file located at Content/uiresources/HologramUI/hud.html.

To start, create HTML elements for the tooltip with a wrapper that includes data-binding attributes. These attributes will allow the tooltip’s position to dynamically adjust based on changes in the game’s data model. Later, an actor will be positioned in the game editor to serve as an anchor for the tooltip. This ensures that the tooltip maintains its position relative to the player’s camera. For now, we’ll focus on setting up the data binding and including the cohtml.js library.

Later, in the game, we’ll also create a model called tipState to manage the tooltip’s visibility and position.

Content/uiresources/HologramUI/hud.html
1
<div
2
class="tip"
3
data-bind-if="{{tipState.visible}}"
4
data-bind-style-left="{{tipState.x}}"
5
data-bind-style-top="{{tipState.y}}"
6
>
7
<div class="overlay">
8
<div class="overlay-lines"></div>
9
</div>
10
<div class="tip-key">
11
<div class="key">P</div>
12
</div>
13
<div class="tip-message">Open inventory</div>
14
</div>
15
<script src="../javascript/cohtml.js"></script>

Here’s how the attributes are used:

  • data-bind-if: Displays the tooltip only when necessary.
  • data-bind-style-left and data-bind-style-top: Dynamically adjust the tooltip’s position based on the player’s camera.

Additionally, the overlay-lines element simulates a noise effect. This animation is created using a similar technique to the one described in the Tetris UI in World tutorial.

Next, create a new CSS file, hud-styles.css, in the Content/uiresources/HologramUI directory. This file will define the tooltip’s appearance and animations.

Content/uiresources/HologramUI/hud-styles.css
1
html,
2
body {
3
perspective: 1000px;
4
margin: 0;
68 collapsed lines
5
width: 100vw;
6
height: 100vh;
7
}
8
9
.overlay,
10
.overlay-lines {
11
position: absolute;
12
width: 100%;
13
height: 100%;
14
top: 0;
15
left: 0;
16
right: 0;
17
bottom: 0;
18
z-index: 999;
19
}
20
21
.overlay-lines {
22
background-image: linear-gradient(rgba(0, 200, 228, 0.1) 0%, rgba(0, 200, 228, 0.1) 30%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%);
23
background-size: 100% 0.5rem;
24
animation: overlay-anim 3s forwards linear infinite;
25
}
26
27
@keyframes overlay-anim {
28
from {
29
background-position: 0% 0%;
30
}
31
32
to {
33
background-position: 0% -10%;
34
}
35
}
36
37
.tip {
38
width: 10rem;
39
height: 3.2rem;
40
position: absolute;
41
display: flex;
42
flex-direction: row;
43
align-items: center;
44
justify-content: center;
45
font-weight: bold;
46
color: rgba(0, 201, 228, 1);
47
}
48
49
.tip-key {
50
position: relative;
51
width: 3.2rem;
52
height: 3.2rem;
53
border-radius: 5rem;
54
background-color: rgba(0, 201, 228, 0.5);
55
border: 0.2rem solid rgba(0, 201, 228, 0.5);
56
}
57
58
.key {
59
width: 100%;
60
height: 100%;
61
font-size: 2rem;
62
display: flex;
63
flex-direction: row;
64
align-items: center;
65
align-content: center;
66
justify-content: center;
67
}
68
69
.tip-message {
70
font-size: 1.2rem;
71
margin-left: 0.4rem;
72
}

Finally, link the newly created stylesheet in the hud.html file:

Content/uiresources/HologramUI/hud.html
1
<head>
6 collapsed lines
2
<meta charset="UTF-8">
3
<meta
4
name="viewport"
5
content="width=device-width, initial-scale=1.0"
6
>
7
<title>Document</title>
8
<link rel="stylesheet" href="hud-styles.css">
9
</head>
10
11
<body>
16 collapsed lines
12
<div
13
class="tip"
14
data-bind-if="{{tipState.visible}}"
15
data-bind-style-left="{{tipState.x}}"
16
data-bind-style-top="{{tipState.y}}"
17
>
18
<div class="overlay">
19
<div class="overlay-lines"></div>
20
</div>
21
<div class="tip-key">
22
<div class="key">P</div>
23
</div>
24
<div class="tip-message">Open inventory</div>
25
</div>
26
<script src="../javascript/cohtml.js"></script>
27
</body>

The noise effect is achieved using the background-image property with a linear gradient that continuously scrolls upward. This creates the noise effect, adding a polished touch to the tooltip UI.

Preparing the tooltip state in the game

With the tooltip UI already created, it’s time to set up the game logic and models needed to display it on the screen.

We will start by creating a new structure under Content/MapAssets/HologramUI to represent the tooltip state required for its model tipState, used in the UI. Name this structure TipState.

The structure will include the following properties:

  1. x (Float): The tooltip’s X-axis position, calculated in the 2D space of the game screen.
  2. y (Float): The tooltip’s Y-axis position, calculated in the 2D space of the game screen.
  3. visible (Boolean): Determines whether the tooltip is visible.

Adding a trigger box

To control the visibility of the tooltip, we need to add a trigger box to the map. When the player enters the trigger box area, the tooltip will be displayed.

We’ll show you how to display the tooltip in the next tutorial. For now we’ll continue with creating the rest of the scene.

Creating an actor for the tooltip

To align the tooltip’s position in the game with its coordinates in the UI, we will need to create a static actor in the level. This actor will serve as a reference for calculating the tooltip’s UI position.

The steps to create the actor are the following:

  1. Add a new actor to the level and name it Tip.
  2. Position the actor at the center of the trigger box.
  3. Assign a tag (e.g., tip) to the actor in the Details Panel so that we are able to easily identify our actor later.

Create variables for the tip state and gameface hud

With the stage setup complete, we can now proceed to the game logic.

Start by creating a new function in the Level Blueprint called Init Variables. This function will initialize all the variables required for the Level Blueprint.

For now, we’ll focus on initializing the Gameface HUD and Tip variables - The Tip variable should reference the static actor created earlier with the tip tag.

Create data model for the tip

Once the Init Variables function is ready, we can proceed with configuring the game model for the UI.

In the Level Blueprint, on Event BeginPlay:

  1. Call Init Variables to initialize all required variables.
  2. Set up the Tip State model when Gameface bindings are ready.

Additionally, perform the following steps during this stage:

  1. Initialize the Input Actor - Create a variable for the Input Actor that Gameface spawns at the start of the game. This actor will be used later to focus different UI views. It’s best to set it up now, as it is spawned once the Gameface bindings are ready.
  2. Add a Boolean for the Bindings - Create a boolean variable named Are Bindings Ready. This will be used as a conditional check to ensure the UI models can be updated from the game. Without this check, attempts to update the models before the bindings are ready will fail.

Next, use Create Data Model From Struct followed by Synchronize Models to create the tipState model from the Tip State structure. This structure was defined earlier and is used in the hud.html page.

Updating the tip state method

To manage updates to the tip state, create a dedicated function in the Level Blueprint called Update Tip State.

  1. Function Inputs - Add three inputs: x, y, and visible. Their data types should match the corresponding fields in the Tip State structure.
  2. Update the Structure Members - Modify the fields of the Tip State structure with the values passed into the function.
  3. Synchronize the Data Model - Update the data model linked to the Tip State structure, identified by the name tipState. Call Synchronize Models to ensure the UI is updated correctly, displaying the tooltip with the new values.

By following these steps, the tooltip will dynamically reflect changes in the UI.

Update the tip visible state method

To simplify the process, we will create a dedicated method to update only the visibility state of the tooltip. This method will be similar to the one that updates the entire state but focuses solely on visibility.

Toggling tooltip visibility

Next, we’ll modify the tooltip’s visibility so that it appears when the player enters the trigger area of the trigger box and disappears when they leave.

To achieve this, we’ll use the On Actor Begin Overlap (TriggerBox) and On Actor End Overlap (TriggerBox) events, which can be accessed in the Level Blueprint:

  1. Right-click in the Level Blueprint editor.
  2. Navigate to Add Event for Trigger Box 0 > Collision.

Once the events are set up, call the Update Tip Visible State method to toggle the tooltip’s visibility in the UI. This ensures the tooltip becomes visible when the player enters the trigger box and hides when the player exits.

Additionally, include a check to confirm that the bindings are ready. This prevents errors if the player interacts with the trigger box before the bindings are initialized.

Updating the position of the tooltip

The final step is to dynamically update the tooltip’s position as the player moves within the trigger area of the box.

To achieve this, perform the following actions on each tick:

  1. Ensure the bindings are ready to prevent errors.
  2. Translate the Tip actor’s 3D coordinates to 2D based on the player’s screen viewport.
  3. Update the tooltip’s position in the UI model so it moves in sync with the Tip actor’s location in the game.

For converting the Tip actor’s position from 3D to 2D:

  1. Retrieve the actor’s location in the game world.
  2. Project its position onto the screen coordinates using the relevant Unreal Engine functions.

Result

Once we’ve completed all the steps, the tooltip will behave in the following way:

  • It appears when the player enters the trigger area.
  • It updates its position dynamically based on the player’s movement.
  • It disappears when the player exits the trigger area.

Here’s an example of the final result:

What is next?

In the next tutorial, we’ll learn how to create an in-world visual indicator above the trigger box, showing the player that they can access their inventory by pressing the P key. Check it out here: Hologram UI Tutorial - Part 2.

On this page