Overview
The gameplay_camera_first_person_device is a concrete creative device that renders the world from the player character's own viewpoint — the classic first-person perspective. It inherits from gameplay_camera_device, which defines the full camera-stack API shared by all gameplay camera types.
When to reach for it:
- You're building a first-person shooter or tactical game and need FPS view from the start or mid-match.
- You want a cinematic moment — a door opens, the player leans in, and the camera snaps to first-person.
- You need per-player camera control: one player gets FPS while others stay third-person.
- You want to restore the previous camera after a cutscene by simply removing this one from the stack.
How the stack works: Cameras in UEFN are stacked per-player. AddTo(Agent) pushes this camera to the top (making it active). RemoveFrom(Agent) pops it, restoring whatever was underneath. AddToAll / RemoveFromAll do the same for every player at once. Enable / Disable toggle the device itself — a disabled device can't be pushed onto any stack.
API Reference
gameplay_camera_first_person_device
Used to update the camera's viewpoint from the perspective of the player character.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from gameplay_camera_device.
gameplay_camera_first_person_device<public> := class<concrete><final>(gameplay_camera_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. |
AddTo |
AddTo<public>(Agent:agent):void |
Adds the camera to the Agent's camera stack and pushes it to be the active camera. |
AddToAll |
AddToAll<public>():void |
Adds the camera to all Agents camera stacks and pushes it to be the active camera. |
RemoveFrom |
RemoveFrom<public>(Agent:agent):void |
Removes the camera from the Agent's camera stack and pops from being the active camera replacing it with the next one in the stack. |
RemoveFromAll |
RemoveFromAll<public>():void |
Removes the camera from all Agents camera stacks and pops from being the active camera replacing it with the next one in the stack. |
gameplay_camera_device
Used to update the camera's current viewpoint and rotation based on current camera mode.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
gameplay_camera_device<public> := class<abstract><epic_internal>(creative_device_base):
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. |
AddTo |
AddTo<public>(Agent:agent):void |
Adds the camera to the Agent's camera stack and pushes it to be the active camera. |
AddToAll |
AddToAll<public>():void |
Adds the camera to all Agents camera stacks and pushes it to be the active camera. |
RemoveFrom |
RemoveFrom<public>(Agent:agent):void |
Removes the camera from the Agent's camera stack and pops from being the active camera replacing it with the next one in the stack. |
RemoveFromAll |
RemoveFromAll<public>():void |
Removes the camera from all Agents camera stacks and pops from being the active camera replacing it with the next one in the stack. |
Walkthrough
Scenario: A horror map. Players start in third-person. When they step on a pressure plate near a dark corridor, the camera switches to first-person to ramp up tension. When they leave the trigger zone, the first-person camera is removed and they return to the default view.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Place this device in your level alongside:
# - One trigger_device named EnterTrigger (player enters corridor)
# - One trigger_device named ExitTrigger (player leaves corridor)
# - One gameplay_camera_first_person_device named FPSCamera
corridor_horror_manager := class(creative_device):
# The first-person camera device placed in the level
@editable
FPSCamera : gameplay_camera_first_person_device = gameplay_camera_first_person_device{}
# Trigger at the entrance of the dark corridor
@editable
EnterTrigger : trigger_device = trigger_device{}
# Trigger at the exit of the dark corridor
@editable
ExitTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# Make sure the camera device is active and ready
FPSCamera.Enable()
# Subscribe to both triggers
EnterTrigger.TriggeredEvent.Subscribe(OnPlayerEnterCorridor)
ExitTrigger.TriggeredEvent.Subscribe(OnPlayerExitCorridor)
# Called when a player steps on the entrance trigger
# TriggeredEvent passes ?agent, so we unwrap it before use
OnPlayerEnterCorridor(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# Push first-person camera onto this player's stack
FPSCamera.AddTo(Agent)
# Called when a player steps on the exit trigger
OnPlayerExitCorridor(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# Pop first-person camera — previous camera resumes automatically
FPSCamera.RemoveFrom(Agent)
Line-by-line breakdown:
| Line | What it does |
|---|---|
@editable FPSCamera |
Exposes the camera device slot in the UEFN Details panel so you can drag in your placed device. |
FPSCamera.Enable() |
Activates the device at round start — required before it can be pushed onto any stack. |
EnterTrigger.TriggeredEvent.Subscribe(OnPlayerEnterCorridor) |
Registers the handler that fires when a player walks into the corridor trigger volume. |
OnPlayerEnterCorridor(MaybeAgent : ?agent) |
TriggeredEvent delivers ?agent (an option type). We must unwrap it with if (Agent := MaybeAgent?): before passing to AddTo. |
FPSCamera.AddTo(Agent) |
Pushes the first-person camera to the TOP of this specific player's camera stack — they instantly see first-person. |
FPSCamera.RemoveFrom(Agent) |
Pops the first-person camera from the stack — the engine automatically restores the next camera down (usually the default third-person view). |
Common patterns
Pattern 1 — All players go first-person at round start, then return to default at round end
Useful for a full FPS match mode where every player should be in first-person for the entire round.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
fps_round_manager := class(creative_device):
@editable
FPSCamera : gameplay_camera_first_person_device = gameplay_camera_first_person_device{}
# A class_designer device or timer that signals round start/end
@editable
RoundStartTrigger : trigger_device = trigger_device{}
@editable
RoundEndTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
FPSCamera.Enable()
RoundStartTrigger.TriggeredEvent.Subscribe(OnRoundStart)
RoundEndTrigger.TriggeredEvent.Subscribe(OnRoundEnd)
OnRoundStart(MaybeAgent : ?agent) : void =
# Push FPS camera onto every connected player's stack at once
FPSCamera.AddToAll()
OnRoundEnd(MaybeAgent : ?agent) : void =
# Pop FPS camera from every player's stack — all return to default
FPSCamera.RemoveFromAll()
Key call: AddToAll() and RemoveFromAll() — no need to iterate players manually. One call affects every agent currently in the session.
Pattern 2 — Disable the camera device entirely to lock it out mid-game
Sometimes you want to prevent the first-person camera from being pushed at all — for example, during a cutscene where you've taken control away from the player.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
cutscene_camera_lockout := class(creative_device):
@editable
FPSCamera : gameplay_camera_first_person_device = gameplay_camera_first_person_device{}
@editable
CutsceneStartTrigger : trigger_device = trigger_device{}
@editable
CutsceneEndTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
FPSCamera.Enable()
CutsceneStartTrigger.TriggeredEvent.Subscribe(OnCutsceneStart)
CutsceneEndTrigger.TriggeredEvent.Subscribe(OnCutsceneEnd)
OnCutsceneStart(MaybeAgent : ?agent) : void =
# Remove FPS camera from all players first, then disable the device
# so nothing can push it again while the cutscene runs
FPSCamera.RemoveFromAll()
FPSCamera.Disable()
OnCutsceneEnd(MaybeAgent : ?agent) : void =
# Re-enable the device so it can be pushed again after the cutscene
FPSCamera.Enable()
Key calls: Disable() locks the device so it cannot be activated. Enable() restores it. Always call RemoveFromAll() before Disable() to cleanly pop any active instances first.
Pattern 3 — Per-player FPS toggle via button interaction
A button in the world that toggles first-person for the individual player who pressed it — useful for optional FPS mode in a mixed-perspective game.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
fps_toggle_device := class(creative_device):
@editable
FPSCamera : gameplay_camera_first_person_device = gameplay_camera_first_person_device{}
@editable
ToggleButton : button_device = button_device{}
# Track whether each player currently has FPS active
# We use a simple per-press toggle: odd press = add, even press = remove
var FPSActiveCount : int = 0
OnBegin<override>()<suspends> : void =
FPSCamera.Enable()
ToggleButton.InteractedWithEvent.Subscribe(OnButtonPressed)
OnButtonPressed(Agent : agent) : void =
# Toggle: try to add first; if already on stack, remove instead
# In a real project you'd track per-agent state with a map
set FPSActiveCount = FPSActiveCount + 1
if (FPSActiveCount mod 2 = 1):
FPSCamera.AddTo(Agent)
else:
FPSCamera.RemoveFrom(Agent)
Key calls: AddTo(Agent) and RemoveFrom(Agent) target a single player, leaving all others unaffected. Note that button_device.InteractedWithEvent delivers a non-optional agent directly — no unwrapping needed, unlike trigger_device.TriggeredEvent.
Gotchas
1. Always Enable() before AddTo() / AddToAll()
A device that has never been enabled (or has been Disable()d) cannot be pushed onto a camera stack. Call FPSCamera.Enable() in OnBegin before any player interaction can fire.
2. TriggeredEvent delivers ?agent, not agent
trigger_device.TriggeredEvent is a listenable(?agent). Your handler signature MUST be (MaybeAgent : ?agent) and you MUST unwrap with if (Agent := MaybeAgent?): before passing Agent to AddTo or RemoveFrom. Skipping the unwrap is a compile error.
3. button_device.InteractedWithEvent delivers plain agent
Unlike trigger devices, button interaction events hand you a non-optional agent directly. Don't add an unnecessary option unwrap — it won't compile.
4. RemoveFrom before Disable
If you call Disable() while the camera is still on players' stacks, those players may be stuck with a broken camera state. Always call RemoveFromAll() first, then Disable().
5. The stack is per-player — RemoveFromAll only removes THIS device
RemoveFromAll() removes this specific gameplay_camera_first_person_device instance from every player's stack. It does NOT clear other cameras. If you have multiple camera devices, each must be removed independently.
6. No events on this device
gameplay_camera_first_person_device exposes no events of its own — it is purely imperative (you call methods; it doesn't notify you of state changes). Drive your logic from other devices' events (triggers, buttons, timers) and call the camera methods in response.
7. Experimental status
As of the 31.30 release notes, this device launched as Experimental. APIs may change before Beta. Pin your UEFN version and re-test after engine updates.