Plugin Documentation

UtilityBelt
Gameplay and UI helpers that every project ends up writing

Input-method detection, gamepad-friendly focusable widgets and menus, live input prompts, typewriter text, easing, maths, balanced randomisation, actor pooling, light flicker, a smoother spring arm and editor visualisation — in one Blueprint and C++ library.

v1.0
UE 5.8
Win64 (verified) · Linux, Mac
Category Code Utilities
Alpha XP

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

RequirementDetails
Unreal Engine5.8 (verified clean)
ModulesUtilityBelt (Runtime), UtilityBeltTypewriter (Runtime, typewriter text widget), UtilityBeltEditor (Editor)
DependenciesEngine plugins Enhanced Input and Paper2D (enabled automatically with UtilityBelt)
LanguageBlueprints and C++
PlatformsWin64, 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

  1. Install UtilityBelt from the launcher into your engine, or copy the UtilityBelt folder into your project's Plugins folder.
  2. For a C++ project, regenerate project files and build the editor target.
  3. Open the project, go to Edit > Plugins, enable UtilityBelt and restart the editor. Enhanced Input and Paper2D are enabled with it.
  4. 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 uses UTypewriterTextWidget (Blueprints need nothing extra).
Verifying the installIn any Blueprint graph, right-click and search for Get Last Input Mode Used (under Belt Game Subsystem). In the UMG palette you should see Focusable Button, Input Image and the other UtilityBelt widgets.

Quick start

Blueprint: react to the player's input method

  1. In a widget or actor Blueprint, add the Belt Game Subsystem node (Game Instance Subsystem getter).
  2. Drag off it and bind to On Input Mode Changed; the event gives you the player index and the new EInputMode (Mouse, Keyboard, Gamepad).
  3. Query the current state at any time with Get Last Input Mode Used or Last Input Was Game Pad.
  4. 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)DefaultDescription
bHideMouseWhenGamepadUsed (Hide Mouse When Gamepad Used)trueMoves the pointer off-screen and hides it when the player switches to a gamepad.
EnhancedInputActionSearchDirectories (Directories to search for Enhanced Input Actions)emptyContent 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.

NodeTypeDescription
Get Last Input Mode UsedCallableDevice (Mouse / Keyboard / Gamepad) of the most recent input of any kind for a player index.
Get Last Input Button PressedCallableDevice of the most recent button or key press (ignores axis movement).
Get Last Input Axis MovedCallableDevice of the most recent axis movement (ignores button presses).
Last Input Was Game PadCallableTrue when the last input of any kind came from a gamepad.
Get Input Image SpriteCallablePaper2D sprite for an action, axis or explicit key, using the device preference and an optional theme.
Register Interest In Enhanced Input ActionCallableBind an Enhanced Input action/trigger so that On Enhanced Input Action Triggered fires for it (useful from UI).
Unregister All Interest In Enhanced Input ActionsCallableRemove every binding made with the node above (e.g. after loading a new level).
Notify Enhanced Input Mappings ChangedCallableLegacy: re-broadcasts On Enhanced Input Mappings Changed after a short delay. No longer required.
Move Mouse Off ScreenCallableParks (and optionally hides) the pointer so it cannot trigger hovers during gamepad navigation.
On Input Mode ChangedEventPlayer index and new main input mode.
On Button Input Mode ChangedEventRaised when the device of the last button press changes.
On Axis Input Mode ChangedEventRaised when the device of the last axis movement changes.
On Enhanced Input Action TriggeredEventAction and trigger event for actions registered with Register Interest In Enhanced Input Action.
On Enhanced Input Mappings ChangedEventLegacy event raised by Notify Enhanced Input Mappings Changed.
On Window Foreground ChangedEventThe game window gained or lost the foreground.
On Viewport ResizedEventNew viewport width and height (also raised on fullscreen toggle).
UBeltGameViewportClientBaseClassGame 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).

NodeTypeDescription
UUiThemeClassData asset holding the keyboard/mouse and gamepad sprite tables.
FKeySpriteClassData Table row: Key and Sprite. Row names are key names (e.g. Gamepad_FaceButton_Bottom).
UInputImageClassImage 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 ActionCallableShow the binding of a legacy input action.
Set From AxisCallableShow the binding of a legacy input axis.
Set From KeyCallableShow a specific key, button or axis.
Set From Input ActionCallableShow the binding of an Enhanced Input action.
Get Binding TypeCallableCurrent binding type.
Get Action Or Axis NameCallableAction/axis name used for lookup.
Get KeyCallableExplicit key used when Binding Type is Key.
URichTextBlockInputImageDecoratorClassRich Text decorator: add it to a Rich Text Block's decorator classes to use the <input/> tag below.
MarkupShows
<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.

NodeTypeDescription
UFocusableButtonClassButton with focus events and focus styling.
Simulate PressCallablePress the button visually and logically (as if Accept was pressed).
Simulate ReleaseCallableRelease a simulated press.
Refresh Focussed StyleCallableRebuild the focus style after changing the widget style at runtime (button, check box and slider; overridable).
On Focus ReceivedEventThe widget gained focus (button, check box, slider).
On Focus LostEventThe widget lost focus (button, check box, slider).
UFocusableCheckBoxClassCheck box with focus styling, gamepad navigation and hover/focus events.
UFocusableSliderClassSlider with focus styling and hover/focus events.
On HoveredEventMouse entered (check box, slider).
On UnhoveredEventMouse left (check box, slider).
UFocusableUserWidgetClassUser widget base with optional automatic focus by priority (Enable Automatic Focus, Automatic Focus Priority).
Set Focus ProperlyCallableOverridable focus entry point (the engine's SetFocus is not virtual).
Is Requesting FocusCallableOverridable: whether this widget currently wants focus.
Take Focus If DesiredCallableOverridable: take focus if requesting it.
UFocusablePanelClassFocusable user widget that delegates focus to a child (Initial Focus Widget Name) and can remember the last focused child.
Set Focus To Initial WidgetCallableFocus the initial child.
Get Initial Focus WidgetEventOverridable: supply the initial focus child dynamically.
Set Initial Focus WidgetCallableSet the initial focus child at runtime.
Save Previous FocusCallableRemember the currently focused child.
Restore Previous FocusCallableRe-focus the remembered child.
UFocusableInputInterceptorUserWidgetClassFocusable 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.

NodeTypeDescription
Clear OptionsCallableRemove all options.
Add OptionCallableAppend an option; returns its index.
Set OptionsCallableReplace all options and choose the selected index.
Get Selected IndexPureSelected index.
Get Selected OptionPureSelected option text.
Set Selected IndexCallableSelect an option by index.
Change OptionCallableMove the selection by a delta (use from custom navigation).
Set Mouse ModeCallableShow the mouse version.
Set Button ModeCallableShow the gamepad/keyboard version.
Update From Input ModeCallableSwitch version for a given input mode.
Get Current Input ModeCallableInput mode the widget is displaying for.
Post Selected Option ChangedEventOverridable hook after the selection changes.
On Selected Option ChangedEventThe player changed the selection.
UNamedOptionWidgetBaseClassOption widget addressed by FName keys (populated from code/graphs).
Add Named OptionCallableAppend an option with a name.
Set Named OptionsCallableReplace all options from a name-to-text map.
Get Selected NamePureName of the selected option.
Get Index For NameCallableIndex of a named option.
Get Name For IndexCallableName of the option at an index.
Set Selected NameCallableSelect by name.
UTabListWidgetClassTab bar that drives a Widget Switcher; needs a panel named TabButtonContainer. Previous/next tab keys default to the gamepad shoulders and Q/E.
Register TabCallableAdd a tab: id, button class, label and content widget.
Set Target Widget SwitcherCallableWidget Switcher controlled by the tabs.
Increment Tab IndexCallableMove the selection by an amount.
Select TabCallableSelect a tab by index.
On Content Widget ChangedEventPrevious and new content widget.
UTabButtonClassBase class for tab buttons created by the tab list.
Set Tab LabelEventOverridable: display the label.
Set Tab SelectedCallableMark the tab selected/unselected.
Notify Tab SelectedCallableCall from your button's click to select this tab.
Refresh For Selection ChangedEventOverridable: update visuals for the selection state.
On Tab SelectedEventTab 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.

NodeTypeDescription
Play LineCallableStart typing a line at a speed multiplier.
Skip To Line EndCallableShow the rest of the current line immediately.
Has Finished Playing LineCallableWhether the whole line has been shown.
Has More Line PartsCallableTrue when Max Number Of Lines split the line and parts remain.
Play Next Line PartCallablePlay the next part of a split line.
Get Current LineCallableLine currently being played.
Set TextCallableSet text immediately without the effect.
Get TextCallableCurrent text.
Get Play SpeedCallableCurrent speed multiplier.
Set Play SpeedCallableChange the speed multiplier while playing.
Find Word VowelsCallablePositions of the vowels in a word (e.g. for lip-flap or voice blips).
On Play LetterEventImplementable: one or more letters were added.
On Line Finished PlayingEventImplementable: the line finished.
On Typewriter Line FinishedEventThe line finished playing or was skipped.
On Typewriter Letter AddedEventNew letters shown.
On Typewriter Start WordEventA new word started (when New Word Event is enabled).
On Typewriter Run Name ChangedEventThe rich-text style run changed.
USmoothChangingProgressBarClassProgress bar that animates to its target (Percent Change Speed, Percent Change Frequency).
Set Percent SmoothlyCallableAnimate to a new percentage.
Stop Smooth Percent ChangeCallableStop the animation (call before a plain Set Percent).
UBeltSubtitleTextblockClassText block that displays engine subtitles; style it like any text block.
UMultiSubtitleVerticalboxClassVertical box showing several recent subtitle lines (Concurrent Lines, Maximum Age, font and colour options).

Gameplay helpers

NodeTypeDescription
UBeltPooledActorSystemClassWorld subsystem for actor pooling. Pooled actors are hidden, have physics disabled and are moved to Storage Location.
GetCallableStatic: get the pooled actor system for a world context.
Get Pooled ActorCallableRe-use or spawn an actor of a class at a location; reports whether it was re-used.
Release Pooled ActorCallableReturn an actor to the pool instead of destroying it.
Add Actor To PoolCallableAdd an externally created actor to the pool.
Pre Warm Actor PoolCallablePre-create a number of actors.
Drain Actor PoolCallableDestroy surplus actors of one class.
Drain All Actor PoolsCallableDestroy all pooled actors.
IBeltPooledActorClassOptional interface for pooled actors.
Deactivate On Added To PoolEventInterface event: the actor entered the pool.
Reactivate On Removed From PoolEventInterface event: the actor is being re-used.
UBeltLightFlickerComponentClassGenerates 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.
PlayCallableStart (optionally resetting time).
PauseCallableStop ticking.
Get Current ValuePureLatest output value.
Set Flicker PatternCallableChange pattern (and custom string) at runtime.
Get Flicker PatternPureCurrent pattern and custom string.
On Light Flicker UpdateEventNew light value each tick — feed it into light intensity or a material parameter.
Evaluate Light CurvePureSample a built-in pattern at a time without a component.
UBeltSpringArmComponentClassSpring 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 SmoothCallableInterpolate the target offset.
Cancel Target Offset SmoothCallableStop a target-offset interpolation.
Set Socket Offset SmoothCallableInterpolate the socket offset.
Cancel Socket Offset SmoothCallableStop a socket-offset interpolation.
Jump To Desired LocationCallableSnap the camera to its desired position immediately.
ABeltDynamicNavMeshVolumeClassNavMesh bounds volume that can move/resize at runtime (NavMesh Runtime Generation must be Dynamic).
Set Location And DimensionsCallableMove and resize the volume, then update navigation.
Set DimensionsCallableResize the volume, then update navigation.
ABeltReplicatedPhysicsActorClassStatic 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

NodeTypeDescription
Ease AlphaCallableApply an EBeltEaseFunction (sine, quad, cubic, quart, quint, expo, circ, back, elastic, bounce; in/out/in-out) to a 0–1 alpha.
Ease FloatCallableEased interpolation between two floats.
Ease VectorCallableEased interpolation between vectors.
Ease RotatorCallableEased interpolation between rotators (optionally shortest path).
Ease QuatCallableEased slerp between quaternions.
Ease TransformCallableEased interpolation of rotation, location and scale.
Sphere Overlap ConeCallableWhether a sphere overlaps a cone (angle in degrees).
Heading Angle 2DPureHeading of a 2D direction in radians (0 along +X).
Angle Between 2DPureSigned angle between two 2D directions in radians.
Get Perceived LuminanceCallablePerceived luminance of a colour (ITU BT.709).
Get Perceived Luminance 2CallablePerceived luminance of a colour (ITU BT.601).
Set Widget FocusCallableFocus a widget through Set Focus Properly when it is a focusable user widget.
Insert Child Widget AtCallableInsert a child into a panel at an index at runtime (keeps horizontal/vertical box padding).
Find Closest Widget In Input DirectionCallableFind the nearest child of a panel in any 2D direction (for analogue-stick navigation).
Add View Origin To StreamingCallableTell texture streaming about an extra view point (e.g. a scene capture).
Update StreamingCallableForce a streaming update, optionally blocking until done.
Get Project VersionPureProject Version string from the project settings.
Make Balanced Random StreamPureCreate a seeded FBeltBalancedRandomStream (Halton sequence — more even than ordinary random numbers).
Balanced RandomCallableNext value 0–1.
Balanced Random 2DCallableNext 2D value.
Balanced Random 3DCallableNext 3D value.
Balanced Random VectorCallableNext unit vector.
Balanced Random Point In BoxCallableNext point inside a box.
UBeltIndexShuffleBagClassDraws array indices without repeats until the bag is empty.
Make Index Shuffle BagCallableCreate a bag for N indices with a seed.
ReinitialiseCallableReset the bag with a new size and seed.
NextCallablePull the next index (refills when empty).
ResetCallableReturn all pulled indices to the bag.
Get Num RemainingPureIndices left in the bag.
Get Num PulledPureIndices already pulled.
Get Num TotalPureBag size.

C++ extras: BeltMathHelpers (OverlapConvex, GetDistanceToConvex2D, IsPointInTriangle2D, Fill2DRegionWithRectangles, ProjectConvex2D, OverlapConvex2D), FBeltBalancedRandomStream1D / 2D / 3D, and the template FBeltShuffleBag<T>.

Debug & editor helpers

NodeTypeDescription
UBeltEditorVisComponentClass"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.
FBeltFixedDataTableRowHandleClassData-table row handle whose table is fixed by meta=(DataTable="/Game/..."); the Details panel shows only a row picker and a browse button.
FBeltDebugRenderSceneProxyClassC++ debug scene proxy with circles, arcs, transformed cylinders/capsules and wireframe meshes.
FBeltVisualLoggerClassC++ 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

SymptomCause and fix
Input Image / rich-text prompts are blankNo 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 buildThe 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 gamepadSet Game Viewport Client Class to BeltGameViewportClientBase and keep Hide Mouse When Gamepad Used enabled.
A dotted outline appears around focused buttonsSet Project Settings > User Interface > Render Focus Rule to Never; the focusable widgets use their Hovered style instead.
<input eaction="..."/> shows nothingThe 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 stackThe 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 effectSet 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.