Player Position: Distance to the Finish Line

In this lesson you'll learn to

  • βœ“Read GetTransform().Translation, compute distance between players and props.

Read GetTransform().Translation, compute distance between players and props.

πŸ“– Reference & full walkthrough: Player Position: Distance to the Finish Line

🧩 Your capstone piece: Finish-line proximity check and nearest-checkpoint helper


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.

πŸ”’

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/player-position
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 🐻 North Jungle expedition.

β›΅ Take me there