Overview
UtilityBelt is a general-purpose helper library for gameplay and UI programmers. It solves the problems that come up in almost every project — knowing whether the player is on mouse, keyboard or gamepad, making UMG menus navigable with a controller, showing the right button prompt, typing out dialogue, easing values, pooling actors — so you can use tested building blocks instead of rewriting them.
- Input-method detection per local player with events when the player switches between mouse, keyboard and gamepad.
- Focusable widgets: button, check box, slider, user widget and panel classes that use their Hovered style when focused and raise focus events.
- Menu stack: hierarchical menus with back/close keys, automatic focus and input-mode / pause / pointer handling.
- Input prompts: an image widget and a rich-text
<input .../>decorator that always show the binding for the active device (Enhanced Input or legacy input). - Typewriter text, option selectors, tab lists, a smoothly changing progress bar and stylable subtitle widgets.
- Gameplay helpers: actor pooling, light flicker component, smooth spring arm, runtime-resizable NavMesh bounds, replicated physics actor, render-target pool.
- Maths: easing functions, cone/convex/2D geometry helpers, balanced (Halton) random streams and shuffle bags.
- Editor helpers: an always-visible debug visualisation component and a data-table row picker locked to one table.
Requirements
| Requirement | Details |
|---|---|
| Unreal Engine | 5.8 (verified clean) |
| Modules | UtilityBelt (Runtime), UtilityBeltTypewriter (Runtime, typewriter text widget), UtilityBeltEditor (Editor) |
| Dependencies | Engine plugins Enhanced Input and Paper2D (enabled automatically with UtilityBelt) |
| Language | Blueprints and C++ |
| Platforms | Win64, Linux, Mac (the plugin's platform list). Win64 is built and verified by Alpha XP; Linux and Mac are supported by the code, not verified by Alpha XP. |
Installation
- Install UtilityBelt from the launcher into your engine, or copy the
UtilityBeltfolder into your project'sPluginsfolder. - For a C++ project, regenerate project files and build the editor target.
- Open the project, go to Edit > Plugins, enable UtilityBelt and restart the editor. Enhanced Input and Paper2D are enabled with it.
- To use the C++ API, add the module to your
.Build.cs:PrivateDependencyModuleNames.Add("UtilityBelt");. The typewriter text widget lives in its own runtime module; add"UtilityBeltTypewriter"as well if your C++ code usesUTypewriterTextWidget(Blueprints need nothing extra).
Quick start
Blueprint: react to the player's input method
- In a widget or actor Blueprint, add the Belt Game Subsystem node (Game Instance Subsystem getter).
- Drag off it and bind to On Input Mode Changed; the event gives you the player index and the new
EInputMode(Mouse, Keyboard, Gamepad). - Query the current state at any time with Get Last Input Mode Used or Last Input Was Game Pad.
- For prompts, place an UInputImage in a widget, set its Binding Type to Enhanced Input Action and pick an action — it switches between keyboard and gamepad art automatically (requires a UI theme, see UI theme & prompts).
C++
#include "UtilityBelt.h" // GetBeltGameSubsystem()
#include "BeltEasings.h"
void AMyHUDActor::BeginPlay()
{
Super::BeginPlay();
if (UBeltGameSubsystem* GS = GetBeltGameSubsystem(GetWorld()))
{
GS->OnInputModeChanged.AddDynamic(this, &AMyHUDActor::HandleInputModeChanged);
const EInputMode Mode = GS->GetLastInputModeUsed(0);
UE_LOG(LogTemp, Log, TEXT("Gamepad active: %d"), Mode == EInputMode::Gamepad);
}
}
// UFUNCTION() void HandleInputModeChanged(int PlayerIndex, EInputMode NewMode);
void AMyHUDActor::HandleInputModeChanged(int PlayerIndex, EInputMode NewMode)
{
const float Eased = UBeltEasings::EaseAlpha(0.25f, EBeltEaseFunction::EaseOut_Back);
// ...
}
Settings
Project Settings > Engine > UtilityBelt (class UBeltPluginSettings, saved to Config/DefaultEngine.ini):
| Setting (C++ name) | Default | Description |
|---|---|---|
bHideMouseWhenGamepadUsed (Hide Mouse When Gamepad Used) | true | Moves the pointer off-screen and hides it when the player switches to a gamepad. |
EnhancedInputActionSearchDirectories (Directories to search for Enhanced Input Actions) | empty | Content folders searched when an Enhanced Input action is referenced by name, e.g. <input eaction="IA_Jump"/>. |
The default UI theme is configured in Config/DefaultGame.ini (restart the editor after changing it):
[/Script/UtilityBelt.BeltGameSubsystem]
DefaultUiThemePath="/Game/UI/DefaultUiTheme.DefaultUiTheme"
For the cursor to stay hidden during gamepad navigation, set Project Settings > Engine > General Settings > Game Viewport Client Class to BeltGameViewportClientBase (or a subclass).
Input & game subsystem
UBeltGameSubsystem is a Game Instance Subsystem; in Blueprints search for Belt Game Subsystem. In C++ use GetBeltGameSubsystem(UWorld*) from UtilityBelt.h.
| Node | Type | Description |
|---|---|---|
| Get Last Input Mode Used | Callable | Device (Mouse / Keyboard / Gamepad) of the most recent input of any kind for a player index. |
| Get Last Input Button Pressed | Callable | Device of the most recent button or key press (ignores axis movement). |
| Get Last Input Axis Moved | Callable | Device of the most recent axis movement (ignores button presses). |
| Last Input Was Game Pad | Callable | True when the last input of any kind came from a gamepad. |
| Get Input Image Sprite | Callable | Paper2D sprite for an action, axis or explicit key, using the device preference and an optional theme. |
| Register Interest In Enhanced Input Action | Callable | Bind an Enhanced Input action/trigger so that On Enhanced Input Action Triggered fires for it (useful from UI). |
| Unregister All Interest In Enhanced Input Actions | Callable | Remove every binding made with the node above (e.g. after loading a new level). |
| Notify Enhanced Input Mappings Changed | Callable | Legacy: re-broadcasts On Enhanced Input Mappings Changed after a short delay. No longer required. |
| Move Mouse Off Screen | Callable | Parks (and optionally hides) the pointer so it cannot trigger hovers during gamepad navigation. |
| On Input Mode Changed | Event | Player index and new main input mode. |
| On Button Input Mode Changed | Event | Raised when the device of the last button press changes. |
| On Axis Input Mode Changed | Event | Raised when the device of the last axis movement changes. |
| On Enhanced Input Action Triggered | Event | Action and trigger event for actions registered with Register Interest In Enhanced Input Action. |
| On Enhanced Input Mappings Changed | Event | Legacy event raised by Notify Enhanced Input Mappings Changed. |
| On Window Foreground Changed | Event | The game window gained or lost the foreground. |
| On Viewport Resized | Event | New viewport width and height (also raised on fullscreen toggle). |
| UBeltGameViewportClientBase | Class | Game viewport client that suppresses the cursor while a gamepad is in use. |
Enums: EInputMode, EInputModeChange, EMousePointerVisibilityChange, EGamePauseChange, EInputBindingType (Action, Axis, Key, EnhancedInputAction), EInputImageDevicePreference.
UI theme & prompts
Prompt images come from a UUiTheme data asset that references two Data Tables of row type FKeySprite (Key + Paper2D Sprite): Keyboard Mouse Images and Xbox Controller Images. Create the theme with Add > Miscellaneous > Data Asset > UiTheme, set it as the default (see Settings) and make sure it is cooked (Asset Manager primary asset or a Primary Asset Label).
| Node | Type | Description |
|---|---|---|
| UUiTheme | Class | Data asset holding the keyboard/mouse and gamepad sprite tables. |
| FKeySprite | Class | Data Table row: Key and Sprite. Row names are key names (e.g. Gamepad_FaceButton_Bottom). |
| UInputImage | Class | Image widget that shows the current binding. Properties: Binding Type, Action Or Axis Name, Input Action, Device Preference, Key, Update Delay, Override Hidden State, Player Index, Custom Theme. |
| Set From Action | Callable | Show the binding of a legacy input action. |
| Set From Axis | Callable | Show the binding of a legacy input axis. |
| Set From Key | Callable | Show a specific key, button or axis. |
| Set From Input Action | Callable | Show the binding of an Enhanced Input action. |
| Get Binding Type | Callable | Current binding type. |
| Get Action Or Axis Name | Callable | Action/axis name used for lookup. |
| Get Key | Callable | Explicit key used when Binding Type is Key. |
| URichTextBlockInputImageDecorator | Class | Rich Text decorator: add it to a Rich Text Block's decorator classes to use the <input/> tag below. |
| Markup | Shows |
|---|---|
<input eaction="IA_Jump"/> | Enhanced Input action, looked up in the configured search directories |
<input action="Fire"/> | Legacy input action |
<input axis="MoveForward"/> | Legacy input axis |
<input key="F1"/> | A specific key, button or axis (any EKeys name) |
Optional attributes: player="1", width="32", height="32", prefer="auto|gkm|gmk|gmkbutton|gmkaxis".
Focusable widgets
These UMG widgets highlight themselves with their Hovered style while they have keyboard/gamepad focus. Set Project Settings > User Interface > Render Focus Rule to Never to hide the engine's dotted focus outline. Common properties: Use Hover Style When Focussed, Take Focus On Hover, Lose Focus On Unhover.
| Node | Type | Description |
|---|---|---|
| UFocusableButton | Class | Button with focus events and focus styling. |
| Simulate Press | Callable | Press the button visually and logically (as if Accept was pressed). |
| Simulate Release | Callable | Release a simulated press. |
| Refresh Focussed Style | Callable | Rebuild the focus style after changing the widget style at runtime (button, check box and slider; overridable). |
| On Focus Received | Event | The widget gained focus (button, check box, slider). |
| On Focus Lost | Event | The widget lost focus (button, check box, slider). |
| UFocusableCheckBox | Class | Check box with focus styling, gamepad navigation and hover/focus events. |
| UFocusableSlider | Class | Slider with focus styling and hover/focus events. |
| On Hovered | Event | Mouse entered (check box, slider). |
| On Unhovered | Event | Mouse left (check box, slider). |
| UFocusableUserWidget | Class | User widget base with optional automatic focus by priority (Enable Automatic Focus, Automatic Focus Priority). |
| Set Focus Properly | Callable | Overridable focus entry point (the engine's SetFocus is not virtual). |
| Is Requesting Focus | Callable | Overridable: whether this widget currently wants focus. |
| Take Focus If Desired | Callable | Overridable: take focus if requesting it. |
| UFocusablePanel | Class | Focusable user widget that delegates focus to a child (Initial Focus Widget Name) and can remember the last focused child. |
| Set Focus To Initial Widget | Callable | Focus the initial child. |
| Get Initial Focus Widget | Event | Overridable: supply the initial focus child dynamically. |
| Set Initial Focus Widget | Callable | Set the initial focus child at runtime. |
| Save Previous Focus | Callable | Remember the currently focused child. |
| Restore Previous Focus | Callable | Re-focus the remembered child. |
| UFocusableInputInterceptorUserWidget | Class | Focusable user widget that sees key presses before UMG consumes them (base of menu stacks and tab lists). |
Options & tabs
UOptionWidgetBase is an option selector that shows clickable arrows for the mouse and a rocker for gamepad/keyboard. Derive a Widget Blueprint from it containing MouseVersion, MouseUpButton, MouseDownButton, MouseUpImage, MouseDownImage, MouseText, GamepadVersion, GamepadUpImage, GamepadDownImage, GamepadText and optionally GamepadUpDisabledImage / GamepadDownDisabledImage (used with Disable At Limit). On GamepadVersion use custom navigation to call Change Option with -1 / 1.
| Node | Type | Description |
|---|---|---|
| Clear Options | Callable | Remove all options. |
| Add Option | Callable | Append an option; returns its index. |
| Set Options | Callable | Replace all options and choose the selected index. |
| Get Selected Index | Pure | Selected index. |
| Get Selected Option | Pure | Selected option text. |
| Set Selected Index | Callable | Select an option by index. |
| Change Option | Callable | Move the selection by a delta (use from custom navigation). |
| Set Mouse Mode | Callable | Show the mouse version. |
| Set Button Mode | Callable | Show the gamepad/keyboard version. |
| Update From Input Mode | Callable | Switch version for a given input mode. |
| Get Current Input Mode | Callable | Input mode the widget is displaying for. |
| Post Selected Option Changed | Event | Overridable hook after the selection changes. |
| On Selected Option Changed | Event | The player changed the selection. |
| UNamedOptionWidgetBase | Class | Option widget addressed by FName keys (populated from code/graphs). |
| Add Named Option | Callable | Append an option with a name. |
| Set Named Options | Callable | Replace all options from a name-to-text map. |
| Get Selected Name | Pure | Name of the selected option. |
| Get Index For Name | Callable | Index of a named option. |
| Get Name For Index | Callable | Name of the option at an index. |
| Set Selected Name | Callable | Select by name. |
| UTabListWidget | Class | Tab bar that drives a Widget Switcher; needs a panel named TabButtonContainer. Previous/next tab keys default to the gamepad shoulders and Q/E. |
| Register Tab | Callable | Add a tab: id, button class, label and content widget. |
| Set Target Widget Switcher | Callable | Widget Switcher controlled by the tabs. |
| Increment Tab Index | Callable | Move the selection by an amount. |
| Select Tab | Callable | Select a tab by index. |
| On Content Widget Changed | Event | Previous and new content widget. |
| UTabButton | Class | Base class for tab buttons created by the tab list. |
| Set Tab Label | Event | Overridable: display the label. |
| Set Tab Selected | Callable | Mark the tab selected/unselected. |
| Notify Tab Selected | Callable | Call from your button's click to select this tab. |
| Refresh For Selection Changed | Event | Overridable: update visuals for the selection state. |
| On Tab Selected | Event | Tab index that was selected. |
Text & progress widgets
UTypewriterTextWidget: create a Widget Blueprint derived from it containing a URichTextBlockForTypewriter named LineText (module UtilityBeltTypewriter, header TypewriterTextWidget.h). Line breaks and the final height are calculated before playback, so text never jumps between lines. Properties: Letter Play Time, End Hold Time, Pause Time At Sentence Terminators, Sentence/Clause Terminators, Max Number Of Lines, Play When Paused, New Word Event.
| Node | Type | Description |
|---|---|---|
| Play Line | Callable | Start typing a line at a speed multiplier. |
| Skip To Line End | Callable | Show the rest of the current line immediately. |
| Has Finished Playing Line | Callable | Whether the whole line has been shown. |
| Has More Line Parts | Callable | True when Max Number Of Lines split the line and parts remain. |
| Play Next Line Part | Callable | Play the next part of a split line. |
| Get Current Line | Callable | Line currently being played. |
| Set Text | Callable | Set text immediately without the effect. |
| Get Text | Callable | Current text. |
| Get Play Speed | Callable | Current speed multiplier. |
| Set Play Speed | Callable | Change the speed multiplier while playing. |
| Find Word Vowels | Callable | Positions of the vowels in a word (e.g. for lip-flap or voice blips). |
| On Play Letter | Event | Implementable: one or more letters were added. |
| On Line Finished Playing | Event | Implementable: the line finished. |
| On Typewriter Line Finished | Event | The line finished playing or was skipped. |
| On Typewriter Letter Added | Event | New letters shown. |
| On Typewriter Start Word | Event | A new word started (when New Word Event is enabled). |
| On Typewriter Run Name Changed | Event | The rich-text style run changed. |
| USmoothChangingProgressBar | Class | Progress bar that animates to its target (Percent Change Speed, Percent Change Frequency). |
| Set Percent Smoothly | Callable | Animate to a new percentage. |
| Stop Smooth Percent Change | Callable | Stop the animation (call before a plain Set Percent). |
| UBeltSubtitleTextblock | Class | Text block that displays engine subtitles; style it like any text block. |
| UMultiSubtitleVerticalbox | Class | Vertical box showing several recent subtitle lines (Concurrent Lines, Maximum Age, font and colour options). |
Gameplay helpers
| Node | Type | Description |
|---|---|---|
| UBeltPooledActorSystem | Class | World subsystem for actor pooling. Pooled actors are hidden, have physics disabled and are moved to Storage Location. |
| Get | Callable | Static: get the pooled actor system for a world context. |
| Get Pooled Actor | Callable | Re-use or spawn an actor of a class at a location; reports whether it was re-used. |
| Release Pooled Actor | Callable | Return an actor to the pool instead of destroying it. |
| Add Actor To Pool | Callable | Add an externally created actor to the pool. |
| Pre Warm Actor Pool | Callable | Pre-create a number of actors. |
| Drain Actor Pool | Callable | Destroy surplus actors of one class. |
| Drain All Actor Pools | Callable | Destroy all pooled actors. |
| IBeltPooledActor | Class | Optional interface for pooled actors. |
| Deactivate On Added To Pool | Event | Interface event: the actor entered the pool. |
| Reactivate On Removed From Pool | Event | Interface event: the actor is being re-used. |
| UBeltLightFlickerComponent | Class | Generates a flicker value from a pattern (built-in candle, torch, strobe, pulse and flicker patterns, or a custom a–z string, 0.1 s per character). Replicates its time position. Properties: Flicker Pattern, Custom Flicker Pattern, Max Value, Min Value, Speed, Auto Play. |
| Play | Callable | Start (optionally resetting time). |
| Pause | Callable | Stop ticking. |
| Get Current Value | Pure | Latest output value. |
| Set Flicker Pattern | Callable | Change pattern (and custom string) at runtime. |
| Get Flicker Pattern | Pure | Current pattern and custom string. |
| On Light Flicker Update | Event | New light value each tick — feed it into light intensity or a material parameter. |
| Evaluate Light Curve | Pure | Sample a built-in pattern at a time without a component. |
| UBeltSpringArmComponent | Class | Spring arm with smooth collision avoidance (Enable Smooth Collision Avoidance, Smooth Collision Avoidance Speed) that also interpolates when the collision test is off. |
| Set Target Offset Smooth | Callable | Interpolate the target offset. |
| Cancel Target Offset Smooth | Callable | Stop a target-offset interpolation. |
| Set Socket Offset Smooth | Callable | Interpolate the socket offset. |
| Cancel Socket Offset Smooth | Callable | Stop a socket-offset interpolation. |
| Jump To Desired Location | Callable | Snap the camera to its desired position immediately. |
| ABeltDynamicNavMeshVolume | Class | NavMesh bounds volume that can move/resize at runtime (NavMesh Runtime Generation must be Dynamic). |
| Set Location And Dimensions | Callable | Move and resize the volume, then update navigation. |
| Set Dimensions | Callable | Resize the volume, then update navigation. |
| ABeltReplicatedPhysicsActor | Class | Static mesh actor simulated on the server and replicated smoothly to clients. Spawn it on the server only. |
C++ only: FBeltTextureRenderTargetPool (obtained with UBeltGameSubsystem::GetTextureRenderTargetPool) reserves and reuses render targets by size and format; UBeltAssetHelpers finds Blueprint classes under content paths with an object library.
Maths, easing & random
| Node | Type | Description |
|---|---|---|
| Ease Alpha | Callable | Apply an EBeltEaseFunction (sine, quad, cubic, quart, quint, expo, circ, back, elastic, bounce; in/out/in-out) to a 0–1 alpha. |
| Ease Float | Callable | Eased interpolation between two floats. |
| Ease Vector | Callable | Eased interpolation between vectors. |
| Ease Rotator | Callable | Eased interpolation between rotators (optionally shortest path). |
| Ease Quat | Callable | Eased slerp between quaternions. |
| Ease Transform | Callable | Eased interpolation of rotation, location and scale. |
| Sphere Overlap Cone | Callable | Whether a sphere overlaps a cone (angle in degrees). |
| Heading Angle 2D | Pure | Heading of a 2D direction in radians (0 along +X). |
| Angle Between 2D | Pure | Signed angle between two 2D directions in radians. |
| Get Perceived Luminance | Callable | Perceived luminance of a colour (ITU BT.709). |
| Get Perceived Luminance 2 | Callable | Perceived luminance of a colour (ITU BT.601). |
| Set Widget Focus | Callable | Focus a widget through Set Focus Properly when it is a focusable user widget. |
| Insert Child Widget At | Callable | Insert a child into a panel at an index at runtime (keeps horizontal/vertical box padding). |
| Find Closest Widget In Input Direction | Callable | Find the nearest child of a panel in any 2D direction (for analogue-stick navigation). |
| Add View Origin To Streaming | Callable | Tell texture streaming about an extra view point (e.g. a scene capture). |
| Update Streaming | Callable | Force a streaming update, optionally blocking until done. |
| Get Project Version | Pure | Project Version string from the project settings. |
| Make Balanced Random Stream | Pure | Create a seeded FBeltBalancedRandomStream (Halton sequence — more even than ordinary random numbers). |
| Balanced Random | Callable | Next value 0–1. |
| Balanced Random 2D | Callable | Next 2D value. |
| Balanced Random 3D | Callable | Next 3D value. |
| Balanced Random Vector | Callable | Next unit vector. |
| Balanced Random Point In Box | Callable | Next point inside a box. |
| UBeltIndexShuffleBag | Class | Draws array indices without repeats until the bag is empty. |
| Make Index Shuffle Bag | Callable | Create a bag for N indices with a seed. |
| Reinitialise | Callable | Reset the bag with a new size and seed. |
| Next | Callable | Pull the next index (refills when empty). |
| Reset | Callable | Return all pulled indices to the bag. |
| Get Num Remaining | Pure | Indices left in the bag. |
| Get Num Pulled | Pure | Indices already pulled. |
| Get Num Total | Pure | Bag size. |
C++ extras: BeltMathHelpers (OverlapConvex, GetDistanceToConvex2D, IsPointInTriangle2D, Fill2DRegionWithRectangles, ProjectConvex2D, OverlapConvex2D), FBeltBalancedRandomStream1D / 2D / 3D, and the template FBeltShuffleBag<T>.
Debug & editor helpers
| Node | Type | Description |
|---|---|---|
| UBeltEditorVisComponent | Class | "UtilityBelt Editor Visualisation" component: arrays of Lines, Arrows, Circles, Arcs, Spheres, Boxes, Cylinders, Capsules and Meshes drawn in the editor even when the actor is not selected. Editor-only, hidden in game. |
| FBeltFixedDataTableRowHandle | Class | Data-table row handle whose table is fixed by meta=(DataTable="/Game/..."); the Details panel shows only a row picker and a browse button. |
| FBeltDebugRenderSceneProxy | Class | C++ debug scene proxy with circles, arcs, transformed cylinders/capsules and wireframe meshes. |
| FBeltVisualLogger | Class | C++ Visual Logger shapes via UE_VLOG_TRIANGLE, UE_VLOG_SQUARE, UE_VLOG_POLY, UE_VLOG_STAR (and _THICK / UE_CVLOG_ variants). |
#include "BeltFixedDataTableRowHandle.h"
#include "BeltLogHelpers.h"
UPROPERTY(EditAnywhere, meta=(DataTable="/Game/Data/DT_Items"))
FBeltFixedDataTableRowHandle Item;
BELT_LOG_ONCE(LogTemp, Warning, TEXT("Shown once per session"));
Troubleshooting
| Symptom | Cause and fix |
|---|---|
| Input Image / rich-text prompts are blank | No UI theme is configured or the Data Tables have no row for the key. Set DefaultUiThemePath in DefaultGame.ini, restart the editor, and make sure the row names match key names (e.g. Gamepad_FaceButton_Bottom). |
| Prompts work in the editor but not in a packaged build | The theme is loaded from code, so it is not cooked automatically. Add it as a primary asset in the Asset Manager or reference it from a Primary Asset Label. |
| The mouse cursor reappears while using a gamepad | Set Game Viewport Client Class to BeltGameViewportClientBase and keep Hide Mouse When Gamepad Used enabled. |
| A dotted outline appears around focused buttons | Set Project Settings > User Interface > Render Focus Rule to Never; the focusable widgets use their Hovered style instead. |
<input eaction="..."/> shows nothing | The action is looked up by name in Directories to search for Enhanced Input Actions; add the folder that contains the Input Action asset. |
| Menu levels do not appear inside the stack | The Menu Stack Blueprint needs a Named Slot (or other content widget) called MenuContainer, and Embed In Parent Container must be enabled on the level. |
| Dynamic NavMesh volume changes have no effect | Set the RecastNavMesh Runtime Generation to Dynamic in Project Settings > Navigation Mesh. |
Credits
© 2026 Alpha XP — alphaxp.net · Support: support@alphaxp.net. Built and verified for Unreal Engine 5.8.