WBP Anim State Machine User Guide
WBP Anim State Machine User Guide
Section titled “WBP Anim State Machine User Guide”This guide walks through using the WbpAnimStateMachine module as a widget author.
The goal is simple:
- create a widget with named animations
- define states and transitions in a data asset
- create the machine in the widget
- drive transitions from Blueprint, input, tracks, or Sequencer
- debug the result in PIE
What You Are Building
Section titled “What You Are Building”The same workflow works for:
- buttons
- panels and modals
- toasts
- tabs
- loading screens
- menu screens
- nested composite widgets
Before You Start
Section titled “Before You Start”You need:
- a widget blueprint
- one or more UMG animations in that widget
- the
WbpAnimStateMachinemodule enabled
Best practice:
- keep state names and animation names aligned when possible
Example:
- state
Hover - animation
Hover
The Core Idea
Section titled “The Core Idea”The workflow has three pieces:
- Widget blueprint
- contains the real UMG animations
- Definition asset
- describes states, transitions, rules, notes, graph layout, and input bindings
- Runtime machine
- created inside the widget and asked to move between states
Quick Start With a Preset
Section titled “Quick Start With a Preset”1. Create a definition asset
Section titled “1. Create a definition asset”In the Content Browser:
- Right-click
- Choose
Miscellaneous - Choose
Data Asset - Select
WbpAnimStateMachineDefinition - Name it something like
DA_ButtonAnimStateMachine
2. Open the asset
Section titled “2. Open the asset”The dedicated asset editor gives you:
- a graph tab
- a details tab
- a debugger tab
3. Set OwnerWidgetClass
Section titled “3. Set OwnerWidgetClass”Set OwnerWidgetClass to the widget blueprint that will use this definition.
This enables:
- animation dropdowns
- entry/exit/condition function dropdowns
- better validation
4. Pick a preset
Section titled “4. Pick a preset”Set PresetToApply and click Apply Preset.
Good starting presets:
ButtonToggleButtonPanelToastTabLoadingScreenCarousel
This fills in:
InitialStateStatesTransitions
Matching Animations in the Widget
Section titled “Matching Animations in the Widget”The state machine does not create animations. Your widget blueprint still owns them.
If your definition includes:
IdleHoverPressedFocusedDisabled
then the widget should contain matching animations or intentionally remapped AnimationName values.
Understanding States
Section titled “Understanding States”Each state gives you the behavior for one named UI mode.
Common settings:
StateNameAnimationNamePlayModePlaybackRateStartTimebRestoreStateReEnterPolicyInterruptPriorityGroupStateTagsDesignerNotesCurveAtlasDurationCurveAtlasBindings
Re-entry behavior
Section titled “Re-entry behavior”ReEnterPolicy controls what happens when the machine is already in the target state:
IgnoreRestartAnimationFire Events
Auto-transition
Section titled “Auto-transition”You can move to another state automatically after a delay:
AutoTransitionDelayAutoTransitionState
Common use:
Visiblefor 3 seconds- then move to
Dismiss
Entry and exit functions
Section titled “Entry and exit functions”States can call widget functions on enter and exit:
EntryFunctionNameExitFunctionName
Use this for:
- playing sounds
- toggling visibility
- starting helper effects
- updating related widget state
Per-state graph color
Section titled “Per-state graph color”EditorNodeColor is editor-only and lets you color important states in the graph without affecting runtime behavior.
Use it to make:
- danger/error states obvious
- accessibility states grouped visually
- parent vs child states easier to scan
Curve Atlas timed sequences
Section titled “Curve Atlas timed sequences”If a state only needs simple timed property motion, you can use a Curve Atlas sequence instead of authoring a full UMG animation timeline. Set CurveAtlasDuration, then add CurveAtlasBindings for the widgets and properties you want to drive.
Each binding samples a UCurveLinearColor row over the state’s normalized playback time. RGBA values can drive opacity, render transform values, common widget tint/color properties, or a visibility threshold. Leave WidgetName empty to target the owning widget itself.
These sequences use the state’s PlayMode and PlaybackRate. PlayOnce and Reverse curve-only states can still advance through OnAnimationFinished transitions when the sequence completes. Loop and PingPong keep running until the state changes.
Understanding Transitions
Section titled “Understanding Transitions”Transitions describe allowed moves between states.
Manual transitions
Section titled “Manual transitions”These happen only when you explicitly call GoToState.
Example:
Idle -> HoverHover -> Pressed
On-finished transitions
Section titled “On-finished transitions”These happen when the current animation finishes.
Example:
Intro -> IdlePressed -> HoverOutro -> Hidden
Wildcard transitions
Section titled “Wildcard transitions”If FromState is None, the transition can match from any current state.
Use this for:
Any -> DisabledAny -> Focused
Transition settings
Section titled “Transition settings”Useful fields:
TriggerBlendTimeConditionFunctionNameRulesRuleMatchModeTransitionTagDesignerNotesbEnableBreakpoint
TransitionGuard exists for C++ integrations only. If you are working in Blueprint, use ConditionFunctionName or built-in transition Rules for guard logic.
Using Built-In Rules
Section titled “Using Built-In Rules”Rules let you gate transitions without needing a custom widget function every time.
Supported rule sources include:
- blackboard float
- blackboard bool
- blackboard name
- blackboard int
- blackboard string
- time in state
- animation progress
- current state
- previous state
Good uses:
- only allow dismiss after
CanDismiss == true - only allow next state after progress >
0.8 - only allow exit from one prior state
Using the Blackboard
Section titled “Using the Blackboard”The blackboard is a lightweight per-machine data store.
Supported types:
floatboolFNameint32FStringUObject*
Typical keys:
HasUnreadSelectedTabCanDismissInputSourceCurrentPage
From Blueprint you can use:
SetBlackboardFloatSetBlackboardBoolSetBlackboardNameSetBlackboardIntSetBlackboardStringSetBlackboardObject
and the matching getters.
Creating the Runtime Machine in Your Widget
Section titled “Creating the Runtime Machine in Your Widget”Typical Blueprint path:
- Add a variable of type
WbpAnimStateMachine - On widget construct or initialize:
- call
CreateAndInitializeStateMachine - store the result
Typical C++ path:
StateMachine = UWbpAnimStateMachine::CreateStateMachine(this, DefinitionAsset);Driving Transitions From Blueprint
Section titled “Driving Transitions From Blueprint”Most common nodes:
Go To WBP StateGo To WBP State And WaitGoToStateGoBackCanTransitionToGetAvailableTransitionsGetCurrentStateIsInState
Preferred authored transition node
Section titled “Preferred authored transition node”In editor builds, the best default node is Go To WBP State.
Why it is better than a plain GoToState call:
- it still performs a normal runtime transition
- but it adds an optional
State Definitionpin - when a definition is available, the
Statepin becomes a dropdown of valid authored state names - the custom nodes appear under
UI Foundry|State Machinein the Blueprint action menu
Best practice:
- Create your machine from a definition asset
- Use
Go To WBP Statefor most direct transitions - Set
State Definitionexplicitly when the node cannot infer it from the machine creation path
The editor pin factory also upgrades standard Blueprint-library GoToState and GoToStateAndWait nodes when the definition can be inferred, but the custom node is the clearest workflow for designers and technical artists.
There is now also a matching Go To WBP State And Wait custom node, which keeps the same authored-state dropdown while using the latent wait behavior.
Linear Blueprint flow with latent waiting
Section titled “Linear Blueprint flow with latent waiting”Use GoToStateAndWait when you want a clean sequential Blueprint flow.
Example pattern:
GoToStateAndWait(Intro)- continue only after
Introhas actually been entered GoToState(Idle)
This is much cleaner than wiring temporary delegate listeners for simple scripted flows.
Finding Machines Later
Section titled “Finding Machines Later”If your widget already created a machine and another Blueprint needs to find it later, use:
FindMachineByDefinition(Widget, Definition)
This is useful when:
- UI controller logic does not already store the machine pointer
- game code wants to drive a specific widget machine indirectly
Using Full Snapshots for Save/Load
Section titled “Using Full Snapshots for Save/Load”There are two save paths:
-
SaveState/RestoreState -
stores only the current state name
-
SaveMachineSnapshot/RestoreMachineSnapshot -
stores current state plus the full blackboard
Use full snapshots when the UI has real authored context, not just a single active state.
Example:
- a crafting panel with tabs, sort choice, selection, and mode flags
Using Parallel Tracks
Section titled “Using Parallel Tracks”If one widget needs multiple independent animation layers, use a UWbpAnimStateMachineGroup.
Good examples:
- base panel flow on one track
- hover/focus feedback on a second track
- attention pulse on a third track
Blueprint helpers:
CreateStateMachineGroupAddTrackGetTrackGetTrackNamesGoToStateOnTrackTickGroupStopAllTracks
Using Sub-State Machines
Section titled “Using Sub-State Machines”A state can host a nested child definition through:
SubMachineDefinitionSubMachineMode
This is ideal when one parent state has its own internal behavior.
Example:
- parent state
Searching - child machine states
Pulse,Spin,Found
Useful modes:
EnterAndRunConcurrentlyEnterAndPauseParentEnterAndWaitForExit
Enhanced Input Integration
Section titled “Enhanced Input Integration”You can author input-driven transitions directly on the definition using InputBindings.
Each input binding gives you:
InputActionTriggerEventTargetStatebForceCallerPriority
At runtime the machine looks for an UEnhancedInputComponent on the owning player’s controller and binds those actions automatically during Initialize().
States can also manage mapping contexts directly:
EntryInputContextEntryInputContextPriorityExitInputContext
The easiest pattern is:
- Set
EntryInputContext = IMC_WidgetFocus - Set
ExitInputContext = IMC_WidgetFocus
That makes the state add the focus mapping context when it becomes active and remove it when the state ends.
Good uses:
- confirm and cancel on controller
- gamepad menu states
- tab navigation
- focused or modal states that should temporarily swap input behavior
You can also add bindings manually in Blueprint with:
AddInputBinding
Focus-Aware State Changes
Section titled “Focus-Aware State Changes”If your widget should react to focus without custom Blueprint glue, enable focus-aware transitions on the definition:
- enable
bEnableFocusAwareTransitions - set
FocusGainedState - set
FocusLostState
Then, while MachineTick is running, the machine will watch the widget’s focus state and request those transitions automatically.
This is a good fit for:
- gamepad-focus button widgets
- accessibility-focused menu items
- widgets that should visually elevate when they become the active focus target
Starter example:
examples/WbpAnimStateMachine/EX_FocusAwareButton.json
View-Model / Blackboard Sync
Section titled “View-Model / Blackboard Sync”If your widget stores a UObject view-model, you can bind reflected fields directly into the state machine blackboard.
Definition fields:
WidgetViewModelPropertyViewModelFieldBlackboardKeyDirection
What this gives you:
- transition rules can react to view-model values without manual setter glue
- blackboard-driven flows can push values back into the view-model when desired
- the widget and machine stay synchronized while
MachineTickruns
Reference recipe:
examples/WbpAnimStateMachine/EX_ViewModelBoundPanel.md
CommonUI Integration
Section titled “CommonUI Integration”If your project uses the CommonUI plugin, UWbpAnimCommonActivatableMixin lets you drive state machine transitions from the CommonUI activation lifecycle without a hard plugin dependency.
Blueprint setup
Section titled “Blueprint setup”- In
NativeConstructorConstruct, callBindActivationEvents(Self, StateMachine, "Active", "Inactive"). - In the widget’s
OnWidgetActivatedevent, callNotifyActivated(Self). - In
OnWidgetDeactivated, callNotifyDeactivated(Self).
C++ setup (on a UCommonActivatableWidget subclass)
Section titled “C++ setup (on a UCommonActivatableWidget subclass)”// NativeConstructUWbpAnimCommonActivatableMixin::BindActivationEvents(this, MyMachine, TEXT("Active"), TEXT("Inactive"));
// NativeOnActivatedSuper::NativeOnActivated();UWbpAnimCommonActivatableMixin::NotifyActivated(this);
// NativeOnDeactivatedSuper::NativeOnDeactivated();UWbpAnimCommonActivatableMixin::NotifyDeactivated(this);- If the widget is not a
UCommonActivatableWidgetsubclass,BindActivationEventsreturns false and logs a warning. Nothing crashes. - Stale entries for destroyed widgets are cleaned up automatically.
- To stop bridging, call
UnbindActivationEvents(Self).
GAS Event Bindings
Section titled “GAS Event Bindings”If your project uses Gameplay Ability System, you can route ability event tags directly into state machine transitions without writing manual GoToState calls in every ability.
Setting up bindings
Section titled “Setting up bindings”In the definition asset: Add entries to the GAS Events array. Each entry has:
| Field | Purpose |
|---|---|
| Event Tag | The FGameplayTag that triggers this binding |
| Target State | State to enter when the tag fires |
| Force | If checked, requests GoToState in force mode and bypasses the transition table |
| Caller Priority | Priority used when Force is checked; it must meet or exceed the current state’s InterruptPriority |
Inline (C++ only): Call AddGasEventBinding(Tag, StateName) before Initialize().
Forwarding events at runtime
Section titled “Forwarding events at runtime”The machine does not subscribe to UAbilitySystemComponent automatically — you forward events with one call:
Blueprint:
- Subscribe to whatever GAS event you care about (e.g. from an
UGameplayAbilityor a tag listener) - Get your state machine reference
- Call Handle Gameplay Event and pass the tag
C++:
// Example: inside your widget's NativeConstructUAbilitySystemComponent* ASC = GetOwningPlayerState<AMyPlayerState>()->GetAbilitySystemComponent();ASC->AddGameplayEventTagContainerDelegate( FGameplayTagContainer(MyTag), FGameplayEventTagMulticastDelegate::FDelegate::CreateWeakLambda(this, [this](FGameplayTag Tag, const FGameplayEventData*) { if (StateMachine) StateMachine->HandleGameplayEvent(Tag); }));Tag matching
Section titled “Tag matching”HandleGameplayEvent uses FGameplayTag::MatchesTag. A binding for Gameplay.Damage will fire when Gameplay.Damage.Fire or Gameplay.Damage.Ice comes in. Use an exact tag in the binding to restrict to a single event type.
- No hard dependency on the
GameplayAbilitiesplugin is added.FGameplayTagis fromGameplayTags, which is already a module dependency. HandleGameplayEventreturns anint32— the number of bindings that successfully triggered aGoToState. Zero means no match or the machine is not initialized.- If multiple bindings match the same incoming tag, they are evaluated in declaration order. Each call runs from the state left by the previous successful binding, so later bindings can succeed or be blocked by the transition table from that new state.
- Force bypasses the transition table, but not interrupt protection. If the current state has a higher
InterruptPrioritythan the binding’sCallerPriority, the forced transition is rejected. - Validation checks that all
TargetStatevalues exist and allEventTagvalues are valid. Errors appear when you press Validate State Machine in the definition asset.
Sequencer Workflow
Section titled “Sequencer Workflow”The module includes a custom Sequencer track path for discrete state transitions.
Current authoring flow:
- Bind your widget object in Sequencer
- Add a
WBP Anim Statetrack - Add sections for target states
- Configure:
TargetState- machine property name
- or machine-group property plus track name
- optional force/priority
Blueprint/editor-script helpers also exist:
AddSequencerStateTrackAddSequencerStateSection
This is ideal for:
- menu reveals
- title-card sequences
- scripted onboarding or splash flows
Graph Editor Basics
Section titled “Graph Editor Basics”The graph is the main authoring surface for most users.
You can:
- drag states around
- pan and zoom
- search states
- use the minimap
- frame all
- select multiple nodes
- align and distribute nodes
- duplicate or copy/paste states
- use group boxes
- add sticky notes
- add standard graph comments
- delete selected states or comments with
DeleteorBackspace - auto-arrange the graph with
Compact,Flow,Wide, orSelectedlayout modes
Creating transitions
Section titled “Creating transitions”You can drag from any node edge to another state to create a transition.
This is much more discoverable than an invisible single-side hotspot and is the intended everyday workflow.
Node density
Section titled “Node density”The default native Graph tab keeps nodes visually stable and does not rely on collapsing nodes for day-to-day readability.
For large graphs, prefer auto-layout, comments, group boxes, search, frame-selection, and the minimap. The older custom Slate graph has been removed, so the native graph is the single production authoring surface.
Auto-layout
Section titled “Auto-layout”Use the graph toolbar’s layout actions to quickly reshape a state machine:
Compactkeeps short state flows close together for editing.Flowemphasizes the initial state and primary transition direction.Widegives dense graphs extra horizontal breathing room.Selectedlays out only the selected states and preserves the rest of the graph.
Auto-layout uses the initial state as the preferred starting point when one is set. Special nodes such as Entry and Any State are positioned as helpers rather than treated as normal runtime states.
Grid snap
Section titled “Grid snap”Press G to toggle grid snap.
When enabled:
- node movement snaps on release
- the graph is easier to keep tidy
Transition quick editing
Section titled “Transition quick editing”The graph supports:
- transition context menus
- selected transition inspector
- keyboard shortcuts for selected transitions
- breakpoint toggles
Graph tab
Section titled “Graph tab”The Graph tab uses Unreal’s graph framework (UEdGraph / SGraphEditor) for state-machine authoring. It replaces the older custom canvas.
The graph is editor-only and synchronized from the same definition asset. It is not a second runtime format and does not add separate serialized state-machine data.
Use the default graph for:
- native selection and context menus
- pin and edge authoring
- graph rewiring that writes back to the definition
- native connector routing and arrow rendering
The connector drawing chooses anchors along the surrounding node edge, distributes dense endpoints, renders bidirectional links as readable parallel lanes, and rotates arrowheads to match the incoming connector direction.
The native graph also supports standard graph comments, Backspace/Delete deletion, transaction-aware edits, and graph-driven state/transition creation.
For production authoring, use Graph as the canonical visual editor for the definition.
Group Boxes and Sticky Notes
Section titled “Group Boxes and Sticky Notes”Use group boxes to organize areas of the graph.
They support:
- dragging
- resizing
- renaming
- fit-to-contained-states
- color presets
Use sticky notes for freeform reminders such as:
- TODO items
- content assumptions
- mobile-only notes
- accessibility notes
Debugging in PIE
Section titled “Debugging in PIE”Open the definition asset and switch to the Debugger tab while PIE is running.
What you get:
- live machine instance list
- current and previous state
- time in state
- animation progress
- transition summary
- blocked reason
- blackboard watch
- transition log
- runtime stats
- state timeline
Breakpoints
Section titled “Breakpoints”You can set:
- transition breakpoints
- condition breakpoints
These are useful when a machine only misbehaves under very specific game state.
Multi-instance debugging
Section titled “Multi-instance debugging”If several widgets use the same definition, the debugger can switch between instances and compare them.
Testing Without PIE
Section titled “Testing Without PIE”The tester panel lets you validate a machine at authoring time.
Use it for:
- stepping through a transition script
- seeing visited-state coverage
- fuzz testing random walks
This is especially helpful before the widget itself is fully wired into gameplay.
The tester simulates state-machine transition reachability; it does not visually preview the owning Widget Blueprint’s UMG animation timeline. It also does not execute Blueprint condition functions, transition rule arrays, or InterruptPriority checks for forced transitions. Use PIE, the Widget Blueprint animation timeline, Sequencer, or the owning widget preview path when you need runtime-accurate behavior or rendered animation review.
Saving and loading test sequences
Section titled “Saving and loading test sequences”Test sequences can be saved as UWbpAnimTestSequenceAsset data assets and reloaded later.
To save:
- Build a sequence in the tester panel - set a start state and add steps.
- Enter a content path in the
State Machine Test Assetbox (e.g./Game/Tests/DA_ButtonSequence), or use the asset picker beside it. - Press Save.
To load:
- Enter the content path of an existing asset in the
State Machine Test Assetbox, or choose one with the picker. - Press Load - the steps are restored into the tester.
The tester shows an inline status message for invalid paths, failed saves, failed loads, and successful save/load operations, so you do not need to rely only on the Output Log.
The asset stores:
InitialState- each step’s
TargetState,bForce, and an optionalComment - a multiline
Descriptionfield for documentation
You can also create assets directly in the Content Browser (Miscellaneous -> Data Asset -> WbpAnimTestSequenceAsset) and hand-author them as regression sequences or acceptance tests.
Export, Import, and Enum Generation
Section titled “Export, Import, and Enum Generation”The definition asset exposes:
Export State Diagram (SVG)Export Definition (JSON)Import Definition (JSON)Generate State Enum Header
Output location:
Saved/WbpAnimStateMachineExports
Generated enum header location:
Saved/WbpAnimStateMachineExports/GeneratedHeaders
Important note:
- the generated enum header is not automatically compiled into your project
- copy it into your game
Sourcetree if you want to use it directly in C++
Validation
Section titled “Validation”Validation catches common authoring mistakes such as:
- duplicate state names
- invalid initial state
- bad animation names
- bad function references
- invalid transition endpoints
- invalid input binding targets
- unreachable states
The definition editor surfaces live validation output while authoring, so you do not have to rely only on a manual validation button. The older editor-module-only details hint has been removed; the native definition editor and the runtime/editor module’s details customization are now the authoritative authoring surfaces.
Common Blueprint Patterns
Section titled “Common Blueprint Patterns”Button
Section titled “Button”- Create machine from a
Buttonpreset - call
GoToState(Hover)on pointer enter - call
GoToState(Pressed)on pointer down - let
Pressed -> Hoverfinish automatically - drive gamepad focus through input bindings or explicit state changes
Hidden -> Intro -> Idle -> Outro -> Hidden- use
OnAnimationFinishedtransitions forIntroandOutro - use
GoToStateAndWaitwhen you need to continue a scripted flow only afterIntro
Spawn -> Visible -> Dismiss- use an auto-transition on
Visible - use a full snapshot if the toast stores mode or content state in the blackboard
Nested panel
Section titled “Nested panel”- parent machine handles section-level flow
- child machine handles local detail motion
Best Practices
Section titled “Best Practices”- Keep state names simple and stable
- Use presets for first pass authoring
- Set
OwnerWidgetClassimmediately - Prefer built-in rules before writing lots of widget condition functions
- Use tracks instead of giant combined state explosion
- Use notes and group boxes to keep bigger graphs readable
- Add breakpoints early when a flow becomes hard to reason about
- Use snapshots when UI state carries data, not just animation mode
- Save regression sequences as
UWbpAnimTestSequenceAssetso they can be replayed after refactors - Use
UWbpAnimCommonActivatableMixinfor CommonUI widgets rather than duplicatingGoToStatecalls in every widget subclass