Phaser AE

Orbit Camera Rig

Free packv3.0.0-23DRigs

The camera for any 3D game where the camera looks at something rather than out of something. Drag to orbit, wheel to zoom, `follow` to chase, and the rig handles the easing, the limits and the ground, so your game code never touches the camera.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 14, 2026 · updated October 19, 2026

Orbit Camera Rig: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

The pack

rigOrbit

function rigOrbit(opts: OrbitOptions = {}): Pack<{ rig: OrbitRigApi }>

The orbit rig: drag turns the camera, the wheel pulls it in and out, and follow eases the point it orbits onto an object — which is all a chase camera is. Requires a 3D world; it writes only the camera's yaw, pitch, distance and focus.

Types

OrbitOptions

interface OrbitOptions

Manifest options.

  • distance?: number — Starting distance from the focus, world units. Default 12.
  • minDistance?: number — Closest the wheel may pull in. Default 2.
  • maxDistance?: number — Furthest the wheel may push out. Default 200.
  • yaw?: number — Starting yaw, radians. Default 0.6.
  • pitch?: number — Starting pitch, radians; positive looks down. Default 0.35.
  • minPitch?: number — Lowest pitch a drag may reach. Default −0.2 (a shade below level).
  • maxPitch?: number — Highest pitch, looking straight down. Default 1.45.
  • sensitivity?: number — Radians per pixel dragged. Default 0.01.
  • invertY?: boolean — Drag up to look up rather than down. Default false.
  • zoomSpeed?: number — Distance change per wheel notch. Default 0.01 per unit of wheel delta.
  • smoothing?: number — How quickly the focus catches a followed object: 1 is instant, 0.1 is a lazy chase. Default 0.15.
  • drag?: boolean — Drag to orbit. Set false to drive yaw and pitch yourself. Default true.
  • pan?: boolean — Right-drag, or shift-drag, moves the focus in the screen plane. Default true.
  • zoomToCursor?: boolean — The wheel dollies toward the POINT UNDER THE CURSOR rather than the middle of the screen. Default true, and it is the difference between a camera that inspects a scene and one that fights you: zooming to the centre means every zoom is followed by a pan to put back what you were looking at.
  • autoRotate?: number — Idle spin, radians a second. Pauses while dragging or flying. Default 0 — off.
  • fly?: boolean — WASD / arrows to move and Q/E to rise and fall, shift for three times the speed. Default false.
  • flySpeed?: number — Fly speed, world units a second. Default scales with distance, so it stays sane at any zoom.

OrbitRigApi

interface OrbitRigApi

game.rig: the orbit camera.

  • follow(target: Handle | null): void — Follow an object: the focus eases to it every step. Pass null to stop.
  • focus(x: number, y: number, z: number): void — Point the focus at a fixed place (and stop following).
  • readonly target: Handle | null — The object being followed, or null.
  • readonly focusX: number — Where the focus is now, world x — after following, panning and flying have had their say. v2's rig exposed its pivot as a live point; here the setter is focus() and these are the readback.
  • readonly focusY: number — The focus's world y.
  • readonly focusZ: number — The focus's world z.
  • readonly eye: { x: number; y: number; z: number } — Where the EYE actually is this step, derived from the focus, the angles and the distance.
  • minPitch: number — The lowest pitch a drag may reach, radians. Live — a first-person eye and a chase cam want different floors.
  • maxPitch: number — The highest pitch a drag may reach, radians. Live.
  • distance: number — Distance from the focus; the wheel drives this too. Clamped to minDistance/maxDistance.
  • minDistance: number — Closest the camera may come, world units. Default 2. The wheel and any code that writes distance are both clamped: a wheel that runs to zero puts the eye inside the subject, which every orbit demo hits within a few seconds of scrolling.
  • maxDistance: number — Furthest it may go. Default 200. Raising it never leaves the camera stranded beyond the new ceiling.
  • yaw: number — Orbit angle, radians.
  • pitch: number — Pitch, radians; positive looks down.
  • height: number — Height above the followed object the focus aims at (head height rather than feet). Default 0.
  • drag: boolean — Turn the drag-to-orbit handling off and on.
  • pan: boolean — Right-drag or shift-drag pans the focus. Live.
  • zoomToCursor: boolean — The wheel dollies toward the cursor. Live.
  • zoomSpeed: number — Distance change per unit of wheel delta; 0 turns the wheel off. Live, so a game can enable the wheel it composed off.
  • autoRotate: number — Idle spin, radians a second; 0 is off. Live.
  • fly: boolean — WASD / arrows fly, Q/E rise and fall. Live, so a demo can turn a chase camera into a free probe without rebuilding the rig. The first fly key STICKS the rig into EXPLORE mode: from then on a drag LOOKS AROUND from where the camera is instead of swinging it about the focus. Keys move you through the world, the mouse turns your head — which is the only model that makes sense once you have left the thing you were orbiting.
  • flySpeed: number — Fly speed, world units a second; 0 scales it with distance. Live.
  • floor: ((x: number, z: number) => number) | null — GROUND CLAMP: the world height at (x, z). The EYE never sinks below it plus floorMargin, so a low orbit glides along the terrain instead of tunnelling into it. rig.floor = (x, z) => terrain.heightAt(x, z). Null is off.
  • floorMargin: number — How far the eye stays above floor. Default 1.5.
  • enabled: boolean — Release the camera and ignore input. Default true.
  • exploring: boolean — True once a fly key has put the rig into explore mode; assigning false hands it back to orbiting.