Checkpoint Gate Prefab: async behaviour in Scene Graph components

In this lesson you'll learn to

  • βœ“Student can write a custom component whose OnSimulate runs async logic (pulse animation + trigger await) and package the gate entity as a reusable prefab.

Student can write a custom component whose OnSimulate runs async logic (pulse animation + trigger await) and package the gate entity as a reusable prefab.

πŸ“– Reference & full walkthrough: Checkpoint Gate Prefab: async behaviour in Scene Graph components

πŸ” Builds on: south-shores/the-deeps scene-graph fundamentals: entities-components, scene-graph-add-component

🧩 Your capstone piece: The CheckpointGate prefab (glow pulse, pass-through detection) instanced along the course β€” and exported for the-deeps to import (FAILS compile 5 err β€” rewrite; carries the whole async arc into components)


A Proximity Lantern: Toggle a Light With Player UI

Imagine building a tower out of LEGO blocks. You snap a red block on a base plate, then a blue block on the red one. Move the red block and the blue block travels with it. That parent/child relationship is the heart of the Scene Graph: an entity is the plastic brick, and components are the powers (a mesh for shape, a light for glow) you bolt onto it.

In this beginner guide we build a lantern controller. Rather than leaving code that only prints, we make it do something a player can see: when the game starts we add a text widget to every player's UI, and we drive a placed light device on/off. The UI is the proof the technique works.

What you'll learn

  • What an entity is (the empty backpack) and what a component is (the items inside).
  • Why Scene Graph parenting means moving the parent moves the child.
  • How to reach every player's UI with GetPlayerUI[] and AddWidget.
  • How to build and show a text_block inside a canvas.
  • How to toggle a light-style state and update the on-screen message.

How it works

An entity on its own is just a container β€” no color, no light, no sound. You give it powers with components: a mesh paints the brick so it has a shape, and a light puts an LED inside so it glows. When one entity is parented to another, moving the parent drags every child along β€” exactly like the LEGO tower.

To make the technique observable, we talk to the player UI. For each player we grab their UI with GetPlayerUI[Player] (fallible, so it lives inside an if), build a canvas holding a text_block, and call AddWidget. We drive the actual glow through a placed customizable_light_device reference, flipping a logic flag so we always know its current state. A button device lets the player toggle it.

flowchart TD ENT["Lantern entity (the backpack)"] --> MESH["mesh (the shape)"] ENT --> LIGHT["light device (the glow)"] BEGIN["OnBegin"] --> UI["AddWidget β†’ text_block on canvas"] BEGIN --> OFF["Light TurnOff β†’ lantern starts dark"] OFF -->|toggle| ON["TurnOn β†’ glows, message updates"]

One entity, two bolted-on powers β€” and the player UI shows the state.

Let's build it

Place a Light device and a Button device in your level and expose both as @editable. At OnBegin we turn the light off, show a status widget in every player's UI, and subscribe to the button. Each press flips the light and rewrites the on-screen message.

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

# Player-facing text must be a `message`, produced by a <localizes> function.
LanternOffMsg<localizes>() : message = "Lantern is OFF"
LanternOnMsg<localizes>() : message = "Lantern is ON"

# Drives a lantern light and mirrors its state in player UI.
lantern_controller := class(creative_device):

    # The placed Customizable Light device that acts as the lantern's glow (the LED in the brick).
    @editable
    LanternLight : customizable_light_device = customizable_light_device{}

    # A Button device the player presses to toggle the lantern.
    @editable
    ToggleButton : button_device = button_device{}

    # Tracks whether the lantern is currently glowing.
    var LanternOn : logic = false

    # The on-screen text we update as the state changes (the proof it works).
    var StatusText : text_block = text_block{}

    OnBegin<override>()<suspends> : void =
        set StatusText = text_block{DefaultText := LanternOffMsg()}

        # Start dark so the player can switch it on.
        LanternLight.TurnOff()
        set LanternOn = false

        # Show the status message in every player's UI.
        for (Player : GetPlayspace().GetPlayers()):
            if (UI := GetPlayerUI[Player]):
                # A canvas positions our text_block near the top of the screen.
                Canvas := canvas:
                    Slots := array:
                        canvas_slot:
                            Anchors := anchors{Minimum := vector2{X := 0.5, Y := 0.1}, Maximum := vector2{X := 0.5, Y := 0.1}}
                            Alignment := vector2{X := 0.5, Y := 0.0}
                            SizeToContent := true
                            Widget := StatusText
                UI.AddWidget(Canvas)

        # Each button press toggles the lantern and refreshes the UI text.
        ToggleButton.InteractedWithEvent.Subscribe(OnToggle)

    # Flip the light, update our flag, and rewrite the on-screen message.
    OnToggle(Agent : agent) : void =
        if (LanternOn?):
            LanternLight.TurnOff()
            set LanternOn = false
            StatusText.SetText(LanternOffMsg())
        else:
            LanternLight.TurnOn()
            set LanternOn = true
            StatusText.SetText(LanternOnMsg())```

## Try it yourself

*   Change the anchor `Y` value in the `anchors` to move the status text down the screen.
*   Add a second `text_block` to the canvas showing the player's name via interpolation.
*   Swap the button for a `trigger_device` β€” subscribe to `TriggeredEvent` instead so stepping on a pad toggles the lantern.
*   In the Scene Graph, parent the light entity under a mesh entity, then move the mesh β€” watch the glow follow.

## Recap

An **entity** is a container; **components** (mesh, light, custom Verse) give it powers, and parenting makes children follow the parent. We turned that idea into something visible: a placed `customizable_light_device` acts as the lantern glow, `GetPlayerUI[]` + `AddWidget` put a `text_block` on every player's screen, and a button toggles both the light and the message. That's the full loop β€” an entity with powers, driven by input, reflected in the player UI.
πŸ”’

Keep going β€” free

You've read the intro. The rest of this lesson is free for members. Sign in to continue and track your progress.

Sign in free to continue this lesson
Pass the quiz above to chart this quest in your Journal.

Sources

/guides/attaching-components-to-entities-in-the-verse-scene-graph
Source

Biloxi Studios original lesson

Guided course

Add this lesson to your free study plan.

🧭 The Keeper’s log

Quest complete? Chart your next heading from the πŸ¦‘ West Coves expedition.

β›΅ Take me there