logo
Mesh

core

Mesh

Free

Install with the CLI:

bjs download Mesh

Mesh

Loads file-based GLB / glTF models through the renderer adapter and optionally makes them follow a sibling proxy.

What it does

MeshComponent is pure loader state — a small idle → loading → loaded | error machine holding the source URL, transform, and (once loaded) the renderer's handle id plus the animation clip names it discovered. MeshSystem drives it renderer-agnostically: it auto-loads on attach via this.world.renderer.loadMesh(...) (or, for instanced pools of identical animated characters, a deduped loadModelTemplate + per-entity instantiateModel), recording the result back on the component. It emits mesh.loading, mesh.loaded (carrying meshId + animationNames), and mesh.error at each transition, and listens for mesh.load to (re)trigger a load. When follow is set, each frame it copies a sibling MeshPrimitive proxy's XZ position onto the mesh and yaws it toward its movement or aim direction.

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.

Fastest path

bjs download scene Mesh

Pulls this exact scene into your project and runs it — no copy-paste. Add --all to grab the components and assets it needs too.

Or 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 Mesh
    bjs download Mesh

    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
{
  "Character": {
    "components": {
      "MeshPrimitive": {
        "primitive": "capsule",
        "radius": 0.5,
        "height": 1.6,
        "position": [0, 0.8, 0],
        "visible": false
      },
      "Mesh": {
        "src": "/models/character.glb",
        "follow": true,
        "scale": 1,
        "autoLoad": true
      }
    }
  }
}

Props

  • src (string, default "") — URL/path to the .glb/.gltf; required before a load can start.
  • position (Vec3, default [0,0,0]) — world-space position applied after load; in follow mode only Y is used (ground/feet offset).
  • rotation (Vec3, default [0,0,0]) — Euler rotation in radians applied after load.
  • scale (number, default 1) — uniform scale.
  • autoLoad (boolean, default true) — trigger a load automatically on entity attach.
  • assetServerUrl (string, default "") — prepended to src to build the final URL.
  • instanced (boolean, default false) — load via shared template + cheap per-entity clones; use for pools of identical animated characters.
  • follow (boolean, default false) — each frame copy the sibling MeshPrimitive's XZ and yaw the mesh toward its facing direction.
  • faceMode ('velocity' | 'proxy', default 'velocity') — face travel direction (velocity) or copy the proxy's own yaw (proxy), e.g. for a twin-stick aim.
  • yawOffset (number, default 0) — radians added to the facing yaw in follow mode.
  • lockRootMotion (boolean, default false) — strip baked horizontal root motion so clips play in place (instanced/template path).

Events

  • emits mesh.loading — a load request was dispatched to the renderer.
  • emits mesh.loaded — model finished loading; payload carries meshId + animationNames.
  • emits mesh.error — the renderer rejected the load; payload carries the error message.
  • listens mesh.load — kick a load for { entityId, src? }; src overrides the component's current value.

Dependencies

MeshPrimitive — supplies the sibling proxy whose position/rotation the mesh reads each frame in follow mode (typically an invisible capsule that gameplay moves).

Notes

  • The System never touches BabylonJS or Three directly — all loading and transform calls go through this.world.renderer (the adapter), so the component is renderer-agnostic.
  • instanced loads can't complete until the shared template finishes; the System keeps retrying each frame and the state stays loading until the clone exists. One loadModelTemplate is issued per URL across the whole pool, then one instantiateModel per entity.
  • With follow, the mesh's own Y comes from position[1] (feet offset) while X/Z track the proxy — make the proxy MeshPrimitive invisible so only the loaded model shows.
  • Pooled (instanced) entities keep their clone and follow state when parked (hidden, not disposed) for cheap re-acquire; a true destroy disposes the clone.

More like this

AnimateMeshy
BoatMode
MeshPrimitive
Shadow
SkeletonAnimator
AiPilot
Animation
ArcCamera
Asteroid
Bullet
CameraFollow
DirectionalLight
EnemySpawner
EnvironmentTexture
Flash
FreighterCar
FreighterChain
FreighterHead
GameConfig
Health
HemisphericLight
Jump
KeyboardInput
KeyboardMover
LensFlare
Lifetime
LineOfSight
MachineGun
Missile
MissileLauncher
MissionDirector
MouseInput
Movement
NebulaSky
Obstacle
ObstacleField
OilBlob
Parts
Physics
PlayerInput
PlayerWalkAnimator
Renderable
RespawnTimer
RoadTreadmill
RoundReset
Score
ShipDamageFX
ShipLoadout
Skybox
SmokeScreen
SpaceDust
SpaceShooterBullet
SpaceShooterFX
SpaceShooterHealth
SpaceShooterScore
ToneMapping
Transform6DOF
TwinStickEnemy
WaveDirector
Waypoint
WaypointTrack

Was this page helpful?

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

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search