Manage Player Health with Verse and On-Screen UI
Tutorial intermediate

Manage Player Health with Verse and On-Screen UI

Updated intermediate

What you'll learn

By the end of this tutorial you will be able to:

  1. Read a player's live health with the GetHealth[] API (it lives on fort_character, not on player).
  2. Modify health safely with SetHealth (a <transacts> mutation clamped between 1.0 and GetMaxHealth).
  3. Build a real HUD with GetPlayerUI[], a text_block, a canvas, and AddWidget so the health value updates on screen every tick.

How it works

Health state is exposed through the healthful interface, which is implemented by fort_character — the in-world character an agent/player controls. So the flow is always: playerGetFortCharacter[] → call GetHealth[]/SetHealth(...).

To drive continuous updates we subscribe to the playspace tick event. GetTickEvent().Subscribe(...) hands us a callback that fires each frame with a DeltaTime, and returns a cancelable we store so we can Cancel() it in OnEnd.

For UI we can't just "set text on a player" — we ask each player for their personal UI surface with GetPlayerUI[], then add a canvas containing a text_block. We keep a reference to that text_block per player so each tick we call SetText(...) to refresh the number. Note that GetHealth[], GetFortCharacter[], and GetPlayerUI[] are all fallible (they use [] and must run inside an if), while SetHealth, SetText, and AddWidget are ordinary calls.

Let's build it

This device caches one text_block per player, then updates health and the on-screen readout every tick — auto-healing anyone below 50 HP.

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

health_hud_device := class<concrete>(creative_device):

    # Per-player readout widgets, so each player sees their own health.
    var Readouts : [player]text_block = map{}

    # Store the tick subscription so we can cancel it on shutdown.
    var TickSub : ?cancelable = false

    OnBegin<override>()<suspends>: void =
        # Build a HUD readout for every player currently in the playspace.
        for (P : GetPlayspace().GetPlayers()):
            CreateReadout(P)

        # Drive continuous updates from the playspace tick event.
        set TickSub = option{ GetPlayspace().GetTickEvent().Subscribe(OnTick) }

    # Build a canvas + text_block on this player's personal UI surface.
    CreateReadout(Player:player):void =
        if (UI := GetPlayerUI[Player]):
            NewText : text_block = text_block{ DefaultText := "Health: --" }
            NewCanvas : canvas = canvas:
                Slots := array:
                    canvas_slot:
                        Anchors := anchors{ Minimum := vector2{X := 0.05, Y := 0.05}, Maximum := vector2{X := 0.05, Y := 0.05} }
                        Offsets := margin{ Top := 0.0, Left := 0.0, Bottom := 0.0, Right := 0.0 }
                        Widget := NewText
            UI.AddWidget(NewCanvas)
            # Remember the widget so OnTick can refresh it.
            if (set Readouts[Player] = NewText) {}

    # Runs every frame with the elapsed DeltaTime.
    OnTick(DeltaTime:float):void =
        for (P : GetPlayspace().GetPlayers()):
            # GetFortCharacter and GetHealth are fallible -> must sit in an if.
            if (Char := P.GetFortCharacter[], Text := Readouts[P]):
                Current : float := Char.GetHealth[]
                # Auto-heal anyone below 50 HP (SetHealth clamps to max).
                if (Current < 50.0):
                    Char.SetHealth(Current + 10.0)
                # Refresh the on-screen number via interpolation.
                Text.SetText(StringToMessage("Health: {Round[Current]}"))

    # Helper: build a message from a string for SetText.
    StringToMessage<localizes>(S:string):message = "{S}"

    OnEnd<override>():void =
        # Clean up the tick subscription.
        if (Sub := TickSub?):
            Sub.Cancel()

Try it yourself

  1. Drop the health_hud_device into your island — no editable fields needed; it discovers players automatically.
  2. Press play with at least one player. A Health: NN readout appears in the top-left corner.
  3. Take some damage until you drop below 50 HP and watch the auto-heal tick you back up in 10-point steps.
  4. Extend it: change the anchor to reposition the readout, or add a color change by swapping to a red text_block when Current < 25.0.
  5. Add a second text_block slot to show Char.GetMaxHealth[] alongside current health.

Recap

You now know that health lives on the healthful interface reached via GetFortCharacter[], that GetHealth[] is fallible (bind it in an if) while SetHealth(...) is a <transacts> mutation clamped to the valid range, and that a real HUD is built by requesting each player's GetPlayerUI[] surface and AddWidget-ing a canvas/text_block you refresh every tick. This foundation scales up to damage flashes, shield bars, and health-gated abilities.

Check your understanding

Test yourself with an interactive quiz and track your progress + earn XP — free for members.

Turn this into a guided course

Add Managing Player Health State via Verse to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.

Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.

Comments

    Sign in to vote, comment, or suggest an edit. Sign in