logo

Babylon.js Market

Waypoint

shooter · space-combat-sim

Waypoint

1
Unlock

Install with the CLI:

bjs download Waypoint

Waypoint

An ordered run of trigger-sphere gates for a 6-DOF space game, plus the per-player progress tracker that advances through them.

What it does

WaypointSystem turns a set of gate entities into a track the player flies. Each gate is one WaypointComponent — an index in the sequence, a radius trigger sphere, and a forward unit vector toward the next gate. The player carries a single WaypointTrackComponent holding currentIndex, totalCount, and completed. Every frame the System finds the player by the player tag, reads its Transform6DOF, and looks at the one gate whose index matches currentIndex. If the ship is inside that gate's sphere it latches reached, emits wingman.waypoint.reached, and bumps currentIndex — emitting wingman.track.completed once past the final gate. If the ship instead crosses past the gate's forward plane (dot(shipPos − gatePos, forward) > radius) without entering, it latches missed and emits wingman.waypoint.missed once. Missing isn't a hard fail: the gate stays active and the player can backtrack into the sphere to recover it. The System also repaints every gate's Renderable each frame — future gates dim blue, the active gate pulsing yellow (red if overshot), reached gates green — so the cleared trail and next target read at a glance. totalCount auto-initialises from the live gate count when left at zero.

Use it in a scene

A scene is just data — a list of entities, each with its components. At startup the SceneLoader turns this JSON into a live world; edit the file and reload to rebuild it.

Build it from scratch with the bjs CLI:

  1. 1Scaffold a project
    npm create @babylonjsmarket/arcade@latest my-game

    World, renderer, and dev server — ready to run.

  2. 2Install dependencies
    cd my-game && npm install
  3. 3Add Waypoint
    bjs download Waypoint

    Copies its source into src/ so the scene resolves.

    First time? Run bjs login once.

  4. 4Paste the scene into src/scenes/arcade-room.ts and run
    npm run dev

    SceneLoader builds the world from the JSON; reload to rebuild.

JSON
{
  "Player": {
    "tags": ["player"],
    "components": {
      "Transform6DOF": { "x": 0, "y": 0, "z": 0 },
      "WaypointTrack": {}
    }
  },
  "Gate0": {
    "tags": ["waypoint"],
    "components": {
      "Transform6DOF": { "x": 0, "y": 0, "z": 260 },
      "Waypoint": { "index": 0, "radius": 80, "fx": 0, "fy": 0, "fz": 1 },
      "Renderable": { "shape": "waypoint", "sx": 80, "sy": 80, "sz": 80 }
    }
  }
}

Props

Waypoint (one per gate):

  • index (number, default 0) — place in the ordered sequence (0..n-1); the player advances gate by gate in index order.
  • radius (number, default 80) — trigger-sphere radius in world units; the ship is "in" the gate when within this distance.
  • fx / fy / fz (numbers, default [0, 0, 1]) — the forward unit vector from this gate toward the next; used only for miss detection.
  • reached (boolean, default false) — latch, set true once the ship flies through this gate.
  • missed (boolean, default false) — latch, set true once the ship crosses past without entering.

WaypointTrack (one, on the player):

  • currentIndex (number, default 0) — index of the gate that currently counts as "next".
  • totalCount (number, default 0) — number of gates; auto-fills from the live gate count when left 0.
  • completed (boolean, default false) — set true once the final gate is reached.

Events

  • Emits wingman.waypoint.reached (WaypointEvents.REACHED) on the frame the ship enters the active gate — { index, total, x, y, z }.
  • Emits wingman.waypoint.missed (WaypointEvents.MISSED) once when the ship crosses past the active gate's plane without entering — { index, total, x, y, z }.
  • Emits wingman.track.completed (WaypointEvents.COMPLETED) once, after the final gate is reached — { total }.
  • Listens for nothing — the System is driven entirely by the player's Transform6DOF position each frame.

Dependencies

  • Transform6DOF — required on both the player (its position is the trigger probe) and every gate (its position is the sphere centre and plane origin). The System's query is Waypoint + Transform6DOF.
  • Renderable — each gate needs one so the System can repaint its r/g/b/emissive to show track state. The waypoint shape draws a ring gate; the Waypoint component itself mints no mesh.

Notes

  • The player is found by the player tag (first match). No player-tagged entity, or one without a WaypointTrack, and the System idles — nothing advances.
  • forward must be a unit vector pointing at the next gate. The miss margin is one full radius past the plane (dot > radius), so a graze along the rim doesn't wrongly count as a miss.
  • Gate colours are overwritten every frame from state, so whatever r/g/b you set on a gate's Renderable is only the seed before the first tick — don't tune it for looks.
  • reached / missed / currentIndex are serialized gameplay state: a save/load round-trip restores exactly where the run left off.
  • System.priority is 55, so it runs after flight has moved the ship this frame — the trigger test sees the current pose, not last frame's.

More like this

MissionDirector
Renderable
Transform6DOF
WaveDirector
AiPilot
Animation
ArcCamera
Asteroid
Bullet
CameraFollow
CardFan
ChaseCamera6DOF
ChaseCameraTarget
DirectionalLight
Enemy
EnemySpawner
EnvironmentTexture
FlightIntent
FreighterCar
FreighterChain
FreighterHead
GameConfig
Health
HealthBar
HemisphericLight
Jump
KeyboardInput
KeyboardMover
Lifetime
LineOfSight
MachineGun
Mesh
MeshPrimitive
Missile
MissileLauncher
MoneyField
Movement
Obstacle
ObstacleField
OilBlob
Parts
Physics
PlayerFlightInput
PlayerInput
PlayerWalkAnimator
PokerHUD
PokerTableCards
RespawnTimer
Score
Scoreboard
Shadow
ShipFlight
ShipLoadout
ShooterCamera
SkeletonAnimator
SpaceDust
SpaceShooterBullet
SpaceShooterHealth
SpaceShooterScore
TwinStickShooter
WaypointTrack
WorldOriginAnchor

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search