UMG Basics: Your First Game UI in UE5


Widget Blueprints, essential widgets, layout panels, and a step-by-step HUD build for the Third Person template


Every game needs UI — health bars, score counters, menus, HUD overlays. Unreal Engine handles all of this through Unreal Motion Graphics (UMG), a Blueprint-based framework for building in-game interfaces without touching C++. If you’ve used UE5 but never built UI, this guide walks you through everything you need: Widget Blueprints, essential widgets, layout panels, getting game data into your UI, button interactivity, and a step-by-step HUD build using the Third Person template.

Prerequisites: You’ve opened UE5, created a Third Person template project, and you’re comfortable navigating the editor and placing Blueprint nodes. No prior UI experience needed.

Unreal Scene by Sarah Page

Widget Blueprints: where all UMG UI lives


A Widget Blueprint is the asset type for every piece of UI in Unreal. Think of it as a self-contained screen — a health bar, a main menu, or an entire HUD — that you design visually and script with Blueprint logic.

To create one: in the Content Browser, right-click → User Interface → Widget Blueprint → select User Widget → name it WBP_PlayerHUD. Double-click to open the Widget Blueprint Editor.

The editor has two modes toggled in the top-right. The Designer tab is your visual workspace with the Palette (searchable widget list, top-left), the Hierarchy (parent-child tree, left), the Designer viewport (WYSIWYG canvas, center), and the Details panel (properties, right). The Graph tab is a standard Blueprint Event Graph for scripting behavior.

The Hierarchy shows how widgets are nested. Drag a Canvas Panel from the Palette into the empty Hierarchy to create a root container — everything else goes inside it as children. Widgets shown in bold have “Is Variable” enabled, making them accessible in the Graph tab.


Four essential widgets



Text displays on-screen text. Key properties under Appearance: Text (the content string — update at runtime with the Set Text node), Font (Family, Typeface, Size, Letter Spacing), Color and Opacity, Justification (Left/Center/Right), and Auto Wrap Text.

Image displays a texture, material, or Slate Brush. The property beginners miss is Draw As inside the Brush section: “Image” stretches to fit, “Box” enables 9-slice scaling (corners stay crisp while the center stretches — essential for scalable UI frames), “Border” tiles edges, and “Rounded Box” draws rounded corners procedurally. Color and Opacity acts as a tint multiplier.

Button is a container, not a standalone visual. By itself it’s just a clickable rectangle — drag a Text or Image child inside it to give it content. The Button handles visual states under Style: Normal, Hovered, Pressed, and Disabled, each with its own background. It also has Pressed Sound and Hovered Sound slots. Five events are scriptable: OnClicked, OnPressed, OnReleased, OnHovered, and OnUnhovered.

Progress Bar fills based on its Percent property (float, 0.0 to 1.0). Set it in Details under Appearance — type 0.7 for 70%. Bar Fill Type controls direction (LeftToRight, TopToBottom, FillFromCenter, etc.). Fill Color and Opacity tints the filled portion. At runtime, call Set Percent to update and Set Fill Color and Opacity to shift colors dynamically.


Canvas Panel and anchoring


Canvas Panel is the most common root. Children sit at absolute pixel positions with individual anchors and Z-Order. The anchoring system handles different screen resolutions using a 0–1 coordinate system where (0,0) is top-left and (1,1) is bottom-right.

The Anchor Medallion — the flower-shaped gizmo in the viewport — shows where a widget is anchored. Drag it to reposition. The Anchors dropdown in Details gives you presets: corner anchors, edge stretches, and full-screen stretch. Alignment (0–1 per axis) sets the pivot — (0.5, 0.5) centers the widget on its anchor.


Vertical Box, Horizontal Box, and Overlay


Vertical Box stacks children top-to-bottom. Horizontal Box stacks left-to-right. Each child’s slot has Padding (Top, Bottom, Left, Right), a Size mode (Auto — the widget takes only the space it needs, or Fill — it greedily consumes remaining space, with a 0–1 weight for distributing among multiple Fill children), and alignment options. These are the workhorses for menus, button rows, stat displays, and any linear arrangement. Prefer them over Canvas Panel for sub-layouts — they’re cheaper on draw calls and produce layouts that respond naturally to different content sizes.

Overlay stacks all children directly on top of each other in the same space, sized to the largest child. First child is the back layer, last child is the front. Use it for layering a background image behind text, combining icons with badges, or placing a Background Blur widget behind a menu panel.

Size Box wraps a single child and overrides its reported size — use it to force a button to exactly 300×80 pixels or set minimum dimensions on a text block. Scale Box uniformly scales its child to fit available space, with stretch modes like Scale to Fit (letterbox, preserves aspect ratio) and Scale to Fill (may crop, no empty space). Useful for background images that must fill a region without distortion.


Getting widgets on screen


Two nodes display UI at runtime: Create Widget (instantiates it) and Add to Viewport (draws it). Build this chain in your Player Controller’s Event Graph:
  1. Drag off Event BeginPlay → add Create Widget → set Class to WBP_PlayerHUD.
  2. Drag off Return Value → Promote to Variable → name it HUDRef.
  3. Drag off the Set node → add Add to Viewport.
  4. Connect your HUDRef variable to Add to Viewport's Target pin.

Setup note: The Third Person template doesn’t include a custom Player Controller. Create one (right-click → Blueprint Class → Player Controller), then set it in your GameMode’s Player Controller Class. If you don’t have a custom GameMode either, create one the same way (Blueprint Class → Game Mode Base) and set it in Project Settings → Maps & Modes → Default GameMode.

The Player Controller is the recommended owner because it persists across pawn changes (respawns, vehicles), keeping UI stable.


Feeding game data into UI


Property bindings are the simplest approach — click the Bind dropdown next to a widget property in the Designer to create a function that returns the matching type. For example, binding a Progress Bar’s Percent to a function that reads CurrentHealth / MaxHealth from your Character. The problem: this function runs every frame on Slate's render cycle, even when health hasn't changed. It works for prototyping, but Epic's official optimization guidelines are blunt — avoid raw bindings in production.

Event-driven updates are the better pattern and worth learning from the start. The idea is simple: update UI only when data actually changes.
  1. In your Character Blueprint, create an Event Dispatcher (e.g., OnHealthChanged). After any script that modifies health, add a Call node for this dispatcher.
  2. In the Widget Blueprint’s Event Construct (fires once when the widget initializes), call Get Owning Player Pawn → Cast to your Character class → Promote to Variable to cache the reference. Then call Bind Event to OnHealthChanged on that cached character, targeting a Custom Event in the widget (e.g., UpdateHealthDisplay).
  3. The Custom Event reads health from the cached character and calls Set Percent on the Progress Bar. Initialize the display by calling the event once during Event Construct after binding.

This pattern means zero per-frame cost. The UI sits idle until health actually changes, then updates instantly. It’s a little more setup than a binding, but it scales — you can use the same dispatcher pattern for ammo, score, status effects, or any other changing value.


Button events


Select a Button in the Hierarchy, ensure Is Variable is checked at the top of the Details panel, then scroll all the way to the bottom of Details. You’ll see the Events section listing OnClicked, OnHovered, OnUnhovered, and others, each with a green + button. Click + next to On Clicked — this automatically creates an event node in the Graph tab. Connect whatever logic should execute from there.



OnHovered and OnUnhovered work the same way — click + to create the event. Use them for hover effects like changing button style, playing sounds, or showing tooltips. The difference between OnPressed, OnReleased, and OnClicked: OnPressed fires the instant the mouse goes down. OnReleased fires when released. OnClicked fires after a complete press-and-release cycle, which feels natural and prevents accidental triggers. For most gameplay UI, OnClicked is the right choice.


Building a simple HUD


Step 1: Create WBP_PlayerHUD and open it.


Step 2: Design the layout


Drag a Canvas Panel into the Hierarchy. Then add:

Health bar: Progress Bar → anchor top-left → Position 20,20 → Size 300×30 → Percent 1.0 → Fill Color green → rename HealthBar → check Is Variable.

Score text: Text → anchor top-center → Alignment (0.5, 0) → Text “Score: 0” → Size 36 → rename ScoreText → check Is Variable.

Pause button: Button → anchor top-right → drag a Text child inside it → child text “Pause” → rename Button to PauseButton → check Is Variable.


Step 3: Script the logic


In the Graph tab, create an UpdateHealth function (Float input HealthPercent) that calls Set Percent on HealthBar. Create UpdateScore (Integer input NewScore) using Format Text Score: {0} → Set Text on ScoreText. For the pause button: OnClicked → Set Game Paused (true) → Set Show Mouse Cursor (true) → Set Input Mode UI Only.


Step 4: Spawn from Player Controller


BeginPlay → Create Widget (WBP_PlayerHUD) → Promote to Variable → Add to Viewport.


Step 5: Connect data


In your Character Blueprint, after health changes, get the HUDRef from the Player Controller and call UpdateHealth with CurrentHealth / MaxHealth. For cleaner architecture, use Event Dispatchers.


Styling basics


Visibility is more nuanced than visible/hidden — UMG has five states:

Visible renders and receives input. Collapsed is invisible and takes no space — use this to toggle elements. Hidden is invisible but reserves space. Not Hit-Testable variants render visually but don’t block mouse input — set decorative elements to this so they don’t intercept button clicks.

Render Opacity cascades to all children — set a panel to 0.5 and everything inside becomes semi-transparent. Padding works through slot properties: a widget inside a Vertical Box has Padding on its slot (Top, Bottom, Left, Right) acting like CSS margin. Font outlines under Appearance → Font → Outline Settings help text readability over busy 3D backgrounds.

Common mistakes


Forgetting anchors is the single most common beginner error. What looks perfect at 1920×1080 drifts off-screen at other resolutions. Always set anchor presets appropriate to each widget’s screen position, and test with the Designer’s Screen Size dropdown.

Canvas Panel for everything. Canvas Panel is great for your root HUD level where elements need absolute positioning. For sub-layouts — a row of buttons, a stacked menu, a stat display — use Vertical Box, Horizontal Box, or Overlay instead. They’re cheaper on draw calls and produce naturally responsive arrangements.

Input mode confusion causes “my buttons don’t work” and “I can’t move my character” bugs constantly. Three nodes control this: Set Input Mode Game Only (UI gets no input), Set Input Mode UI Only (game gets no input), and Set Input Mode Game and UI (both work, UI gets priority). For a HUD with clickable buttons during gameplay, use Game and UI. For full-screen menus, use UI Only. Always pair UI modes with Set Show Mouse Cursor (true) — without it, the cursor is invisible and nothing can be clicked.

Not checking Is Variable. If you can’t find a widget in the Graph tab’s variable list, go back to the Designer, select the widget, and check the box at the top of Details. Without it, you can’t call Set Text, Set Percent, bind events, or do anything programmatic with that widget.

Not storing the Create Widget reference. If you skip the Promote to Variable step, you can see the widget on screen but can’t update or remove it later. Always store it.

Player Controller class not set in GameMode. Your custom Player Controller with HUD creation logic never runs because the GameMode is still using the default controller. Set it in Project Settings → Maps & Modes or in the GameMode Blueprint’s Classes section.

What’s next

For now, the fundamentals covered here — Widget Blueprints, the four essential widgets, layout panels, event-driven data binding, and proper anchoring — will get you through the vast majority of indie game UI needs. Build the HUD from this tutorial, get it running in the Third Person template, then start adapting it for your own project.




Linktr.ee  INSTAGRAM