# CameraParams

> Talos next · Since 0.6; changed in 0.7

Settings for {@link CameraHandle.set}.

Every key is optional and keeps its previous value when absent, except `distance`. Any other key is passed through to the rig.

## Signature

```ts
export interface CameraParams {
  /**
   * Vertical field of view in degrees, for every kind. Sticky: it stands until another `set` names
   * one or `follow(null)`. `null` drops it, so the scene camera's `fov` is drawn again.
   */
  fov?: number | null
  /**
   * How far the camera sees, in metres, for every kind. Absent, the scene camera's `far` decides,
   * and failing that `meta.bounds`. A value under one metre is ignored.
   */
  far?: number
  /**
   * `"orthographic"` draws the view as a box instead of a pyramid (a 2D, isometric or top-down game); `fov` is
   * then ignored. `"perspective"` switches back. Absent keeps the scene camera's `projection`. Sticky, like
   * the three lens keys below, until `follow(null)`; each one lies over the scene camera's own value.
   */
  projection?: "perspective" | "orthographic"
  /** Orthographic: half the view's height in world units. Wins over `pixelsPerUnit`. Not above zero: ignored. */
  orthoSize?: number
  /** Orthographic: pixels per world unit in the 1920 x 1080 reference view; with no `orthoSize` from scene or script, sizes the box from it (1080 / (2 × ppu)). The window draws at a whole multiple of it. */
  pixelsPerUnit?: number
  /** Orthographic: round the eye to the drawn view's screen-pixel grid so pixel art holds still. */
  pixelSnap?: boolean
  /** Boom length in metres, for `third-person`, `orbit` and `lock` (default 4.5 on `lock`). */
  distance?: number
  /** Yaw in radians about world +Y, measured the way {@link EntityHandle.teleport} measures it. */
  yaw?: number
  /** Pitch in radians; positive looks up. On `"lock"`: the pitch at distance, default -0.25; it drops towards a view from above as the target comes close. */
  pitch?: number
  /** Radius of the sphere the boom sweeps to keep itself out of geometry. Sticky: omitting it keeps the last value. */
  probeRadius?: number
  /**
   * Metres up world +Y from the follow target to the eye — the eye itself in `first-person`, the
   * pivot the boom swings around in `third-person` and `orbit`.
   *
   * Defaults to 1.65, a standing character measured from the feet, so a character scene is
   * unchanged. `0` means the anchor the script named **is** the eye, which is what a vehicle
   * wants: a car has already authored `driver-eye` and `chase-anchor` at the height it wants,
   * and the default sat an extra standing person on the roof.
   *
   * Sticky, like `probeRadius` and unlike `distance`: omitting it keeps the last value rather
   * than returning to the default. A value that is not finite is ignored.
   */
  eyeHeight?: number
  /** `"fixed"` only: a world `[x, y, z]` the rig is bolted to — makes it live without a follow target. */
  position?: [number, number, number]
  /** `"fixed"` only: `[x, y, z]` from the followed entity (the isometric follow-cam). The alternative to `position`. */
  offset?: [number, number, number]
  /**
   * `"fixed"`: a world point to look at; without one it looks at the followed entity, else along yaw/pitch.
   *
   * `"lock"`: the entity (handle or scene id) or world point to keep in frame with the player; required to take
   * the lock, then sticky. The heading turns towards it; close up the eye lifts and slides aside so the player
   * never hides it. A despawned target ends the lock; another kind eases out of it.
   */
  target?: [number, number, number] | EntityHandle | string
  /** `"lock"` only: metres above the target entity's origin that the camera aims at (its chest). Default 1. Sticky. */
  height?: number
  /**
   * `"lock"` only: where the camera looks between the followed entity's pivot (0) and the target (1). Default 0.5,
   * which frames both. Sticky.
   */
  framing?: number
  /** `"lock"` only: the fastest the heading turns towards the target, degrees per second. Default 270. Sticky. */
  turnRateDeg?: number
  /**
   * Seconds without a steer before the rig swings back behind the followed entity — the way it visibly faces:
   * a character, or a car whose chase camera comes back round after the player stops turning the view. A `set`
   * that writes a different `yaw` is a steer. `null` or a negative number turns it off. Sticky.
   */
  recenterDelay?: number | null
  /** How fast the recenter swing turns, degrees per second; default 90. Sticky. */
  recenterSpeedDeg?: number
  /**
   * Seconds of the followed entity's horizontal travel the followed point leads by, so more of the way ahead is
   * on screen: 0.3 at 10 m/s is 3 m ahead. 0 (the default) is off. Never applied to the first-person eye. Sticky.
   */
  lookAhead?: number
  /** Longest the look-ahead lead may be, metres; default 2. Sticky. */
  lookAheadMax?: number
  /** How quickly the lead settles on a new direction, per second; default 3. Sticky. */
  lookAheadRate?: number
  /**
   * `third-person` and `orbit`: arm length, metres, below which the followed character starts to fade (a
   * screen-door dither), so an arm a wall has collapsed shows the world rather than the inside of the character.
   * Default 1; 0 turns fading off. Sticky, like every wall-handling key below.
   */
  fadeStart?: number
  /** Arm length, metres, at which the character is gone entirely. Default 0.45. */
  fadeFull?: number
  /** How quickly the fade follows the arm, per second. Default 12. */
  fadeRate?: number
  /**
   * How quickly the arm grows back once a wall clears, per second. Default 5; 0 snaps back. The arm always
   * shortens at once: easing into a wall is clipping through it.
   */
  recoverRate?: number
  /**
   * Metres to shift the pivot sideways, towards the side with room, while a wall has the arm short. Default 0 (off).
   *
   * On `"lock"` it is instead the eye's sideways shift, along the camera's right (85% of it at any range, all of it with the
   * target within about 1.2 m): default 1.0, negative for the left shoulder, 0 to turn it off.
   */
  shoulder?: number
  /**
   * Swing the yaw gently away from a wall that is shortening the arm, after `avoidDelay` seconds without a steer.
   * Default false: in a game with camera-relative controls, a camera that turns by itself also turns the player's
   * "forward", and a run along a wall curves off it.
   */
  avoidWalls?: boolean
  /** Fastest the avoid swing turns, degrees per second. Default 60. */
  avoidSpeedDeg?: number
  /** How far either side the avoid feelers look, degrees. Default 30. */
  avoidAngleDeg?: number
  /** Seconds after a steer before the avoid swing may act. Default 0.5. */
  avoidDelay?: number
  [key: string]: unknown
}
```

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

## Members

| Member | Signature | Description |
|---|---|---|
| `fov` | `fov?: number \| null` | Vertical field of view in degrees, for every kind. Sticky: it stands until another `set` names one or `follow(null)`. `null` drops it, so the scene camera's `fov` is drawn again. |
| `far` | `far?: number` | How far the camera sees, in metres, for every kind. Absent, the scene camera's `far` decides, and failing that `meta.bounds`. A value under one metre is ignored. |
| `projection` | `projection?: "perspective" \| "orthographic"` | `"orthographic"` draws the view as a box instead of a pyramid (a 2D, isometric or top-down game); `fov` is then ignored. `"perspective"` switches back. Absent keeps the scene camera's `projection`. Sticky, like the three lens keys below, until `follow(null)`; each one lies over the scene camera's own value. |
| `orthoSize` | `orthoSize?: number` | Orthographic: half the view's height in world units. Wins over `pixelsPerUnit`. Not above zero: ignored. |
| `pixelsPerUnit` | `pixelsPerUnit?: number` | Orthographic: pixels per world unit in the 1920 x 1080 reference view; with no `orthoSize` from scene or script, sizes the box from it (1080 / (2 × ppu)). The window draws at a whole multiple of it. |
| `pixelSnap` | `pixelSnap?: boolean` | Orthographic: round the eye to the drawn view's screen-pixel grid so pixel art holds still. |
| `distance` | `distance?: number` | Boom length in metres, for `third-person`, `orbit` and `lock` (default 4.5 on `lock`). |
| `yaw` | `yaw?: number` | Yaw in radians about world +Y, measured the way {@link EntityHandle.teleport} measures it. |
| `pitch` | `pitch?: number` | Pitch in radians; positive looks up. On `"lock"`: the pitch at distance, default -0.25; it drops towards a view from above as the target comes close. |
| `probeRadius` | `probeRadius?: number` | Radius of the sphere the boom sweeps to keep itself out of geometry. Sticky: omitting it keeps the last value. |
| `eyeHeight` | `eyeHeight?: number` | Metres up world +Y from the follow target to the eye — the eye itself in `first-person`, the pivot the boom swings around in `third-person` and `orbit`. Defaults to 1.65, a standing character measured from the feet, so a character scene is unchanged. `0` means the anchor the script named **is** the eye, which is what a vehicle wants: a car has already authored `driver-eye` and `chase-anchor` at the height it wants, and the default sat an extra standing person on the roof. Sticky, like `probeRadius` and unlike `distance`: omitting it keeps the last value rather than returning to the default. A value that is not finite is ignored. |
| `position` | `position?: [number, number, number]` | `"fixed"` only: a world `[x, y, z]` the rig is bolted to — makes it live without a follow target. |
| `offset` | `offset?: [number, number, number]` | `"fixed"` only: `[x, y, z]` from the followed entity (the isometric follow-cam). The alternative to `position`. |
| `target` | `target?: [number, number, number] \| EntityHandle \| string` | `"fixed"`: a world point to look at; without one it looks at the followed entity, else along yaw/pitch. `"lock"`: the entity (handle or scene id) or world point to keep in frame with the player; required to take the lock, then sticky. The heading turns towards it; close up the eye lifts and slides aside so the player never hides it. A despawned target ends the lock; another kind eases out of it. |
| `height` | `height?: number` | `"lock"` only: metres above the target entity's origin that the camera aims at (its chest). Default 1. Sticky. |
| `framing` | `framing?: number` | `"lock"` only: where the camera looks between the followed entity's pivot (0) and the target (1). Default 0.5, which frames both. Sticky. |
| `turnRateDeg` | `turnRateDeg?: number` | `"lock"` only: the fastest the heading turns towards the target, degrees per second. Default 270. Sticky. |
| `recenterDelay` | `recenterDelay?: number \| null` | Seconds without a steer before the rig swings back behind the followed entity — the way it visibly faces: a character, or a car whose chase camera comes back round after the player stops turning the view. A `set` that writes a different `yaw` is a steer. `null` or a negative number turns it off. Sticky. |
| `recenterSpeedDeg` | `recenterSpeedDeg?: number` | How fast the recenter swing turns, degrees per second; default 90. Sticky. |
| `lookAhead` | `lookAhead?: number` | Seconds of the followed entity's horizontal travel the followed point leads by, so more of the way ahead is on screen: 0.3 at 10 m/s is 3 m ahead. 0 (the default) is off. Never applied to the first-person eye. Sticky. |
| `lookAheadMax` | `lookAheadMax?: number` | Longest the look-ahead lead may be, metres; default 2. Sticky. |
| `lookAheadRate` | `lookAheadRate?: number` | How quickly the lead settles on a new direction, per second; default 3. Sticky. |
| `fadeStart` | `fadeStart?: number` | `third-person` and `orbit`: arm length, metres, below which the followed character starts to fade (a screen-door dither), so an arm a wall has collapsed shows the world rather than the inside of the character. Default 1; 0 turns fading off. Sticky, like every wall-handling key below. |
| `fadeFull` | `fadeFull?: number` | Arm length, metres, at which the character is gone entirely. Default 0.45. |
| `fadeRate` | `fadeRate?: number` | How quickly the fade follows the arm, per second. Default 12. |
| `recoverRate` | `recoverRate?: number` | How quickly the arm grows back once a wall clears, per second. Default 5; 0 snaps back. The arm always shortens at once: easing into a wall is clipping through it. |
| `shoulder` | `shoulder?: number` | Metres to shift the pivot sideways, towards the side with room, while a wall has the arm short. Default 0 (off). On `"lock"` it is instead the eye's sideways shift, along the camera's right (85% of it at any range, all of it with the target within about 1.2 m): default 1.0, negative for the left shoulder, 0 to turn it off. |
| `avoidWalls` | `avoidWalls?: boolean` | Swing the yaw gently away from a wall that is shortening the arm, after `avoidDelay` seconds without a steer. Default false: in a game with camera-relative controls, a camera that turns by itself also turns the player's "forward", and a run along a wall curves off it. |
| `avoidSpeedDeg` | `avoidSpeedDeg?: number` | Fastest the avoid swing turns, degrees per second. Default 60. |
| `avoidAngleDeg` | `avoidAngleDeg?: number` | How far either side the avoid feelers look, degrees. Default 30. |
| `avoidDelay` | `avoidDelay?: number` | Seconds after a steer before the avoid swing may act. Default 0.5. |

## Example

The tested fixture `fixtures/app/agent.ts`.

```ts
import type { Behavior } from "@argus/api"

// Sends a nav agent to `props.target` once, then reports arrival through ctx.state so the
// test can read it without polling the crowd directly.
export default {
  init(ctx) {
    ctx.state.arrived = false
    ctx.nav?.goTo(ctx.props.target as [number, number, number])
  },
  update(ctx) {
    if (ctx.nav?.arrived) ctx.state.arrived = true
  },
} satisfies Behavior
```
