Overview
The conditional_button_device is a button that only activates when the interacting agent is carrying a required quantity of one or more key items configured in the device's properties panel. It fires two events:
ActivatedEvent— the player had the goods; the button succeeded.NotEnoughItemsEvent— the player tried but was short; nothing was consumed.
Reach for this device whenever you want a cost gate in front of an action: unlocking a clifftop cannon, boarding a ferry at the dock, opening a sunken-treasure chest in a cove, or trading fish for a weapon at a shore-side shop. Pair it with Verse to read item counts at runtime, change the required cost mid-game, or show a custom hint that tells the player exactly how many more items they need.
API Reference
conditional_button_device
Used to create a specialized button which can only be activated when
agents are carrying specific items.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
conditional_button_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
ActivatedEvent |
ActivatedEvent<public>:listenable(agent) |
Signaled when this device is activated. Sends the agent that activated this device. |
NotEnoughItemsEvent |
NotEnoughItemsEvent<public>:listenable(agent) |
Signaled when this device fails to activate because agent didn't have the required items. Sends the agent that attempted to activate the device. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
Activate |
Activate<public>(Agent:agent):void |
Activates this device. Agent is used as the instigator of the action. |
Toggle |
Toggle<public>(Agent:agent):void |
Toggles the conditional button state. Agent is used as the instigator of the action. |
SetInteractionText |
SetInteractionText<public>(Text:message):void |
Sets the text that appears when agents approach the device. Text is limited to 150 characters and will revert back to default if empty. |
SetInteractionTime |
SetInteractionTime<public>(Time:float):void |
Sets the time (in seconds) that an interaction with this device should take to complete. |
GetInteractionTime |
GetInteractionTime<public>()<transacts>:float |
Returns the time (in seconds) that an interaction with this device will take to complete. |
SetItemCountRequired |
SetItemCountRequired<public>(KeyItemIndex:int, Count:int):void |
Sets the quantity of a specific key item type that needs to be collected in order to activate the switch. KeyItemIndex ranges from 0 to number of key item types - 1. |
GetItemCountRequired |
GetItemCountRequired<public>(KeyItemIndex:int)<transacts>:int |
Returns the total quantity of a specific key item type that needs to be collected in order to activate the switch. |
GetRemainingItemCountRequired |
GetRemainingItemCountRequired<public>(KeyItemIndex:int)<transacts>:int |
Returns the remaining quantity of a specific key item type that needs to be collected in order to activate the switch. |
SetItemScore |
SetItemScore<public>(KeyItemIndex:int, Score:int):void |
Sets the score to be awarded for a key item. KeyItemIndex ranges from 0 to number of key item types - 1. |
GetItemScore |
GetItemScore<public>(KeyItemIndex:int)<transacts>:int |
Returns the score to be awarded for a key item. |
GetItemCount |
GetItemCount<public>(Agent:agent, KeyItemIndex:int):int |
Returns how many items an Agent has of the item stored at KeyItemIndex. |
HasAllItems |
HasAllItems<public>(Agent:agent)<transacts><decides>:void |
Returns if the Agent has all of the items required to interact with this Device. |
IsHoldingItem |
IsHoldingItem<public>(Agent:agent)<transacts><decides>:void |
Returns if the Agent is currently holding any of the items stored in the Device. |
IsHoldingItem |
IsHoldingItem<public>(Agent:agent, KeyItemIndex:int)<transacts><decides>:void |
Returns if the Agent is currently holding the item stored at KeyItemIndex. |
button_device
Used to create a button which can trigger other devices when an agent interacts with it.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
button_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
InteractedWithEvent |
InteractedWithEvent<public>:listenable(agent) |
Signaled when an agent successfully interacts with the button for GetInteractionTime seconds. Sends the agent that interacted with the button. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
SetInteractionText |
SetInteractionText<public>(Text:message):void |
Sets the text that displays when an agent is close to this button and looks at it. Text is limited to 64 characters. |
SetInteractionTime |
SetInteractionTime<public>(Time:float):void |
Sets the duration of the interaction required to activate this device (in seconds). |
GetInteractionTime |
GetInteractionTime<public>()<transacts>:float |
Returns the duration of the interaction required to activate this device (in seconds). |
SetMaxTriggerCount |
SetMaxTriggerCount<public>(MaxCount:int):void |
Sets the maximum amount of times this button can be interacted with before it will be disabled. * MaxCount must be between 0 and 10000. * 0 indicates no limit on trigger count. |
GetMaxTriggerCount |
GetMaxTriggerCount<public>()<transacts>:int |
Returns the maximum amount of times this button can be interacted with before it will be disabled. * GetTriggerMaxCount will be between 0 and 10000. * 0 indicates no limit on trigger count. |
GetTriggerCountRemaining |
GetTriggerCountRemaining<public>()<transacts>:int |
Returns the number of times that this button can still be interacted with before it will be disabled. Will return 0 if GetMaxTriggerCount is unlimited. |
Walkthrough
Scenario — The Cove Treasure Chest
You've built a sun-drenched cove island. A glowing treasure chest sits on a wooden dock. Players must collect 3 Golden Doubloons (key item 0, configured in the device panel) and bring them to the chest to open it. When they succeed, a cinematic trigger fires and the chest opens. When they fall short, the button tells them exactly how many more coins they need.
Place these devices in your UEFN level:
conditional_button_device— the chest's interaction button (key item 0 = Golden Doubloon, count = 3)trigger_device— fires the chest-open cinematic
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Localized helper so we can pass dynamic text as a `message`.
ChestPrompt<localizes>(S : string) : message = "{S}"
cove_treasure_chest_manager := class(creative_device):
# The conditional button placed on the dock chest.
@editable
ChestButton : conditional_button_device = conditional_button_device{}
# A trigger that fires the chest-open cinematic / prop animation.
@editable
ChestOpenTrigger : trigger_device = trigger_device{}
# Key item index 0 = Golden Doubloon (set up in the device panel).
DoubloonIndex : int = 0
DoubloonCost : int = 3
OnBegin<override>()<suspends> : void =
# ── Runtime configuration ──────────────────────────────────────
# Enforce the cost in code so it's easy to tune from one place.
ChestButton.SetItemCountRequired(DoubloonIndex, DoubloonCost)
# Give the button a flavour-text prompt visible on approach.
ChestButton.SetInteractionText(ChestPrompt("Open Treasure Chest"))
# A 1-second hold makes it feel weighty — not an accidental tap.
ChestButton.SetInteractionTime(1.0)
# ── Event subscriptions ────────────────────────────────────────
ChestButton.ActivatedEvent.Subscribe(OnChestOpened)
ChestButton.NotEnoughItemsEvent.Subscribe(OnNotEnoughDoubloons)
ChestButton.Enable()
# Called when the player had all 3 doubloons and activated the button.
OnChestOpened(Agent : agent) : void =
# Fire the cinematic / prop-open trigger.
ChestOpenTrigger.Trigger(Agent)
# After the chest is looted, disable the button so it can't be
# opened a second time.
ChestButton.Disable()
# Called when the player tried but didn't have enough doubloons.
OnNotEnoughDoubloons(Agent : agent) : void =
# Find out how many more coins this player still needs.
Remaining := ChestButton.GetRemainingItemCountRequired(DoubloonIndex)
# Update the prompt so the player sees a personalised hint.
HintText := "Need {Remaining} more Doubloon(s)!"
ChestButton.SetInteractionText(ChestPrompt(HintText))
Line-by-line explanation
| Lines | What's happening |
|---|---|
SetItemCountRequired(0, 3) |
Tells the device at runtime that key item slot 0 requires exactly 3 items. Overrides whatever was set in the panel. |
SetInteractionText(...) |
Shows custom flavour text when a player walks up to the chest. Accepts a message (localized value), not a raw string. |
SetInteractionTime(1.0) |
Player must hold the interact key for 1 second — prevents accidental activations. |
ActivatedEvent.Subscribe(OnChestOpened) |
Registers our handler; fires only when the player had all required items. |
NotEnoughItemsEvent.Subscribe(OnNotEnoughDoubloons) |
Registers our "you're broke" handler. |
ChestOpenTrigger.Trigger(Agent) |
Fires the cinematic trigger, passing the activating agent as instigator. |
ChestButton.Disable() |
One-time chest — disables the button after a successful open. |
GetRemainingItemCountRequired(0) |
Returns how many of item 0 the player still needs; used to build a personalised hint. |
Common patterns
Pattern 1 — Dynamically raise the cost mid-game (escalating toll gate)
A toll booth on the clifftop road starts cheap and gets more expensive each time a player pays. Uses SetItemCountRequired and GetItemCountRequired together.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
TollPrompt<localizes>(S : string) : message = "{S}"
clifftop_toll_manager := class(creative_device):
@editable
TollButton : conditional_button_device = conditional_button_device{}
# Key item index 0 = Toll Coin.
TollItemIndex : int = 0
OnBegin<override>()<suspends> : void =
# Start at 1 coin.
TollButton.SetItemCountRequired(TollItemIndex, 1)
TollButton.SetInteractionText(TollPrompt("Pay Toll"))
TollButton.Enable()
TollButton.ActivatedEvent.Subscribe(OnTollPaid)
OnTollPaid(Agent : agent) : void =
# Read the current cost, then raise it by 1 for next time.
CurrentCost := TollButton.GetItemCountRequired(TollItemIndex)
NewCost := CurrentCost + 1
TollButton.SetItemCountRequired(TollItemIndex, NewCost)
# Refresh the prompt so the next player sees the updated price.
TollButton.SetInteractionText(TollPrompt("Pay Toll"))
Pattern 2 — Check whether a player is holding the key item before they even interact
A shore-side ferry gate uses HasAllItems (a <decides> function) to light up a green lamp the moment a player walks near, giving visual feedback before they press anything.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
FerryPrompt<localizes>(S : string) : message = "{S}"
ferry_gate_manager := class(creative_device):
@editable
FerryButton : conditional_button_device = conditional_button_device{}
# A trigger that turns on the green "ready" lamp prop.
@editable
GreenLampTrigger : trigger_device = trigger_device{}
# A trigger that turns on the red "not ready" lamp prop.
@editable
RedLampTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
FerryButton.SetInteractionText(FerryPrompt("Board Ferry"))
FerryButton.Enable()
FerryButton.ActivatedEvent.Subscribe(OnBoarded)
FerryButton.NotEnoughItemsEvent.Subscribe(OnBoardingFailed)
# Utility called from game logic when a player approaches the gate.
# (Wire this from a trigger_device's TriggeredEvent in a real setup.)
CheckPlayerReadiness(Agent : agent) : void =
# HasAllItems is a <decides> function — use it inside an if.
if (FerryButton.HasAllItems[Agent]):
GreenLampTrigger.Trigger(Agent)
else:
RedLampTrigger.Trigger(Agent)
OnBoarded(Agent : agent) : void =
FerryButton.Disable()
OnBoardingFailed(Agent : agent) : void =
RedLampTrigger.Trigger(Agent)
Pattern 3 — Temporarily toggle the button off during a cooldown
A dock cannon can only be fired once every 10 seconds. After activation the button is toggled off; a Sleep brings it back. Uses Toggle and Activate.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
CannonPrompt<localizes>(S : string) : message = "{S}"
dock_cannon_manager := class(creative_device):
@editable
CannonButton : conditional_button_device = conditional_button_device{}
@editable
CannonTrigger : trigger_device = trigger_device{}
CooldownSeconds : float = 10.0
AmmoItemIndex : int = 0
OnBegin<override>()<suspends> : void =
CannonButton.SetItemCountRequired(AmmoItemIndex, 1)
CannonButton.SetInteractionText(CannonPrompt("Fire Cannon"))
CannonButton.SetInteractionTime(0.5)
CannonButton.Enable()
CannonButton.ActivatedEvent.Subscribe(OnCannonFired)
OnCannonFired(Agent : agent) : void =
CannonTrigger.Trigger(Agent)
# Disable during cooldown, then re-enable.
spawn:
CooldownAndReenable(Agent)
CooldownAndReenable(Agent : agent)<suspends> : void =
# Toggle off immediately (button is currently enabled → becomes disabled).
CannonButton.Toggle(Agent)
CannonButton.SetInteractionText(CannonPrompt("Reloading..."))
Sleep(CooldownSeconds)
# Toggle back on.
CannonButton.Toggle(Agent)
CannonButton.SetInteractionText(CannonPrompt("Fire Cannon"))
Gotchas
1 — SetInteractionText requires a message, not a string
The parameter type is message (a localized value). You cannot pass a raw string literal or a string variable directly. Declare a localizes helper:
MyPrompt<localizes>(S : string) : message = "{S}"
Then call ChestButton.SetInteractionText(MyPrompt("Open Chest")). There is no StringToMessage built-in.
2 — HasAllItems and IsHoldingItem are <decides> functions
They don't return a bool — they succeed or fail. Always call them inside an if expression:
if (ChestButton.HasAllItems[Agent]):
# player is ready
Note the square brackets [] — required for failable (decides) calls.
3 — NotEnoughItemsEvent fires but items are NOT consumed
The device only consumes items on a successful ActivatedEvent. If you're updating UI or prompts in NotEnoughItemsEvent, don't assume any inventory change occurred.
4 — KeyItemIndex is 0-based and bounded by the panel configuration
If you call SetItemCountRequired(2, 5) but only configured 2 key item slots (indices 0 and 1) in the panel, the call is silently ignored at runtime. Always match your code indices to the number of key item types you set up in the device's Details panel.
5 — GetRemainingItemCountRequired is per-call, not reactive
It returns the remaining count at the moment you call it. If you want a live HUD counter, poll it on a timer or call it inside NotEnoughItemsEvent (which fires every failed attempt).
6 — Toggle uses the current enabled state
Toggle(Agent) flips enabled↔disabled. If you call it twice in quick succession (e.g., in a race condition with two players), the state may not be what you expect. Prefer explicit Enable() / Disable() when you need deterministic state.
7 — @editable fields are mandatory for placed devices
You cannot construct a conditional_button_device{} in code and expect it to exist in the world. Always declare it @editable and assign the placed device in the Details panel:
@editable
ChestButton : conditional_button_device = conditional_button_device{}