# CameraHandle

> Talos 0.6 · Since 0.6

The active camera rig.

While a script drives it — it follows something, or a `"fixed"` rig was given a `position` — the rig is the rendered view and the listener; otherwise the scene's primary `camera` entity is.

Reached in a behaviour as `ctx.camera`.

## Signature

```ts
export interface CameraHandle {
  /** Switch rigs; `params` are the rig's settings, per kind: see {@link CameraParams}. */
  set(kind: CameraKind, params?: CameraParams): void
  /**
   * What the rig tracks. `null` returns the view to the scene's primary camera and forgets every
   * `set` param, `fov` included.
   */
  follow(target: EntityHandle | string | null): void
  /**
   * The engine rig's yaw now, radians: what the last `set` left it at, or wherever a `recenterDelay` swing
   * has taken it since. Camera-relative movement reads this rather than keeping its own copy, so that a
   * recenter turns the controls with the view.
   */
  readonly yaw: number
  /** The engine rig's pitch now, radians; positive looks up. */
  readonly pitch: number
  /**
   * The heading of the view actually being drawn, radians about +Y with 0 facing -Z: the rig when a
   * script drives one, else the scene's primary camera; 0 with no camera at all. Measured at the top of
   * the tick. This is the frame an `inputBasis: "camera"` controller reads its stick in, so a behaviour that
   * turns stick input into a world direction itself (`input: "script"`) reads it to agree with the engine:
   * forward is `[-sin(viewYaw), 0, -cos(viewYaw)]`.
   */
  readonly viewYaw: number
  /**
   * The vertical field of view being drawn, degrees: what a script set with `set(kind, { fov })`,
   * else the scene's primary camera's `fov`, else 60. A rig that names no fov of its own (the
   * built-in first-person rig by default) draws at this.
   */
  readonly fov: number
  /**
   * How much of the world the view shows while its lens is orthographic, and the viewport it fills:
   * see {@link ViewSize}. `null` while the lens is perspective, which shows a different width at every
   * distance. The lens is read live (a `set` that changes `orthoSize`, `pixelsPerUnit` or `projection`
   * is seen at once), the window's size as of the top of the tick. What a 2D follow camera keeps inside
   * a level with, whatever the window's aspect.
   */
  readonly viewSize: ViewSize | null
  /** The engine rig's boom this frame: its length, whether a wall collapsed it, what did, and the character fade. */
  readonly arm: CameraArm
}
```

Import: `import type { CameraHandle } from "@argus/api"`

## Members

| Member | Signature | Description |
|---|---|---|
| `set` | `set(kind: CameraKind, params?: CameraParams): void` | Switch rigs; `params` are the rig's settings, per kind: see {@link CameraParams}. |
| `follow` | `follow(target: EntityHandle \| string \| null): void` | What the rig tracks. `null` returns the view to the scene's primary camera and forgets every `set` param, `fov` included. |
| `yaw` | `readonly yaw: number` | The engine rig's yaw now, radians: what the last `set` left it at, or wherever a `recenterDelay` swing has taken it since. Camera-relative movement reads this rather than keeping its own copy, so that a recenter turns the controls with the view. |
| `pitch` | `readonly pitch: number` | The engine rig's pitch now, radians; positive looks up. |
| `viewYaw` | `readonly viewYaw: number` | The heading of the view actually being drawn, radians about +Y with 0 facing -Z: the rig when a script drives one, else the scene's primary camera; 0 with no camera at all. Measured at the top of the tick. This is the frame an `inputBasis: "camera"` controller reads its stick in, so a behaviour that turns stick input into a world direction itself (`input: "script"`) reads it to agree with the engine: forward is `[-sin(viewYaw), 0, -cos(viewYaw)]`. |
| `fov` | `readonly fov: number` | The vertical field of view being drawn, degrees: what a script set with `set(kind, { fov })`, else the scene's primary camera's `fov`, else 60. A rig that names no fov of its own (the built-in first-person rig by default) draws at this. |
| `viewSize` | `readonly viewSize: ViewSize \| null` | How much of the world the view shows while its lens is orthographic, and the viewport it fills: see {@link ViewSize}. `null` while the lens is perspective, which shows a different width at every distance. The lens is read live (a `set` that changes `orthoSize`, `pixelsPerUnit` or `projection` is seen at once), the window's size as of the top of the tick. What a 2D follow camera keeps inside a level with, whatever the window's aspect. |
| `arm` | `readonly arm: CameraArm` | The engine rig's boom this frame: its length, whether a wall collapsed it, what did, and the character fade. |

## Example

The tested fixture `fixtures/host/door.ts`.

```ts
import type { Behavior } from "@argus/api"
// docs/API.md, "Joints": a door on a hinge that swings open while the player is near and closes
// behind them. Typechecked by packages/api's tests.
export default {
  update(ctx) {
    const player = ctx.world.find("player")
    const near = player !== null && ctx.entity.distanceTo(player) < 2
    ctx.joint?.setMotor(near ? Math.PI / 2 : 0, { mode: "position", maxForce: 200 })
  },
} satisfies Behavior
```
