Reference Verse compiles

Player Position: Distance to the Finish Line

Every racer, prop, and checkpoint on your island has a world position you can read from Verse: `GetTransform().Translation` hands you a `vector3`, and `Distance()` measures the gap between any two of them. This lesson turns those two calls into the finish-line proximity check and nearest-checkpoint helper that Barnaby's Jungle Mod-Rally uses to crown its winner — vector math with a dirtbike attached.

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

Every racer on Barnaby's rally route is really just a point in space — three numbers, updated every frame. Learn to read that point and compare it against the points you care about (a finish-line arch, a checkpoint marker), and suddenly you can answer the questions every race asks: did they finish? and where should they go next? This lesson is pure jungle-grade vector craft: GetTransform().Translation to read a position, Distance() to measure between two of them.

What you will build

The finish-line proximity check and nearest-checkpoint helper for Barnaby's Jungle Mod-Rally — the exact piece the capstone uses to detect the winner at Sunrise Summit. One device that:

  • reads the finish-line prop's world position once,
  • polls every racer's position on a half-second heartbeat,
  • calls the finish when someone gets within FinishRadius centimetres, and
  • answers "which checkpoint is nearest to me?" at the press of a button.

Distances in UEFN are measured in centimetres, so 500.0 means five metres. Keep that conversion taped to your monitor; it is the number-one source of "my trigger radius is the size of a coconut" bugs.

Walkthrough

Reading a position

Everything positional in Verse — a fort_character, a creative_prop, a device — carries a transform, and the part we want is its Translation: a vector3 holding world-space X, Y, Z:

Where := Body.GetTransform().Translation   # a vector3: Where.X, Where.Y, Where.Z

To get a racer's Body you walk the chain you met in the find-the-player lesson: GetPlayspace()GetPlayers()P.GetFortCharacter[] (failable — a mid-respawn racer has no body, and the if just skips them).

Measuring between two positions

/UnrealEngine.com/Temporary/SpatialMath gives you the whole measuring kit:

  • Distance(V1, V2) — straight-line distance between two vector3 values, in cm.
  • DistanceXY(V1, V2) — the same but ignoring height. Perfect for a finish line, where a jumping racer should still count.
  • DistanceSquared(V1, V2) — the distance before the square root. Cheaper, and fine when you only need to compare.

The full device

Drop a prop where your finish arch stands, scatter a few checkpoint marker props, add a button, and wire them all into this device:

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

# Watches every racer's position, calls the finish, and answers
# "which checkpoint is nearest?" on demand.
finish_line_device := class(creative_device):

    # The prop that marks the finish-line arch at Sunrise Summit.
    @editable
    FinishLine : creative_prop = creative_prop{}

    # Checkpoint marker props along the rally route, wired in course order.
    @editable
    Checkpoints : []creative_prop = array{}

    # Press this for a "which checkpoint is nearest?" hint.
    @editable
    HintButton : button_device = button_device{}

    # How close (in centimetres) counts as crossing. 500.0 = 5 metres.
    @editable
    FinishRadius : float = 500.0

    OnBegin<override>()<suspends> : void =
        HintButton.InteractedWithEvent.Subscribe(OnHintRequested)

        # Cache the finish position once -- the arch does not move.
        FinishPos := FinishLine.GetTransform().Translation
        Print("Finish line is at X={FinishPos.X} Y={FinishPos.Y} Z={FinishPos.Z}")

        var RaceOver : logic = false
        loop:
            Sleep(0.5)
            if (RaceOver?):
                break
            for (P : GetPlayspace().GetPlayers()):
                if (Body := P.GetFortCharacter[]):
                    RacerPos := Body.GetTransform().Translation
                    D := Distance(RacerPos, FinishPos)
                    if (D <= FinishRadius):
                        Print("A racer reached the finish, {D} cm from the marker!")
                        set RaceOver = true

    # Button handler: tell the presser which checkpoint is closest to them.
    OnHintRequested(Presser : agent) : void =
        if (Body := Presser.GetFortCharacter[]):
            RacerPos := Body.GetTransform().Translation
            if (Index := NearestCheckpointIndex(RacerPos)?):
                Print("Nearest checkpoint is number {Index} on the route")

    # Index of the checkpoint closest to Pos; empty when none are wired up.
    NearestCheckpointIndex(Pos : vector3)<transacts> : ?int =
        var Best : ?int = false
        var BestDist : float = 999999999.0
        for (Index -> Checkpoint : Checkpoints):
            D := Distance(Checkpoint.GetTransform().Translation, Pos)
            if (D < BestDist):
                set BestDist = D
                set Best = option{Index}
        Best

How it works, top to bottom:

  1. FinishPos := FinishLine.GetTransform().Translation — read the arch's position once, before the loop. It never moves, so there is no reason to re-ask fifty times a minute.
  2. The heartbeat loop + Sleep(0.5) — position checks do not need to run every frame. Twice a second is plenty for a finish line and costs almost nothing.
  3. P.GetFortCharacter[] — the failable bridge from player to their body. No body (mid-respawn, just joined) means the racer is skipped this tick, exactly as it should be.
  4. Distance(RacerPos, FinishPos) <= FinishRadius — the proximity check itself. One function call, one comparison.
  5. set RaceOver = true + break — first racer inside the radius ends the watch. The capstone replaces the Print with the podium sequence.
  6. NearestCheckpointIndex — the classic find-the-minimum sweep: start BestDist absurdly high, walk Checkpoints with Index -> Checkpoint, and keep whichever marker measures shortest. It returns ?int (an optional, from the optionals lesson) so an unwired checkpoint array fails gracefully instead of lying with a fake index.

Common patterns

Flat-ground check with DistanceXY

# Racers love to hit the line mid-jump. DistanceXY ignores height,
# so a racer 3 metres in the AIR above the marker still counts.
CheckFinishFlat(RacerPos : vector3, FinishPos : vector3, Radius : float) : void =
    FlatD := DistanceXY(RacerPos, FinishPos)
    if (FlatD <= Radius):
        Print("Crossed the line (flat distance {FlatD} cm)")

Compare racers without the square root

# "Who is closer?" does not need the actual distance -- comparing
# SQUARED distances gives the same winner and skips the square root.
CallTheLeader(PosA : vector3, PosB : vector3, FinishPos : vector3) : void =
    if (DistanceSquared(PosA, FinishPos) < DistanceSquared(PosB, FinishPos)):
        Print("Racer A leads!")
    else:
        Print("Racer B leads!")

Square roots are not expensive enough to fear, but when a check runs for every racer, every tick, skipping work you never needed is just good jungle hygiene.

Where this goes next

This is piece 16 of Barnaby's Jungle Mod-Rally, the north-jungle capstone. The rally imports this lesson directly: the finish gate at Sunrise Summit is exactly this Distance()-versus-radius check, and the nearest-checkpoint sweep becomes the helper that respawning riders use to rejoin the route. Pair it with the filter-an-array lesson's still_racing list and the trigger-device checkpoint sensors, and you have the whole spine of race-position logic. The distance helper itself graduates into the shared CodewoodKit module (the creating-custom-modules lesson) so east-volcano and the-deeps can measure things too — write it once, race with it everywhere.

Build your own lesson with player_position

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 →