Overview
The class_and_team_selector_device works hand-in-hand with class_designer_device to give you runtime control over which team and class each player belongs to. You configure the target team and class slots in the device's editor properties, then call its Verse methods to apply those settings to any agent at any moment during gameplay.
When should you reach for it?
- Role-assignment games — Prop Hunt, Among Us-style, Infection: assign the first player who steps on a trigger to the "Hunter" team.
- Mid-game class upgrades — a player collects enough coins and earns a new loadout class.
- Team balancing — detect an uneven team count and move a volunteer to the smaller side.
- Cinematic moments — switch everyone to a spectator class when a boss dies.
The device exposes two reactive events (ClassSwitchedEvent, TeamSwitchedEvent) so the rest of your game can respond whenever an assignment happens, keeping your systems decoupled.
API Reference
class_and_team_selector_device
Used together with
class_designer_deviceto control how/when created classes can be accessed byagents.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
class_and_team_selector_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
ClassSwitchedEvent |
ClassSwitchedEvent<public>:listenable(agent) |
Signaled when an agent changes class. Sends the agent whose class changed. |
TeamSwitchedEvent |
TeamSwitchedEvent<public>:listenable(agent) |
Signaled when an agent changes teams. Sends the agent whose team changed. |
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. |
ChangeClass |
ChangeClass<public>(Agent:agent):void |
Changes the Agent's class. |
ChangeTeam |
ChangeTeam<public>(Agent:agent):void |
Changes the Agent's team. |
ChangeTeamAndClass |
ChangeTeamAndClass<public>(Agent:agent):void |
Changes the Agent's team and class. |
ChangeSelectorTeam |
ChangeSelectorTeam<public>(Agent:agent):void |
Changes the selecting team. |
Walkthrough
Scenario: Prop Hunt Role Assignment
A player steps on a trigger plate. If they are the first to do so, they become the Hunter (Team 2, Class 2). Everyone else who steps on the plate becomes a Prop (Team 1, Class 1). When any player's team changes we log the event by enabling a confirmation device.
Place in your level:
- One
trigger_device(the role-selection plate) - Two
class_and_team_selector_deviceinstances: one configured for Hunter (Team 2 / Class 2), one for Prop (Team 1 / Class 1) - One
hud_message_deviceto confirm the switch (optional — used here to show Enable/Disable)
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
prop_hunt_role_assigner := class(creative_device):
# The trigger plate players step on to get their role
@editable
RolePlate : trigger_device = trigger_device{}
# Selector pre-configured in editor: Team 2, Class 2 (Hunter)
@editable
HunterSelector : class_and_team_selector_device = class_and_team_selector_device{}
# Selector pre-configured in editor: Team 1, Class 1 (Prop)
@editable
PropSelector : class_and_team_selector_device = class_and_team_selector_device{}
# HUD device used to show a confirmation banner
@editable
ConfirmationHUD : hud_message_device = hud_message_device{}
# Track whether the Hunter slot has been filled
var HunterAssigned : logic = false
OnBegin<override>()<suspends> : void =
# Subscribe to the trigger plate
RolePlate.TriggeredEvent.Subscribe(OnPlayerStepped)
# React whenever EITHER selector fires a TeamSwitchedEvent
HunterSelector.TeamSwitchedEvent.Subscribe(OnTeamChanged)
PropSelector.TeamSwitchedEvent.Subscribe(OnTeamChanged)
# React whenever a class changes on the Hunter selector
HunterSelector.ClassSwitchedEvent.Subscribe(OnClassChanged)
# Called when a player steps on the role plate
OnPlayerStepped(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
if (not HunterAssigned?):
# First player becomes the Hunter — switch both team AND class atomically
set HunterAssigned = true
HunterSelector.ChangeTeamAndClass(Agent)
else:
# All subsequent players become Props
PropSelector.ChangeTeamAndClass(Agent)
# Called whenever a player's team changes on either selector
OnTeamChanged(Agent : agent) : void =
# Show the confirmation HUD banner briefly
ConfirmationHUD.Enable()
# Called whenever a player's class changes on the Hunter selector
OnClassChanged(Agent : agent) : void =
# Could trigger a cinematic, grant items, etc.
# Here we simply disable the selector so the Hunter can't switch again
HunterSelector.Disable()
Line-by-line breakdown
| Lines | What's happening |
|---|---|
@editable fields |
Bind the placed devices so Verse can call their methods. Without @editable the identifiers are unknown. |
var HunterAssigned |
Simple flag so only the first player gets the Hunter role. |
RolePlate.TriggeredEvent.Subscribe(OnPlayerStepped) |
Hooks the trigger plate; the handler receives ?agent. |
HunterSelector.TeamSwitchedEvent.Subscribe(OnTeamChanged) |
Listens for team changes on the Hunter selector. |
if (Agent := MaybeAgent?) |
Unwraps the ?agent option — mandatory before using it. |
HunterSelector.ChangeTeamAndClass(Agent) |
Atomically moves the agent to Team 2 and Class 2 as configured in the editor. |
PropSelector.ChangeTeamAndClass(Agent) |
Moves everyone else to Team 1 / Class 1. |
ConfirmationHUD.Enable() |
Demonstrates Enable — turns on the HUD device as a side-effect of the team switch. |
HunterSelector.Disable() |
Demonstrates Disable — locks the Hunter selector after the role is assigned. |
Common patterns
Pattern 1 — Change only the team (team balancer)
A button in a lobby lets a volunteer move to the smaller team. Only ChangeTeam is called — the player keeps their current class.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
team_balancer := class(creative_device):
# Button players press to volunteer for the smaller team
@editable
VolunteerButton : button_device = button_device{}
# Selector configured in editor to target the smaller team
@editable
SmallTeamSelector : class_and_team_selector_device = class_and_team_selector_device{}
OnBegin<override>()<suspends> : void =
VolunteerButton.InteractedWithEvent.Subscribe(OnVolunteer)
OnVolunteer(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# Move the agent to the configured team, class unchanged
SmallTeamSelector.ChangeTeam(Agent)
Pattern 2 — Change only the class (mid-game upgrade)
A player collects a power-up trigger and earns a new class loadout without changing their team affiliation.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
class_upgrade_device := class(creative_device):
# The power-up pickup trigger
@editable
PowerUpTrigger : trigger_device = trigger_device{}
# Selector configured in editor: same team, upgraded class slot
@editable
UpgradeSelector : class_and_team_selector_device = class_and_team_selector_device{}
OnBegin<override>()<suspends> : void =
PowerUpTrigger.TriggeredEvent.Subscribe(OnPickedUp)
# Also listen for the class switch confirmation
UpgradeSelector.ClassSwitchedEvent.Subscribe(OnUpgradeConfirmed)
OnPickedUp(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# Only change the class, keep the player on their current team
UpgradeSelector.ChangeClass(Agent)
OnUpgradeConfirmed(Agent : agent) : void =
# ClassSwitchedEvent fired — safe to grant upgraded items, play FX, etc.
UpgradeSelector.Disable() # prevent double-upgrade
Pattern 3 — ChangeSelectorTeam (shift which team the selector targets)
ChangeSelectorTeam changes which team the selector itself targets, based on the calling agent's team. Use this when you want the device to dynamically re-point at a different team slot before applying a switch to another player.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
dynamic_team_redirect := class(creative_device):
# A trigger that fires when a round ends
@editable
RoundEndTrigger : trigger_device = trigger_device{}
# Selector whose target team will be redirected
@editable
RoundSelector : class_and_team_selector_device = class_and_team_selector_device{}
OnBegin<override>()<suspends> : void =
RoundEndTrigger.TriggeredEvent.Subscribe(OnRoundEnd)
RoundSelector.TeamSwitchedEvent.Subscribe(OnTeamSwitched)
OnRoundEnd(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# Redirect the selector's own team based on this agent,
# then apply the full team+class change to them
RoundSelector.ChangeSelectorTeam(Agent)
RoundSelector.ChangeTeamAndClass(Agent)
OnTeamSwitched(Agent : agent) : void =
# Re-enable the selector for the next round
RoundSelector.Enable()
Gotchas
1. You MUST declare devices as @editable fields
A bare class_and_team_selector_device{} literal in a local variable has no connection to the placed device in your level. Always declare it as an @editable field on your creative_device class and wire it up in the UEFN editor's Details panel. Forgetting this is the #1 cause of "nothing happens" bugs.
2. listenable(agent) hands you ?agent — always unwrap
ClassSwitchedEvent and TeamSwitchedEvent are listenable(agent), but the handler signature receives (Agent : ?agent). You must unwrap with if (A := Agent?): before passing A to any method. Skipping the unwrap is a compile error.
3. The device's editor properties drive the target — Verse drives the trigger
ChangeClass, ChangeTeam, and ChangeTeamAndClass apply whatever team/class slots are configured in the device's editor properties. Verse code cannot override those slots at runtime — set them correctly in the Details panel before pressing Play.
4. ChangeTeamAndClass vs two separate calls
Calling ChangeTeam then ChangeClass in sequence can fire two separate events and briefly leave the player in an inconsistent state. Prefer ChangeTeamAndClass when you need both to change atomically.
5. Disable prevents the device from responding to further calls
After calling Disable(), subsequent calls to ChangeClass, ChangeTeam, etc. on that device will have no effect until Enable() is called again. Use this intentionally to gate upgrades or prevent double-assignment, but don't accidentally leave a device disabled and wonder why nothing works.
6. One selector = one configured target
Each class_and_team_selector_device instance points to exactly one team/class configuration. For a game with multiple distinct roles, place multiple selector devices — one per role — and call the appropriate one based on your game logic.