
Verse Button Events & Player UI Widgets
What you'll learn
- How to subscribe to
InteractedWithEventon abutton_device. - How to safely cast an
agentto aplayerand get theirplayer_uiwithGetPlayerUI[...]. - How to add and later remove a
text_blockwidget from a player's screen.
How it works
- Subscribe: In
OnBegin, we callButton.InteractedWithEvent.Subscribe(HandleButtonInteraction). Device events use.Subscribedirectly (no parentheses on the event), unlike character events. - Handler receives an agent: The handler is passed the
agentwho interacted. An agent can be a player OR AI, so we can't use it directly for UI. - Cast + get UI in one failure context:
if (InPlayer := player[Agent], PlayerUI := GetPlayerUI[InPlayer]):casts the agent to a player and fetches that player's UI. Both are fallible ([]) calls, so they live inside anifcondition. - Track state per widget: We store the current widget in a per-player
weak_mapoption. If a widget already exists we remove it, then add a fresh one showing the updated count.
Why the failure context?
player[Agent]andGetPlayerUI[InPlayer]are<decides>calls — the[]brackets are only legal inside anif,for, or other failure context. If the agent is an AI, the cast simply fails and we skip the UI code.
Let's build it
using { /Fortnite.com/Devices }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Displays a per-player click counter widget when a Button device is pressed.
button_ui_device := class<concrete>(creative_device):
@editable
Button : button_device = button_device{}
# How many times each player has clicked. weak_map keyed by agent.
var ClickCounts : [agent]int = map{}
# The current widget shown to each player, so we can remove it before re-adding.
var ShownWidgets : [agent]?text_block = map{}
OnBegin<override>()<suspends> : void =
# Device events subscribe WITHOUT parentheses on the event itself.
Button.InteractedWithEvent.Subscribe(HandleButtonInteraction)
# Runs whenever a player interacts with the Button device.
HandleButtonInteraction(Agent : agent) : void =
# Cast the agent to a player AND fetch their UI in one failure context.
# Both [] calls are fallible; AI agents will simply fail the cast here.
if (InPlayer := player[Agent], PlayerUI := GetPlayerUI[InPlayer]):
# Compute the new click count for this player.
var Count : int = 0
if (Existing := ClickCounts[Agent]):
set Count = Existing
set Count = Count + 1
if (set ClickCounts[Agent] = Count) {}
# Remove any widget we previously showed this player.
if (Old := ShownWidgets[Agent]?):
PlayerUI.RemoveWidget(Old)
# Build a fresh text widget with the updated count and show it.
NewWidget : text_block = text_block{DefaultText := ClickMessage}
NewWidget.SetText(StringToMessage("Clicked {Count} times!"))
PlayerUI.AddWidget(NewWidget)
if (set ShownWidgets[Agent] = option{NewWidget}) {}
Print("Button pressed! Player count is now {Count}")
# Default text shown before SetText overrides it.
ClickMessage<localizes> : message = "Clicked!"
# Wrap a string into a message so text_block can display it.
StringToMessage<localizes>(S : string) : message = "{S}"
Try it yourself
- Add a second
button_deviceand give each its own counter map. - After showing the widget,
Sleep(3.0)then callPlayerUI.RemoveWidget(NewWidget)to auto-hide it (you'll need to restructure into aspawn{}). - Wrap the
text_blockin astack_boxoroverlayfor custom positioning.
Recap
- Device events like
InteractedWithEventuse.Subscribe(Handler)directly. - Handlers get an
agent; cast withplayer[Agent]inside a failure context before touching UI. GetPlayerUI[InPlayer]returns aplayer_ui; useAddWidget/RemoveWidgetto manage that player's on-screen widgets.- Track shown widgets in an option map so you can remove the old one before adding a new one.
Check your understanding
Test yourself with an interactive quiz and track your progress + earn XP — free for members.
Turn this into a guided course
Add Subscribing to Button Device Interaction Events in Verse to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.
Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.