Skip to main content

πŸ“‹ Menus and Navigation

Every game needs menusβ€”a main menu to start, a pause menu to take breaks, settings to customize the experience. But menus are more than buttons on screen. They need to handle input modes, support keyboard and gamepad navigation, manage focus, and transition smoothly between screens. In this lesson, you'll learn to create professional menu systems that feel polished and responsive.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Create main menus with proper input handling
  • Build pause menus that freeze gameplay
  • Implement settings screens with working controls
  • Support keyboard and gamepad navigation
  • Manage widget focus for accessible navigation
  • Transition between menu screens smoothly

Estimated Time: 55-65 minutes

Prerequisites: Lesson 7.2 (Creating Widgets), Lesson 7.3 (HUD Elements)

πŸ“‘ In This Lesson

Pause Menu System

The pause menu appears during gameplay, freezes the game, and lets players access options or quit. It requires careful handling of input mode and game pause state.

Pause Menu Widget

Create WBP_PauseMenu with structure similar to main menu:

Canvas Panel
β”œβ”€β”€ Image (Semi-transparent background overlay)
└── Vertical Box (Centered)
    β”œβ”€β”€ Text Block: "PAUSED"
    β”œβ”€β”€ Button: "Resume"
    β”œβ”€β”€ Button: "Options"
    β”œβ”€β”€ Button: "Main Menu"
    └── Button: "Quit"

The background overlay should be semi-transparent (e.g., black with 0.7 alpha) to dim the game view.

Opening the Pause Menu

Handle pause input in your Player Controller:

  1. Create an Input Action for Pause (or use the Escape key directly)
  2. In Player Controller, on pause input:
    • Check if pause menu is already open
    • If not open: Create and show pause menu
    • If open: Close pause menu

Player Controller Setup

Variables needed:

  • PauseMenuWidget (type: WBP_PauseMenu) β€” Reference to current pause menu
  • bIsPaused (Boolean) β€” Track pause state

Functions:

// Function: OpenPauseMenu
Create Widget (WBP_PauseMenu) β†’ Set PauseMenuWidget
Add to Viewport (PauseMenuWidget)
Set Game Paused: True
Set Input Mode UI Only (Widget to Focus: Resume Button)
Set Show Mouse Cursor: True
Set bIsPaused: True

// Function: ClosePauseMenu
Remove from Parent (PauseMenuWidget)
Set PauseMenuWidget: None
Set Game Paused: False
Set Input Mode Game Only
Set Show Mouse Cursor: False
Set bIsPaused: False

// On Pause Input Pressed
Branch on bIsPaused
  True β†’ ClosePauseMenu
  False β†’ OpenPauseMenu
Pause Menu Flow Gameplay Input: Game Only Paused: False ESC Pause Menu Open Input: UI Only Paused: True Resume / ESC Options Quit / Main Menu

Figure: Pause menu flow showing state transitions.

Pause Menu Button Handlers

In WBP_PauseMenu, handle button clicks:

Resume Button

On Resume Clicked:
  Get Owning Player β†’ Cast to YourPlayerController
  Call ClosePauseMenu function

Main Menu Button

On MainMenu Clicked:
  Get Owning Player β†’ Cast to YourPlayerController
  Call ClosePauseMenu function
  Open Level: "MainMenu_Level"

Quit Button

On Quit Clicked:
  Quit Game

Handling ESC to Close

Players expect ESC to close the pause menu. Two approaches:

Option 1: Handle in Player Controller (already done if toggle logic is there)

Option 2: Handle in Widget with Input Action:

  1. In widget Graph, search for "Escape" or your pause action
  2. On that input, call the close/resume logic

Confirmation Dialogs

For destructive actions (Quit, Return to Main Menu), add confirmation:

  1. Create WBP_ConfirmDialog widget:
    • Text: "Are you sure?"
    • Button: "Yes" / "Confirm"
    • Button: "No" / "Cancel"
  2. Add Event Dispatcher: OnConfirmed
  3. Add Event Dispatcher: OnCancelled
  4. Yes calls OnConfirmed; No calls OnCancelled
  5. Parent binds to dispatchers and handles result
Confirmation Dialog Pattern Return to Main Menu? Unsaved progress will be lost. Yes, Exit Cancel Show confirmation for destructive actions like quitting or losing progress

Figure: Confirmation dialog prevents accidental data loss.

Settings/Options Menu

Options menus let players customize their experience. Common settings:

Graphics:

  • Resolution (Combo Box)
  • Quality Preset (Low/Medium/High/Ultra)
  • Fullscreen/Windowed (Check Box)
  • VSync (Check Box)

Audio:

  • Master Volume (Slider)
  • Music Volume (Slider)
  • SFX Volume (Slider)

Controls:

  • Mouse Sensitivity (Slider)
  • Invert Y (Check Box)
  • Key Bindings (advanced)

Saving Settings

Use the Game User Settings system for graphics, or create a custom Save Game for other settings:

// Get Game User Settings
Get Game User Settings β†’ Set Fullscreen Mode
                       β†’ Set Screen Resolution
                       β†’ Apply Settings

// For custom settings (audio, controls)
Create Save Game Object β†’ Set values β†’ Save to Slot

βœ… Settings Best Practices

  • Apply changes immediately so players can see the effect
  • Provide "Apply" and "Cancel" buttons for confirmation
  • Auto-save on Apply, or revert on Cancel
  • Include "Reset to Defaults" option
  • Load saved settings on game start

Hands-On: Complete Menu System

Let's build a complete menu system with a main menu, pause menu, and a simple options screen. This exercise ties together everything we've learned about menus, input modes, focus, and navigation.

🎯 Exercise Goal

Create a functional menu system with: a main menu that starts the game, a pause menu accessible during gameplay, an options screen with volume control, and proper keyboard/gamepad navigation throughout. All menus will properly handle input modes and focus.

Part 1: Create the Main Menu

Step 1: Create the Widget

  1. Create Widget Blueprint: WBP_MainMenu
  2. Open it in the Widget Editor

Step 2: Build the Layout

  1. The root Canvas Panel should already exist
  2. Add Image for background:
    • Anchors: Stretch (all corners)
    • Offsets: All 0
    • Color: Dark blue (#1a237e) or your preference
    • Rename: Background
  3. Add Text Block for title:
    • Anchors: Top-Center
    • Position Y: 80
    • Alignment X: 0.5
    • Text: "ADVENTURE GAME" (or your title)
    • Font Size: 48
    • Rename: TitleText
  4. Add Vertical Box for buttons:
    • Anchors: Center
    • Alignment: 0.5, 0.5
    • Rename: ButtonContainer

Step 3: Add Menu Buttons

Inside ButtonContainer, add three buttons:

  1. Play Button:
    • Add Button to ButtonContainer
    • Add Text child: "Play Game"
    • Button size: 200 Γ— 50
    • Padding (Slot): 0, 5, 0, 5 (top/bottom margin)
    • Style Normal Tint: #667eea
    • Style Hovered Tint: #8b9cf9
    • Style Pressed Tint: #5560d4
    • Rename button: PlayButton
    • Check Is Variable
  2. Options Button:
    • Same styling as Play
    • Text: "Options"
    • Rename: OptionsButton
  3. Quit Button:
    • Same styling as Play
    • Text: "Quit"
    • Rename: QuitButton
WBP_MainMenu Structure Hierarchy πŸ“¦ Canvas Panel [Root] β”œβ”€ πŸ–ΌοΈ Background β”œβ”€ πŸ“ TitleText └─ πŸ“ ButtonContainer β”œβ”€ πŸ”˜ PlayButton └─ Text "Play Game" β”œβ”€ πŸ”˜ OptionsButton └─ πŸ”˜ QuitButton ADVENTURE GAME Play Game Options Quit First button has focus (white border)

Figure: Main menu widget hierarchy and preview.

Step 4: Add Button Click Events

Switch to Graph view:

  1. Play Button Handler:
    • Select PlayButton in Hierarchy
    • In Details β†’ Events β†’ On Clicked, click +
    • In the event handler, add:
      • Open Level node
      • Level Name: "GameLevel" (your gameplay level)
  2. Quit Button Handler:
    • Create On Clicked event for QuitButton
    • Add Quit Game node
  3. Options Button: (We'll complete this after creating options menu)

Step 5: Set Initial Focus

  1. In Graph, add Event Construct
  2. Drag PlayButton from Variables
  3. Add Set Keyboard Focus node
  4. Connect PlayButton to Target

Part 2: Create the Main Menu Level

  1. Create a new Level: File β†’ New Level β†’ Empty Level
  2. Save as MainMenu_Level
  3. Open Level Blueprint (Blueprints β†’ Open Level Blueprint)
  4. Add the following on Event BeginPlay:
    • Create Widget (Class: WBP_MainMenu)
    • Add to Viewport
    • Get Player Controller (index 0)
    • Set Input Mode UI Only
    • Set Show Mouse Cursor: True
MainMenu_Level Blueprint Event BeginPlay Create Widget WBP_MainMenu Add to Viewport Set Input Mode UI Only Set Show Mouse Cursor Get Player Controller (0) feeds into Set Input Mode and Set Show Mouse Cursor

Figure: Level Blueprint setup for main menu.

Part 3: Create the Pause Menu

Step 1: Create the Widget

  1. Create Widget Blueprint: WBP_PauseMenu

Step 2: Build the Layout

  1. Add Image for overlay:
    • Anchors: Stretch
    • Color: Black with 0.7 alpha (semi-transparent)
    • Rename: Overlay
  2. Add Vertical Box for content:
    • Anchors: Center
    • Alignment: 0.5, 0.5
    • Rename: MenuContainer
  3. Inside MenuContainer, add:
    • Text Block: "PAUSED" (Font Size: 36)
    • Spacer: Height 30
    • Button: "Resume" β†’ ResumeButton (Is Variable βœ“)
    • Button: "Options" β†’ PauseOptionsButton
    • Button: "Main Menu" β†’ MainMenuButton
    • Button: "Quit" β†’ PauseQuitButton
  4. Style all buttons consistently (same as main menu)

Step 3: Create Event Dispatcher

The pause menu needs to tell the Player Controller when to close:

  1. In Graph, go to My Blueprint panel
  2. Under Event Dispatchers, click +
  3. Name it OnResumeClicked

Step 4: Add Button Events

  1. Resume Button:
    • On Clicked β†’ Call OnResumeClicked (dispatcher)
  2. Main Menu Button:
    • On Clicked β†’ Open Level: "MainMenu_Level"
  3. Quit Button:
    • On Clicked β†’ Quit Game

Step 5: Set Initial Focus

  1. On Event Construct β†’ Set Keyboard Focus to ResumeButton

Part 4: Set Up Player Controller

  1. Create (or open) your Player Controller Blueprint: BP_PlayerController

Step 1: Add Variables

  1. PauseMenuRef (Type: WBP_PauseMenu, Object Reference)
  2. bIsGamePaused (Type: Boolean, Default: False)

Step 2: Create OpenPauseMenu Function

  1. Create new function: OpenPauseMenu
  2. Add nodes:
    • Create Widget (Class: WBP_PauseMenu, Owning Player: Self)
    • Set PauseMenuRef to return value
    • Add to Viewport (Target: PauseMenuRef)
    • Set Game Paused: True
    • Set Input Mode UI Only (In Widget to Focus: PauseMenuRef)
    • Set Show Mouse Cursor: True
    • Set bIsGamePaused: True
    • Drag PauseMenuRef β†’ Bind Event to OnResumeClicked
    • Create custom event: HandleResume

Step 3: Create ClosePauseMenu Function

  1. Create new function: ClosePauseMenu
  2. Add nodes:
    • Is Valid check on PauseMenuRef
    • If valid: Remove from Parent (Target: PauseMenuRef)
    • Set PauseMenuRef: None (clear reference)
    • Set Game Paused: False
    • Set Input Mode Game Only
    • Set Show Mouse Cursor: False
    • Set bIsGamePaused: False

Step 4: Handle HandleResume Event

  1. From the HandleResume custom event created earlier
  2. Call ClosePauseMenu

Step 5: Handle Pause Input

  1. In Event Graph, add input for Escape key (or create Input Action)
  2. On Escape Pressed:
    • Branch on bIsGamePaused
    • True β†’ Call ClosePauseMenu
    • False β†’ Call OpenPauseMenu
Player Controller Pause Logic Escape Pressed Paused? ClosePauseMenu Resume gameplay True OpenPauseMenu Show pause menu False OpenPauseMenu does: β€’ Create WBP_PauseMenu widget β€’ Add to Viewport β€’ Set Game Paused = True β€’ Set Input Mode UI Only β€’ Bind to OnResumeClicked

Figure: Player Controller handles pause menu toggle.

Part 5: Create Simple Options Menu

Step 1: Create the Widget

  1. Create Widget Blueprint: WBP_OptionsMenu

Step 2: Build the Layout

  1. Add Image for background (same as main menu or semi-transparent)
  2. Add Vertical Box (centered) for content
  3. Inside Vertical Box:
    • Text Block: "OPTIONS" (title)
    • Spacer: Height 20
    • Horizontal Box: Volume control
      • Text Block: "Master Volume"
      • Slider: VolumeSlider (Is Variable βœ“)
      • Text Block: VolumePercent (Is Variable βœ“) "100%"
    • Spacer: Height 20
    • Button: "Back" β†’ BackButton

Step 3: Add Event Dispatcher

  1. Create Event Dispatcher: OnBackClicked

Step 4: Add Slider Logic

  1. Select VolumeSlider
  2. In Details β†’ Events β†’ On Value Changed, click +
  3. In the event handler:
    • Get the Value parameter
    • Multiply by 100, round to integer
    • Format as text with "%"
    • Set VolumePercent text
    • (Optional) Apply to audio: Get Sound Mix β†’ Set Sound Mix Class Override

Step 5: Back Button

  1. On BackButton Clicked β†’ Call OnBackClicked dispatcher

Part 6: Connect Options to Menus

Now connect the Options button in both menus:

Main Menu Options Button:

  1. In WBP_MainMenu Graph
  2. Create variable: OptionsMenuRef (Type: WBP_OptionsMenu)
  3. On OptionsButton Clicked:
    • Create Widget (WBP_OptionsMenu)
    • Set OptionsMenuRef
    • Add to Viewport
    • Set Self Visibility: Collapsed (hide main menu)
    • Bind to OnBackClicked β†’ Create custom event "HandleOptionsBack"
  4. On HandleOptionsBack:
    • Remove OptionsMenuRef from Parent
    • Set Self Visibility: Visible
    • Set Keyboard Focus to PlayButton

Part 7: Set Game Mode

  1. Open Project Settings β†’ Maps & Modes
  2. Set Default GameMode to one that uses your BP_PlayerController
  3. Or create a Game Mode Blueprint that specifies BP_PlayerController
  4. Set Editor Startup Map to MainMenu_Level
  5. Set Game Default Map to MainMenu_Level

Part 8: Test Everything

  1. Test Main Menu:
    • Play the MainMenu_Level
    • Verify mouse cursor is visible
    • Click buttons to test hover states
    • Use arrow keys to navigate between buttons
    • Press Enter to activate focused button
    • Test Options opens and Back returns
    • Test Quit exits (in standalone, not editor)
  2. Test Gameplay:
    • Click Play to start game level
    • Verify mouse cursor is hidden
    • Verify character can move (if applicable)
  3. Test Pause Menu:
    • Press Escape during gameplay
    • Verify game pauses (movement stops)
    • Verify mouse cursor appears
    • Test Resume closes menu and unpauses
    • Test Main Menu returns to main menu level
    • Test Escape key closes pause menu

βœ… Exercise Complete!

You've built a complete menu system with:

  • Main menu with Play, Options, and Quit buttons
  • Pause menu with Resume, Options, Main Menu, and Quit
  • Simple options screen with volume slider
  • Proper input mode handling (UI Only vs Game Only)
  • Keyboard/gamepad navigation with focus
  • Game pause functionality
  • Menu transitions with Event Dispatchers

This foundation can be expanded with more options, confirmation dialogs, and visual polish!

Troubleshooting

⚠️ Common Issues

Can't click buttons:

  • Verify Input Mode is set to UI Only
  • Check that Show Mouse Cursor is True
  • Ensure buttons aren't blocked by other widgets

Can't use keyboard to navigate:

  • Set Keyboard Focus to the first button
  • Ensure buttons have Is Focusable checked (default for buttons)

Game doesn't pause:

  • Verify Set Game Paused is being called
  • Check that the Player Controller is being used

ESC doesn't work:

  • Verify input event is set up in Player Controller
  • Check that the Game Mode uses your Player Controller

Options menu doesn't return:

  • Verify Event Dispatcher is being called on Back button
  • Check that parent widget binds to the dispatcher

Bonus Challenges

  1. Add Menu Animations: Fade in the main menu on level load, slide buttons in
  2. Add Sound Effects: Play sounds on button hover and click
  3. Add Confirmation Dialog: Confirm before quitting or returning to main menu
  4. Add More Settings: Graphics quality, fullscreen toggle, mouse sensitivity
  5. Save Settings: Use Save Game to persist options between sessions
  6. Add Loading Screen: Show a loading widget when transitioning between levels

Summary

In this lesson, you've learned how to create professional menu systems that handle input properly, support multiple input devices, and integrate smoothly with gameplay. Menus are where players spend significant time, so getting them right is essential for a polished game experience.

Key Concepts

Input Modes: Three modes control where input goesβ€”Game Only for gameplay, UI Only for menus, and Game and UI for hybrid situations. Always set the appropriate mode when showing or hiding menus.

Widget Focus: Focus determines which widget receives keyboard/gamepad input. Set initial focus when opening menus to enable immediate navigation. Buttons are focusable by default; other widgets can be made focusable as needed.

Navigation: UMG automatically handles directional navigation between focusable widgets. Override navigation explicitly when automatic behavior doesn't work well for your layout.

Game Pause: Use Set Game Paused to freeze gameplay during pause menus. Remember that UI widgets continue to function while the game is paused.

Main Menu: Typically in a dedicated level, displays on BeginPlay, sets Input Mode UI Only. Contains buttons for Play, Options, and Quit with appropriate handlers.

Pause Menu: Created and shown during gameplay, toggled with ESC/Start. Requires pausing the game, changing input mode, and showing cursor. Resume button restores gameplay state.

Event Dispatchers: Enable child menus (like Options) to communicate back to parent menus. The child calls the dispatcher; the parent binds and handles the response.

Menu Transitions: Use visibility changes, Widget Switcher, or create/destroy widgets to move between menu screens. Maintain focus and input state during transitions.

Input Mode Quick Reference

Situation Input Mode Cursor Game Paused
Normal Gameplay Game Only Hidden No
Main Menu UI Only Visible N/A
Pause Menu UI Only Visible Yes
Inventory (gameplay continues) Game and UI Visible Optional
HUD Only Game Only Hidden No

Menu System Checklist

When Opening Menu When Closing Menu
Create/Show widget Remove from Parent/Hide widget
Add to Viewport Clear widget reference
Set Input Mode UI Only Set Input Mode Game Only
Show Mouse Cursor = True Show Mouse Cursor = False
Set Game Paused = True (if pause menu) Set Game Paused = False
Set Keyboard Focus to first button β€”

Best Practices

  • Always set initial focus: Enable immediate keyboard/gamepad navigation without requiring a click first
  • Match input mode to context: UI Only for menus, Game Only for gameplayβ€”don't leave in wrong state
  • Handle both mouse and controller: Test navigation with keyboard, then gamepadβ€”both should work smoothly
  • Use Event Dispatchers for sub-menus: Keep menu logic encapsulated; communicate through dispatchers
  • Add confirmation for destructive actions: Quit and Return to Main Menu should confirm to prevent accidents
  • Keep animations short: 0.2-0.5 seconds maxβ€”players see menus repeatedly
  • Test pause functionality: Verify game actually freezesβ€”physics, AI, timers should all stop
  • Clear references when closing: Set widget references to None after Remove from Parent to prevent stale references
  • Consider audio: Add button hover/click sounds; pause music or lower volume during pause menu
Complete Menu System Architecture Main Menu Level WBP_MainMenu Input: UI Only Gameplay Level WBP_PlayerHUD Input: Game Only Pause Menu WBP_PauseMenu Input: UI Only + Paused Play ESC Resume Main Menu Player Controller Manages pause state, input modes, and menu widgets

Figure: Complete menu system showing relationships between levels, menus, and the Player Controller.

What's Next?

With your menu system complete, the next lesson covers Data Binding and Events in more depth. You'll learn advanced techniques for connecting UI to game systems, including property binding optimizations, event-based UI updates, and creating truly dynamic interfaces that respond to complex game state changes.

Knowledge Check

Question 1

What input mode should you use when displaying a full-screen pause menu?

Correct answer: B β€” UI Only ensures that input goes to the menu widgets and not to the game. This prevents the player from accidentally moving or shooting while navigating the menu. Combined with Set Game Paused, the game freezes while the menu is open.

Question 2

Why is it important to set keyboard focus when opening a menu?

Correct answer: B β€” Setting initial focus allows players using keyboard or gamepad to immediately navigate with arrow keys/D-pad without needing to click a button first. This is essential for controller support and accessibility.

Question 3

What three things should you typically do when closing a pause menu?

Correct answer: A β€” When closing a pause menu: (1) Remove from Parent to hide the widget, (2) Set Input Mode Game Only so the player can control the game again, (3) Set Game Paused False to resume gameplay. Also hide the mouse cursor with Set Show Mouse Cursor False.

Question 4

How do sub-menus (like Options) typically communicate back to parent menus?

Correct answer: C β€” Event Dispatchers are the proper way for sub-menus to communicate with parents. The Options menu calls OnBackClicked dispatcher; the parent (Main Menu or Pause Menu) binds to it and handles closing the options and restoring focus.

Question 5

Where is the best place to handle the ESC key for toggling the pause menu?

Correct answer: B β€” The Player Controller is the best location because it persists throughout gameplay, has access to input, and is responsible for managing the player's UI state. It can track whether the menu is open and toggle appropriately.

Question 6

What happens if you forget to call Set Game Paused False when closing a pause menu?

Correct answer: B β€” The game state remains paused even after the menu is removed. The player can see the game world but nothing movesβ€”physics, AI, and animations all stay frozen. Always pair Set Game Paused True with a corresponding False.

Question 7

Which widgets are focusable by default in UMG?

Correct answer: C β€” Interactive widgets that respond to input (Button, Check Box, Slider, Editable Text) are focusable by default. Display-only widgets like Text Block, Image, and Progress Bar are not focusable by default but can be made focusable in their properties.