Overview
The character_device is a single interactive mannequin you place in the world to visualize a character, its clothing, and play emotes. Think of it as the body for an NPC: a quest-giver standing in your town square, a dance-off opponent on a stage, or a guard that blocks a doorway until the player completes an objective.
Reach for it whenever you need a presence in the world that a player can interact with — but where you want Verse to decide what happens next instead of relying on built-in device wiring. The device fires InteractedWithEvent when a player interacts with it, and exposes simple verbs you call from code: Enable/Disable (turn its interactivity on and off), Show/Hide (make it appear or vanish), and PlayEmote (make it perform its configured emote).
A key setup note: in the device's User Options, set Interact Type to Send Event Only so that interacting fires InteractedWithEvent for your Verse code to handle, rather than doing some built-in action. Also enabling Use Animated Idle makes the mannequin feel alive.
API Reference
character_device
Used to configure a single interactive mannequin, that can visualize characters, clothing, and perform emotes.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
character_device<public> := class<concrete>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
InteractedWithEvent |
InteractedWithEvent<public>:listenable(agent) |
Signaled when an agent interacts with this device. Sends the agent that interacted with this 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. |
Show |
Show<public>():void |
Shows this device. |
Hide |
Hide<public>():void |
Hides this device. |
PlayEmote |
PlayEmote<public>():void |
Plays an emote on the character created by this device. |
Walkthrough
Let's build a dance-off NPC. A character stands on a stage. When a player walks up and interacts with it, the NPC plays its emote (a dance), and after three interactions it has "finished its routine" — it plays one final emote, then hides itself and disables further interaction.
Drag a Character Device into your scene (set Interact Type = Send Event Only). Then create this Verse device and assign the character device to its @editable field in UEFN.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporal }
# A dance-off NPC: emotes each time a player interacts, then bows out.
dance_off_npc := class(creative_device):
# Drag your placed Character Device onto this field in UEFN.
@editable
Dancer : character_device = character_device{}
# Tracks how many times a player has challenged the dancer.
var Interactions : int = 0
OnBegin<override>()<suspends> : void =
# Make sure the NPC is visible and interactable when the round starts.
Dancer.Show()
Dancer.Enable()
# React whenever a player interacts with the mannequin.
Dancer.InteractedWithEvent.Subscribe(OnInteracted)
# Event handler — runs each time a player talks to / interacts with the NPC.
OnInteracted(Agent : agent) : void =
set Interactions += 1
# Every interaction, the NPC busts out its configured emote.
Dancer.PlayEmote()
# After three rounds, the dancer finishes and leaves the stage.
if (Interactions >= 3):
Dancer.Disable()
Dancer.Hide()
Line by line:
@editable Dancer : character_device = character_device{}declares the field that lets you wire the placed device in UEFN. Without an@editablefield, callingDancer.PlayEmote()would fail with Unknown identifier — you can never call a bare device.var Interactions : int = 0is mutable state that survives between interactions, counting how many times we've been challenged.- In
OnBegin,Dancer.Show()andDancer.Enable()guarantee the NPC is visible and accepting interactions at round start (good hygiene even if it's the default). Dancer.InteractedWithEvent.Subscribe(OnInteracted)wires the device's interaction event to our method.InteractedWithEventislistenable(agent), so the handler receives a plainagent.OnInteracted(Agent : agent)is a method at class scope — that's the shape a subscribed handler must have. We bump the counter, callPlayEmote()to make the mannequin dance, and once we hit three weDisable()(no more interactions) andHide()(the character vanishes from the stage).
Common patterns
Toggle an NPC's visibility from a button (Show / Hide)
A "summon the merchant" button: pressing it reveals the hidden character; the character can then be interacted with.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
summon_merchant := class(creative_device):
@editable
Merchant : character_device = character_device{}
@editable
SummonButton : button_device = button_device{}
OnBegin<override>()<suspends> : void =
# Start hidden — the merchant only appears when summoned.
Merchant.Hide()
SummonButton.InteractedWithEvent.Subscribe(OnSummon)
OnSummon(Agent : agent) : void =
Merchant.Show()
Merchant.Enable()
Make the NPC celebrate when a player interacts (PlayEmote on interact)
The simplest reactive NPC: each interaction triggers its emote.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
celebrating_npc := class(creative_device):
@editable
Greeter : character_device = character_device{}
OnBegin<override>()<suspends> : void =
Greeter.InteractedWithEvent.Subscribe(OnGreet)
OnGreet(Agent : agent) : void =
# The NPC waves / dances every time someone says hi.
Greeter.PlayEmote()
Disable a guard NPC after a quest trigger (Enable / Disable)
A guard blocks a path. When a quest trigger fires, we disable the guard so players can pass and stop it from being interacted with.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
quest_guard := class(creative_device):
@editable
Guard : character_device = character_device{}
@editable
QuestComplete : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
Guard.Enable()
QuestComplete.TriggeredEvent.Subscribe(OnQuestDone)
OnQuestDone(MaybeAgent : ?agent) : void =
# Quest finished — the guard stands down.
Guard.Disable()
Note trigger_device.TriggeredEvent is listenable(?agent), so its handler takes a ?agent (optional). Unwrap with if (A := MaybeAgent?): if you need the player — here we just disable the guard, so we don't need it.
Gotchas
- You must wire an
@editablefield. Callingcharacter_device{}.PlayEmote()on a fresh value does nothing — you have to drag your placed device onto the@editable Dancerfield in UEFN so the code controls the real mannequin in the level. - Set Interact Type = Send Event Only. If the device's User Option Interact Type is left on a built-in action,
InteractedWithEventmay not fire for your Verse handler. This is the single most common reason "my interact code does nothing." InteractedWithEventsends a plainagent, not?agent. Your handler signature isOnInteracted(Agent : agent)— no?and no unwrap needed. Contrast withtrigger_device.TriggeredEvent, which islistenable(?agent)and does need unwrapping.Hide()is notDisable().Hideremoves the visual mannequin but the device can still be logically enabled;Disablestops interaction. When you want an NPC truly gone and uninteractable, call both — as the walkthrough does.PlayEmote()plays the emote configured in the device's User Options. It takes no arguments — you choose which emote in the device settings in UEFN, not in code.- Handlers are methods at class scope. Define
OnInteractedas a class member andSubscribeto it insideOnBegin. Defining it as a local function insideOnBeginwon't let you subscribe the same way.