Skip to main content

Actors and models

createActor loads one or more model files (typically FBX), builds skinned meshes, optional animation clips, and a Rapier collider chosen from the mesh bounds. Use actors for humanoids, creatures, and prop models that need skeletal animation rather than sprite frames or primitive shapes.

Minimal example​

website/snippets/entities/actors-and-models.ts:

import { createActor } from '@zylem/game-lib/entity';

const hero = createActor({
name: 'hero',
models: ['/assets/models/hero.fbx'],
animations: [{ key: 'idle', path: '/assets/animations/hero-idle.fbx' }],
collisionShape: 'capsule',
});

hero.onSetup(({ me }) => {
me.playAnimation({ key: 'idle' });
});

Options​

FieldPurpose
modelsModel file paths merged into the actor group
animations{ key, path } entries registered with the animation delegate
collisionShape'capsule', 'bounds', 'trimesh', or 'model' (CollisionShapeType)
scaleUniform or per-axis scale applied before collider fit
staticWhen true, collider is fixed in the world
stripRootMotionYRemoves root Y translation tracks for static previews (off by default)
materialShader / surface overrides (defaults to standard shader)

Call playAnimation with a clip key after animations load—usually from onSetup or onLoaded.

Collision shape selection​

  • capsule — best default for upright characters; cheap and stable.
  • bounds — axis-aligned box from model bounds; fast props.
  • trimesh / model — tighter fit for static level geometry; more expensive and better suited to non-dynamic bodies.

The loader picks collision source files from the model list; keep visible and collision meshes aligned in your DCC export.

Variations​

  • Multiple animation entries can share keys; the delegate resolves clips by key when you call playAnimation.
  • Actors participate in the same lifecycle and entity.use(...) pipeline as primitives—attach Platformer3DBehavior or FirstPersonBehavior when movement should drive the skeleton.
  • Use hideUntilPositioned: true when a spawner places the actor a few frames after creation.

Pitfalls​

  • Grounding — Mixamo-style exports often encode hip height in root motion; leave stripRootMotionY false unless you deliberately want to freeze vertical root tracks.
  • Async load — large FBX files finish loading after spawn; prefer onLoaded for animation that must run exactly once when clips are ready.
  • Dynamic trimesh — avoid high-density trimesh colliders on fast-moving dynamic actors; prefer capsules for players.

API reference​