Reference Devices compiles

video_player_device: Cinematic Screens That Play on Cue

The video_player_device streams curated videos onto in-world screens or directly into a player's HUD. With Verse you can start a stream the moment a player steps into a theater, blast a clip fullscreen on a key event, seek to a highlight, or force a priority takeover — all from real device methods.

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

Overview

The video_player_device displays curated videos on in-game screens or as a picture-in-picture (PIP) overlay on a player's HUD. Think of a lobby cinema, a tutorial screen that explains the objective, a jumbotron that replays a moment, or a countdown video that plays for everyone at round start.

Reach for it whenever you want video (not just audio or text) to react to gameplay: a player enters a trigger and the trailer starts, a boss dies and a victory clip fills the screen, or one device needs to take control of every screen on the island so an important announcement can't be missed.

In Verse the device gives you fine control over when and for whom video happens. You can Enable/Disable it, push it EnterFullScreen for a single agent, shrink or grow the PIP, Restart or Seek the stream, force a TakeControl/ReleaseControl priority override, and react to the StreamStartedEvent when a player becomes the controlling viewer.

API Reference

video_player_device

Used to display curated videos onto in-game screens or player HUDs.

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

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

Events (subscribe a handler to react):

Event Signature Description
StreamStartedEvent StreamStartedEvent<public>:listenable(agent) Signaled when this device becomes the controlling streaming device for the agent.

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.
EnableCollision EnableCollision<public>():void Enables collision checks on this device.
DisableCollision DisableCollision<public>():void Disables collision checks on this device.
EnterFullScreen EnterFullScreen<public>(Agent:agent):void Transitions to fullscreen for Agent.
ExitFullScreen ExitFullScreen<public>(Agent:agent):void Transitions to fullscreen for Agent.
HidePIP HidePIP<public>(Agent:agent):void Hides the picture-in-picture video from Agent.
MakePIPDefaultSize MakePIPDefaultSize<public>(Agent:agent):void Transitions the picture-in-picture video to the default size for Agent.
MakePIPFullScreen MakePIPFullScreen<public>(Agent:agent):void Transitions the picture-in-picture video to full screen for Agent.
EndForAll EndForAll<public>():void Turns off all streaming devices of this type on the island.
Restart Restart<public>():void Restart the stream from the beginning.
Seek Seek<public>():void Seeks to the Triggered Seek Time. Caution: The stream will pause while the video buffers when seeking.
TakeControl TakeControl<public>():void Stops the currently playing stream and starts the custom stream with the audio only playing from this device. Stream Priority will not work until control is released.
ReleaseControl ReleaseControl<public>():void If any streaming device has forced control of the stream, this will release it and play the highest priority stream in line.

Walkthrough

Let's build a lobby theater. We place a video_player_device (the screen) and a trigger_device (a pressure plate at the theater entrance). When a player steps on the plate, we enable the screen, restart the clip from the top, and push it fullscreen for that player. We also subscribe to StreamStartedEvent so we know when the device has actually become the controlling stream for an agent.

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

log_theater := class(log_channel){}

lobby_theater_device := class(creative_device):

    Logger : log = log{Channel := log_theater}

    # The screen that plays the curated video.
    @editable
    Screen : video_player_device = video_player_device{}

    # The pressure plate at the theater entrance.
    @editable
    EntryPlate : trigger_device = trigger_device{}

    OnBegin<override>()<suspends>:void =
        # React when a player steps on the plate.
        EntryPlate.TriggeredEvent.Subscribe(OnPlayerEntered)
        # React when the screen becomes the controlling stream for someone.
        Screen.StreamStartedEvent.Subscribe(OnStreamStarted)
        # Make sure the screen starts off until a player arrives.
        Screen.Disable()

    # TriggeredEvent hands us an ?agent — unwrap it before use.
    OnPlayerEntered(Agent : ?agent):void =
        if (Player := Agent?):
            Screen.Enable()              # turn the screen on
            Screen.Restart()             # play from the very beginning
            Screen.EnterFullScreen(Player) # fill this player's view
            Logger.Print("Theater started for a player")

    OnStreamStarted(Player : agent):void =
        Logger.Print("Stream is now controlling for an agent")

Line by line:

  • log_theater := class(log_channel){} and Logger : log = log{Channel := log_theater} give us a named log channel so our Print calls show up tagged in the output.
  • @editable Screen : video_player_device and @editable EntryPlate : trigger_device are the fields that let us reference the placed devices. Without declaring them as editable fields, calling Screen.Enable() would fail with 'Unknown identifier'. Drag each placed device into these slots in the Details panel.
  • In OnBegin, we Subscribe the plate's TriggeredEvent to our OnPlayerEntered method and the screen's StreamStartedEvent to OnStreamStarted. Event handlers are plain methods at class scope.
  • Screen.Disable() keeps the screen dark until someone arrives.
  • OnPlayerEntered(Agent : ?agent) — the trigger's event is a listenable(?agent), so the handler receives an optional agent. if (Player := Agent?): unwraps it; everything inside only runs when a real player is present.
  • Screen.Enable() powers the device, Screen.Restart() rewinds the clip, and Screen.EnterFullScreen(Player) transitions that specific player's view to fullscreen.
  • OnStreamStarted fires when the device becomes the controlling streaming device for an agent — handy for confirming playback actually began.

Common patterns

Picture-in-picture mini-screen, then promote to fullscreen

Show the video as a small PIP corner overlay first, and only blow it up to fullscreen on a second cue (e.g. a button press).

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

pip_promoter_device := class(creative_device):

    @editable
    Screen : video_player_device = video_player_device{}

    @editable
    PromoteButton : button_device = button_device{}

    OnBegin<override>()<suspends>:void =
        PromoteButton.InteractedWithEvent.Subscribe(OnPromote)

    OnPromote(Agent : agent):void =
        Screen.Enable()
        Screen.MakePIPDefaultSize(Agent)   # show small PIP overlay for this agent
        Screen.MakePIPFullScreen(Agent)    # then grow it to fill the HUD

A priority takeover for an emergency broadcast

One announcement screen forces control of every stream on the island, then releases it when the message is done.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

broadcast_device := class(creative_device):

    @editable
    AnnounceScreen : video_player_device = video_player_device{}

    # Plate that starts the emergency broadcast.
    @editable
    StartPlate : trigger_device = trigger_device{}

    # Plate that ends it and returns to normal programming.
    @editable
    EndPlate : trigger_device = trigger_device{}

    OnBegin<override>()<suspends>:void =
        StartPlate.TriggeredEvent.Subscribe(OnStart)
        EndPlate.TriggeredEvent.Subscribe(OnEnd)

    OnStart(Agent : ?agent):void =
        AnnounceScreen.Enable()
        AnnounceScreen.TakeControl()  # forces this stream over all others, audio from here

    OnEnd(Agent : ?agent):void =
        AnnounceScreen.ReleaseControl()  # hand control back to highest-priority stream

Seek to a highlight and clean up all screens

Jump to a configured Triggered Seek Time, or shut every screen down at round end.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

highlight_device := class(creative_device):

    @editable
    Screen : video_player_device = video_player_device{}

    @editable
    SeekButton : button_device = button_device{}

    @editable
    RoundEndPlate : trigger_device = trigger_device{}

    OnBegin<override>()<suspends>:void =
        SeekButton.InteractedWithEvent.Subscribe(OnSeek)
        RoundEndPlate.TriggeredEvent.Subscribe(OnRoundEnd)

    OnSeek(Agent : agent):void =
        Screen.Enable()
        Screen.Seek()  # jumps to the device's configured Triggered Seek Time

    OnRoundEnd(Agent : ?agent):void =
        Screen.EndForAll()  # turns off ALL video_player_devices on the island

Gotchas

  • You must declare the device as an @editable field. A bare video_player_device{}.Enable() won't work — Verse needs a field bound to a placed device in the Details panel. Forgetting to assign the device in-editor leaves it empty and methods do nothing.
  • Per-agent vs. island-wide methods. EnterFullScreen, ExitFullScreen, HidePIP, MakePIPDefaultSize, and MakePIPFullScreen all take an agent and only affect that player's HUD. Enable, Disable, Restart, Seek, TakeControl, ReleaseControl, and EndForAll affect the device/stream globally. Don't expect EnterFullScreen(P) to change anyone else's view.
  • EndForAll is a nuke. It turns off every video_player_device of this type on the island, not just this one. Use it for round resets, not to stop a single screen — use Disable() for that.
  • TakeControl blocks Stream Priority. While a device holds control, Stream Priority settings are ignored until you call ReleaseControl(). Always pair them, or other screens stay stuck.
  • Seek pauses to buffer. Seeking causes the stream to pause while it buffers to the Triggered Seek Time, so a momentary stall is expected — don't treat it as a bug.
  • Unwrap optional agents. Trigger TriggeredEvent is listenable(?agent), so the handler gets ?agent. Always do if (Player := Agent?): before passing it to a per-agent method. Button InteractedWithEvent already hands a non-optional agent, so no unwrap is needed there.
  • StreamStartedEvent is listenable(agent) (non-optional) — the handler receives a plain agent you can use directly.

Device Settings & Options

The video_player_device User Options panel in the UEFN editor — every setting you can tune.

Video Player Device settings and options panel in the UEFN editor (view 1 of 3)
Video Player Device — User Options (1 of 3) in the UEFN editor
Video Player Device settings and options panel in the UEFN editor — Interact Time
Video Player Device — User Options (2 of 3) in the UEFN editor: Interact Time
Video Player Device settings and options panel in the UEFN editor — Volume, Interact Time
Video Player Device — User Options (3 of 3) in the UEFN editor: Volume, Interact Time
⚙️ Settings on this device (5)

Setting names read from the panel above — may be partial; the screenshots are the source of truth.

Video To Play
Show Border
Volume
Can Interact
Interact Time

Guides & scripts that use video_player_device

Step-by-step tutorials that put this object to work.

Build your own lesson with video_player_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 →