logo
MotionTrail

fx · physics-puzzle

MotionTrail

Listens toGravityBody
1
Unlock

Install with the CLI:

bjs download MotionTrail

MotionTrail

A glowing ribbon that tapers away behind a moving mesh: a comet tail on a rock, an exhaust streak on a ship.

What it does

MotionTrail: {} beside a MeshPrimitive drags a ribbon behind the mesh, full width at the head and nothing at the tail. Babylon's TrailMesh draws it, unlit and additive so it reads as light, and it joins the scene's glow layer when there is one.

The ribbon follows an anchor, not the mesh: a node that copies the mesh's position each frame and turns to face the way it moves. Hang a trail on a tumbling rock and the tail tumbles with it. Sweep it along the wrong axis and its round cross-section flattens into a strip, which vanishes edge-on in one of the two views. The anchor keeps the ribbon square to the motion, whatever the rock is doing.

The System's job is timing, and pooling is what makes timing hard. A pooled rock is parked at one end of the map and handed out again at the other, and a trail that kept recording would draw one long streak across the field. So:

  • Parked, the trail stops and hides.
  • Handed out again, it stays hidden one more frame. The mesh sits at its parking spot until MeshPrimitive's restore moves it.
  • On the next frame it collapses onto the mesh's new spot and shows.

A rock that jumps through a wormhole hits the same problem mid-flight. On gravity.body.jumped, its trail collapses onto the far mouth on the frame the rock comes out, instead of streaking back across the field.

Setup

The engine work ships with the component, in adapter/register.ts. A project made with bjs create installs it for you: src/main.ts calls every adapter/register.ts that bjs download puts in the project, before the scene loads. If you boot the game from your own code, call it once, right after building the adapter:

TypeScript
import { registerMotionTrailExtension } from './Components/MotionTrail/adapter/register';

const adapter = new BabylonAdapter();
registerMotionTrailExtension(adapter);
const game = new ArcadeGame(adapter, { … });

Without it there are no trails, and the System warns once, the first frame something is trailed.

Use it in a scene

A SpaceGolf ship, circling on its own with OrbitMover:

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 MotionTrail
    bjs download MotionTrail

    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
{
  "World": {
    "tags": ["world"],
    "components": { "GlowLayer": { "intensity": 0.85 } }
  },
  "Ship": {
    "components": {
      "MeshPrimitive": {
        "primitive": "box",
        "width": 3,
        "height": 0.55,
        "depth": 1.1,
        "material": { "diffuseColor": [0.28, 0.3, 0.36], "emissiveColor": [0.45, 0.08, 0.05] }
      },
      "OrbitMover": { "radius": 6, "speed": 0.5, "faceMotion": true },
      "MotionTrail": { "width": 0.45, "length": 34, "color": [1, 0.5, 0.18], "alpha": 0.7 }
    }
  }
}

Props

  • width (number, default 0.3) — size of the ribbon at the head, in world units. Babylon uses it as a radius, so the head is twice this across.
  • length (number, default 36) — frames of history the ribbon holds. Rounded down, never below 2.
  • color (RGB, default [0.35, 0.85, 1]) — ribbon colour.
  • alpha (number, default 0.65) — peak opacity, 0 to 1.

Events

  • gravity.body.jumped (listens) — restarts the trail of the body named in bodyId, where it came out.

Emits nothing.

Dependencies

  • MeshPrimitive — the mesh the ribbon follows. Nothing is drawn until the mesh exists.

Notes

  • The look is read when the trail is built. A live edit to width or color shows only once the trail is rebuilt, for example by removing and re-adding the component.
  • length counts frames, so the same trail stretches further at a lower frame rate.
  • MotionTrail runs after GravityBody (priority 10 against 50). GravityBody moves the rock before it sends the jump, so the reset lands on the far mouth that same frame. Keep that order if you change priorities.
  • A destroyed entity's trail is removed. A parked one is only hidden, so a pool slot keeps its trail for life.
  • The plugin is Babylon only. Under Three.js or Babylon Lite there are no trails.

More like this

GravityBody
MeshPrimitive
AxisViewCamera
BlackHole
CaptureZone
DirectionalLight
EnvironmentTexture
Flash
GravityLens
GravityMass
HemisphericLight
LensFlare
MassDriver
Mesh
NebulaSky
PointerDrag
Renderable
RoadTreadmill
Shadow
ShipDamageFX
Skybox
SmokeScreen
SpaceDust
SpaceGolfDirector
SpaceGolfHUD
SpaceRock
SpaceShooterFX
Spin
ToneMapping
TrajectoryPreview
WhiteHole
Wormhole

Was this page helpful?

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

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search