Reference Devices compiles

changing_booth_device: React to Outfit Changes in Real Time

The `changing_booth_device` lets players swap their outfit mid-match — but its real power for creators is the two Verse events it fires: `PlayerEnterEvent` and `PlayerExitEvent`. Subscribe to these and you can reward players for using the booth, lock a door until someone changes, or track how many costume swaps have happened across your whole island.

Updated Examples verified on the live UEFN compiler
Watch the Knotchanging_booth_device in ~90 seconds.

Overview

The changing_booth_device is a Creative device that presents players with an outfit-selection UI when they walk up to it. From a Verse perspective the device exposes two listenable events:

Event When it fires Payload
PlayerEnterEvent A player steps into the booth player
PlayerExitEvent A player leaves the booth (after or without changing) player

Reach for this device whenever you need to:

  • Gate progression behind a costume change (e.g. "put on the disguise to enter the enemy base").
  • Award XP / items the moment a player finishes changing.
  • Track stats — count total outfit swaps across all players.
  • Trigger cinematics or narrative beats tied to a character transformation.

Because both events carry a player payload you always know who entered or exited, making per-player logic straightforward.

API Reference

changing_booth_device

Allows players to change their outfit in game!

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).

changing_booth_device<public> := class<concrete><final>(creative_device_base):

Events (subscribe a handler to react):

Event Signature Description
PlayerEnterEvent PlayerEnterEvent<public>:listenable(player) Signaled when a player enters the changing booth device.
PlayerExitEvent PlayerExitEvent<public>:listenable(player) Signaled when a player exits the changing booth device.

Walkthrough

Scenario: The Disguise Gate

You have a spy-themed map. A locked barrier blocks the path to the enemy base. Players must step into a changing_booth_device (to put on a disguise) before the barrier opens. Once they exit the booth the barrier unlocks for that player and a confirmation message is broadcast.

Place these devices on your island:

  • One changing_booth_device (the disguise booth)
  • One barrier_device (the gate — set it to Enabled / blocking by default in its properties)
  • One hud_message_device (optional — to show the "Disguise acquired" message)
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

# disguise_gate_device.verse
# Drop this Verse device on the island, then wire up the three @editable fields.
disguise_gate_device := class(creative_device):

    # The changing booth the player must use to get their disguise.
    @editable
    DisguiseBooth : changing_booth_device = changing_booth_device{}

    # The barrier that blocks the path to the enemy base.
    @editable
    Gate : barrier_device = barrier_device{}

    # A HUD message device to confirm the disguise was acquired.
    @editable
    ConfirmationHUD : hud_message_device = hud_message_device{}

    # Tracks how many players have successfully changed.
    var DisguisedCount : int = 0

    OnBegin<override>()<suspends> : void =
        # Subscribe both events so we react to enter AND exit.
        DisguiseBooth.PlayerEnterEvent.Subscribe(OnPlayerEnterBooth)
        DisguiseBooth.PlayerExitEvent.Subscribe(OnPlayerExitBooth)

    # Called the moment a player steps INTO the booth.
    # Use this to give a hint or start a timer if you like.
    OnPlayerEnterBooth(P : player) : void =
        # The player is now inside — we could start a countdown here.
        # For this example we just wait for them to exit.
        Print("A player entered the disguise booth.")

    # Called when a player EXITS the booth (whether they changed or not).
    # We treat any exit as "disguise acquired" for simplicity.
    OnPlayerExitBooth(P : player) : void =
        # Increment the global counter.
        set DisguisedCount = DisguisedCount + 1

        # Unlock the gate for everyone once at least one player has changed.
        # (Swap this logic for per-player gating if your game needs it.)
        Gate.Disable()

        # Show the confirmation message.
        ConfirmationHUD.Show()

        Print("Disguise acquired! Total disguised players: {DisguisedCount}")

Line-by-line explanation

Lines What's happening
@editable fields Wired in the UEFN editor — no hard-coded device names.
var DisguisedCount A mutable counter that persists for the session.
OnBegin Runs at game start; subscribes both events so handlers fire automatically.
OnPlayerEnterBooth Fires the instant a player walks into the booth UI. Great for hints or timers.
OnPlayerExitBooth Fires when the player leaves — this is where we unlock the gate and show the HUD.
Gate.Disable() Disables the barrier device, opening the path.
ConfirmationHUD.Show() Pops the HUD message so the player knows they're good to go.

Common patterns

Pattern 1 — Count how many players are currently inside the booth

Sometimes you want to know whether anyone is actively in the booth right now (e.g. to prevent the booth being used while a cinematic plays).

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

booth_occupancy_tracker := class(creative_device):

    @editable
    Booth : changing_booth_device = changing_booth_device{}

    # How many players are currently inside the booth.
    var PlayersInside : int = 0

    OnBegin<override>()<suspends> : void =
        Booth.PlayerEnterEvent.Subscribe(OnEnter)
        Booth.PlayerExitEvent.Subscribe(OnExit)

    OnEnter(P : player) : void =
        set PlayersInside = PlayersInside + 1
        Print("Booth occupancy: {PlayersInside}")

    OnExit(P : player) : void =
        if (PlayersInside > 0):
            set PlayersInside = PlayersInside - 1
        Print("Booth occupancy: {PlayersInside}")

This pattern is useful as a guard: check PlayersInside > 0 before triggering anything that would conflict with the booth UI.


Pattern 2 — Award an item the moment a player exits the booth

Pair the booth with an item_granter_device to hand a weapon or consumable to every player who completes a costume change.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

booth_item_reward_device := class(creative_device):

    @editable
    DisguiseBooth : changing_booth_device = changing_booth_device{}

    # An item_granter_device pre-configured in the editor with the reward item.
    @editable
    Granter : item_granter_device = item_granter_device{}

    OnBegin<override>()<suspends> : void =
        # Only subscribe to PlayerExitEvent — we reward on exit, not entry.
        DisguiseBooth.PlayerExitEvent.Subscribe(OnExitBooth)

    OnExitBooth(P : player) : void =
        # Grant the configured item to the player who just exited.
        Granter.GrantItem(P)
        Print("Item granted to player who exited the booth.")

item_granter_device.GrantItem(agent) targets a specific player, so every person who exits gets their own reward independently.


Pattern 3 — Fire a cinematic the first time any player enters the booth

Trigger a one-shot narrative moment (via a cinematic_sequence_device) the very first time a player steps into the booth.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

booth_cinematic_device := class(creative_device):

    @editable
    DisguiseBooth : changing_booth_device = changing_booth_device{}

    @editable
    Cinematic : cinematic_sequence_device = cinematic_sequence_device{}

    # Guard so the cinematic only plays once.
    var CinematicPlayed : logic = false

    OnBegin<override>()<suspends> : void =
        DisguiseBooth.PlayerEnterEvent.Subscribe(OnFirstEnter)

    OnFirstEnter(P : player) : void =
        if (CinematicPlayed = false):
            set CinematicPlayed = true
            Cinematic.Play()
            Print("Cinematic triggered by first booth entry.")

The logic guard ensures Cinematic.Play() is called exactly once no matter how many players use the booth.

Gotchas

1. Both events carry player, not ?agent

PlayerEnterEvent and PlayerExitEvent are listenable(player) — the payload is a concrete player, not ?agent. You do not need to unwrap an option; just use P : player directly in your handler signature. Contrast this with some other devices whose events send ?agent and require if (A := Agent?): unwrapping.

2. Exit fires whether or not the player changed outfit

PlayerExitEvent fires whenever the player leaves the booth UI — even if they closed it without picking a new outfit. If your game logic requires confirming an actual outfit change you will need additional state (e.g. compare the player's cosmetic before and after, or require them to interact with a separate confirmation button).

3. Subscribe in OnBegin, not at field-initialisation time

You must call .Subscribe(...) inside OnBegin<override>()<suspends>. Attempting to subscribe at class-field level (outside a method) will not compile because the device references are not yet valid.

4. No methods — only events

changing_booth_device exposes zero callable methods. You cannot programmatically open the booth UI, force a player into it, or query which outfit a player chose. All Verse interaction is purely reactive via the two events.

5. One handler per subscription call

Each call to .Subscribe(Handler) registers one callback. If you accidentally call Subscribe twice in a loop or from two code paths, your handler will fire twice per event. Keep subscription calls in a single, clearly guarded location (typically OnBegin).

6. message parameters need localisation helpers

If you pass text to a device that accepts a message type (e.g. hud_message_device), raw strings are not accepted. Declare a localised helper:

MyText<localizes>(S : string) : message = "{S}"

and pass MyText("Disguise acquired!") — there is no StringToMessage function in Verse.

Build your own lesson with changing_booth_device

Generate a personalized, step-by-step lesson plan built around this object — grounded in this exact reference and our compile-verified knowledge base.

Build a lesson →