Taos API Reference
    Preparing search index...

    Class CameraController

    Dual free-fly + orbit camera controller, in the spirit of PlayCanvas's CameraControls.

    CameraController.mode selects the active scheme; both share the same yaw/pitch + position state, so flipping between them mid-session is seamless (orbit pivots around whatever is in front of you; fly slides off from wherever you were orbiting).

    Fly mode ('fly', default) — FPS-style: WASD (or arrows) for horizontal movement, ControlLeft (or AltLeft) for a 3× speed boost, and a switchable vertical scheme (see CameraController.verticalKeyMode): 'hybrid' (default, either pair), Space/ShiftLeft, or KeyE/KeyQ to ascend/descend. When usePointerLock is true, clicking the canvas acquires pointer lock and mouse motion drives yaw/pitch; when false, left-drag looks around. Middle-drag dollies along the view and right-drag pans the camera in its view plane. The mouse wheel dollies along the view direction (see CameraController.wheelDolly).

    Orbit mode ('orbit') — turntable around a focus point at CameraController.focusDistance: left-drag orbits, middle-drag dollies (drag to zoom, three.js-style), right-drag (or Shift+left-drag) pans the focus, and the wheel zooms (clamped to CameraController.minDistance/CameraController.maxDistance). WASD still flies the focus point along the view. CameraController.focusOn recenters the pivot. Enable CameraController.enableDamping for eased, inertia-like orbit/pan/zoom and a smooth fly-to on focus.

    As a component (recommended) — add the controller to the camera's GameObject and the engine drives it for you: it auto-attaches its DOM listeners (to the engine canvas) and updates against its owner every frame, so no engine.beforeFrame(...) plumbing is needed:

    cameraGO.addComponent(CameraController.create({ ... }));
    

    Standalone — for non-engine drivers (raw render-graph samples, the editor, tests), call CameraController.attach once, then CameraController.update every frame against the camera's GameObject.

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    yaw: number

    Yaw in radians, rotation around world Y.

    pitch: number

    Pitch in radians, rotation around local X (clamped to ±89°).

    speed: number

    Movement speed in world units per second.

    sensitivity: number

    Mouse sensitivity in radians per pixel of movement.

    worldUp: Vec3 = ...

    World-space "up" the controls are relative to. Defaults to +Y (a flat world). Set it to the local surface normal — e.g. the radial direction from a planet's center — to free-fly around a curved body: yaw orbits this up, pitch tilts about the resulting right, Space/Shift move along it, and the horizon stays level as you move. The control frame is the shortest-arc rotation from +Y to this vector, so yaw/pitch keep their world-+Y meaning when it's +Y (unchanged behavior). Re-set it each frame for a moving camera on a sphere.

    moveRelativeToView: boolean = false

    When true, movement is relative to the full view orientation (6-DOF free-fly): forward follows the look direction including pitch, strafe the camera right, and Space/Shift the camera's own up. When false (default), movement uses the surface frame — horizontal forward in the yaw plane (pitch ignored), vertical along worldUp. Set it true in space, where worldUp is detached from the body and a horizontal frame no longer matches the view (W would drift sideways, Space/Shift off-axis).

    inputForward: number = 0

    Analog forward input in [-1, 1] (touch joystick / programmatic).

    inputStrafe: number = 0

    Analog strafe input in [-1, 1] (positive = right).

    inputUp: boolean = false

    Held-up flag (OR-ed with the active ascend key).

    inputDown: boolean = false

    Held-down flag (OR-ed with the active descend key).

    verticalKeyMode: "eq" | "space-shift" | "hybrid" = 'hybrid'

    Which keyboard keys drive vertical (up/down) movement. 'hybrid' (default) accepts both schemes — Space or KeyE to ascend, ShiftLeft or KeyQ to descend; 'space-shift' uses only Space to ascend and ShiftLeft to descend; 'eq' uses only KeyE to ascend and KeyQ to descend. Switch this live to flip between the schemes.

    inputFast: boolean = false

    Held-fast flag (OR-ed with ControlLeft / AltLeft).

    usePointerLock: boolean = false

    Set false to suppress pointer-lock acquisition on canvas click (touch devices).

    wheelDolly: boolean = true

    When true (default), rolling the mouse wheel over the canvas dollies the camera forward/backward along the view direction. Set false to ignore wheel input.

    dollySpeed: number = 1

    World units the camera dollies per wheel notch (scaled by speed).

    mode: CameraControlMode = 'fly'

    Active control scheme. 'fly' (default) is FPS free-fly; 'orbit' turntables around the focus point. Flip it live — the shared yaw/pitch/position state makes the switch seamless.

    focusDistance: number = 10

    Orbit-mode distance from the camera to its focus point, in world units. Also the implicit pivot distance used when entering orbit from fly.

    minDistance: number = 0.1

    Minimum focusDistance the wheel zoom will clamp to (orbit mode).

    maxDistance: number = Infinity

    Maximum focusDistance the wheel zoom will clamp to (orbit mode).

    minPitch: number = -HALF_PI

    Pitch clamp, radians. Defaults to ±89° (just shy of gimbal lock).

    maxPitch: number = HALF_PI
    orbitSpeed: number = 0.005

    Per-pixel rotation rate for orbit drag. Defaults to sensitivity.

    panSpeed: number = 1

    Pan rate multiplier (orbit middle/right-drag). Scaled by focusDistance.

    zoomSpeed: number = 0.1

    Wheel zoom rate (orbit mode); each notch scales focusDistance by exp(±this).

    enableDamping: boolean = false

    When true, orbit/pan/zoom (and focus fly-to) are eased toward their targets instead of applied instantly. Off by default so fly mode stays frame-exact with existing samples.

    damping: number = 0.12

    Damping time-constant in seconds when enableDamping is set (smaller = snappier).

    id: string = ...

    Stable identity for this component, unique within a session. Auto-generated for runtime-created components; the editor overwrites it with a persistent id when projecting a saved document so references survive save / load / undo.

    enabled: boolean = true

    Whether this component participates in simulation and rendering. When false, the GameObject skips its update/updateRender and the scene's render collectors (mesh renderers, camera, lights, …) ignore it — the component stays attached and keeps its state, like Unity's Behaviour.enabled / Renderer.enabled. Defaults to true.

    gameObject: GameObject

    The owning GameObject; assigned by addComponent before onAttach runs.

    _sceneAttached: boolean = false

    True between onAttach and onDetach — i.e. while this component sits on a GameObject that is part of a live Scene. Managed by GameObject. Internal — do not set directly.

    Accessors

    • get time(): Time

      The simulation clock of the scene this component belongs to. Read inside update (or any time after the GameObject is added to a scene) for absolute time, frame count, FPS, and timeScale-aware delta — e.g. this.time.elapsed, this.time.delta, this.time.frameCount.

      this.time.delta equals the dt argument passed to update, so components can ignore that argument entirely and pull everything from here.

      Returns Time

      if the owning GameObject is not currently part of a scene.

    Methods

    • Injects a key as if it were currently held.

      Use when the controller is attached after the physical keydown event already fired (e.g. double-tap toggle).

      Parameters

      • code: string

        KeyboardEvent.code value, e.g. 'KeyW'.

      Returns void

    • Adds the given delta to yaw and pitch (with the same sensitivity scaling as mouse movement). Used by touch-drag look handlers and similar programmatic camera input.

      Parameters

      • dx: number

        Horizontal movement in pixels (positive = right).

      • dy: number

        Vertical movement in pixels (positive = down).

      Returns void

    • Recenters the orbit focus on a world-space point (orbit mode), optionally setting a new focusDistance. With enableDamping on, the camera eases (flies) to the new framing; otherwise it snaps. Yaw/pitch are unchanged, so the viewing angle is preserved.

      Parameters

      • point: Vec3

        World-space point to orbit around.

      • Optionaldistance: number

        Optional new distance from the camera to that point.

      Returns void

    • Seed yaw/pitch from the owning GameObject's current orientation, so the controller keeps facing where the transform points instead of snapping to its stored yaw/pitch the next time it updates. Call this after the camera has been posed via its transform and that facing should be preserved — e.g. an editor entering play mode on an authored camera. Inverts the same yaw · pitch (under the surface worldUp tilt) composition that update builds, so it round-trips exactly.

      Returns void

    • Advances the controller, applying input to the GameObject's position and rotation.

      Yaw and pitch are composed as independent quaternions so the camera never accumulates roll.

      Two call forms:

      • As a Component the engine invokes update(dt) during scene.update, driving the controller's owning GameObject. It attaches its DOM listeners to the scene's presentation canvas (the engine canvas standalone; the Game view in the editor), so adding the controller to the camera is all the wiring an app needs.
      • Standalone drivers call update(gameObject, dt) against an explicit GameObject (after a manual attach).

      Parameters

      • dt: number

        Frame delta time in seconds.

      Returns void

    • Advances the controller, applying input to the GameObject's position and rotation.

      Yaw and pitch are composed as independent quaternions so the camera never accumulates roll.

      Two call forms:

      • As a Component the engine invokes update(dt) during scene.update, driving the controller's owning GameObject. It attaches its DOM listeners to the scene's presentation canvas (the engine canvas standalone; the Game view in the editor), so adding the controller to the camera is all the wiring an app needs.
      • Standalone drivers call update(gameObject, dt) against an explicit GameObject (after a manual attach).

      Parameters

      • gameObject: GameObject

        GameObject whose transform represents the camera.

      • dt: number

        Frame delta time in seconds.

      Returns void

    • Connect to a Signal with automatic disconnect when this component is removed from its GameObject — the safe default for cross-object listening, so a destroyed component never leaks into (or gets called by) a signal it once observed. Typically called from onAttach:

      onAttach(): void {
      const health = this.gameObject.getComponent(Health)!;
      this.listen(health.died, () => this.playDeathEffect());
      }

      Type Parameters

      • A extends unknown[]

      Parameters

      Returns () => void

      The unsubscribe function, for listeners that also want to disconnect early; calling it is optional and idempotent.

    • Called when the component joins a live scene — from addComponent when the GameObject is already in a scene, otherwise when the GameObject is added to one. this.gameObject.scene (and scene.engine) is always set here. Override to acquire references to siblings/children or initialize resources.

      Returns void

    • Called when this component's GameObject begins touching another body, with the GameObject it collided with. Dispatched by the physics system after each world step (only while playing), so handlers may freely mutate the scene. Requires a physics body (RigidBody / CharacterBody) on the object.

      Parameters

      • _other: GameObject

        The other GameObject involved in the contact.

      Returns void

    • Called every frame by the GameObject's render traversal, after update and any input/controller mutations to the transform. Override to refresh per-frame state that render passes consume (e.g. Camera recomputes its cached view/projection matrices here).

      Parameters

      • _ctx: RenderContext

        Active render context (provides canvas width/height etc.).

      Returns void