# @ferret/character: API

Character movement (capsule, walk, run, jump, steps, slopes), cameras and the player controller.

12 exports. Generated from the source (`packages/character/src`), so it matches the code.

## Classes

### CameraRig

*class* · `packages/character/src/camera.ts:45`

```ts
class CameraRig
```

The player's camera: first or third person, switchable at run time. The third-person boom is a spring arm: it is
shortened when a wall is in the way, so the camera never clips into the level. Inputs of Babylon's own are removed.

- `readonly camera: BABYLON.FreeCamera`
- `view: ViewMode`
- `yaw: number`
- `pitch: number`
- `distance: number`
- `currentDistance: number` — the boom length actually used after collision
- `readonly o: Required<Omit<CameraRigOptions, 'mask'>> & { mask: number }`
- `boom: ExternalBoom | null` — a boom fixed on something else than the character (a ride); `update` uses it in place of the first/third person camera while it is set
- `constructor(scene: BABYLON.Scene, private physics: PhysicsService, opts: CameraRigOptions = {})`
- `toggleView()`
- `setView(v: ViewMode)`
- `zoom(delta: number)`
- `look(dyaw: number, dpitch: number)`
- `groundForward(out = new BABYLON.Vector3())` — Forward on the ground plane for the current yaw (what "move forward" means).
- `groundRight(out = new BABYLON.Vector3())`
- `setBoom(b: ExternalBoom | null)` — Fix the camera on a boom of its own (or back on the character with null).
- `blendFromCurrent(duration: number, exp = 2)` — Start a timed blend from where the camera is now to wherever `update` puts it (UE: SetViewTargetWithBlend, ease in-out).
- `get blending()`
- `update(feet: BABYLON.Vector3, dt: number)` — Place the camera for a rendered frame; `feet` is the interpolated position of the character.

### CharacterMovement

*class* · `packages/character/src/movement.ts:70`

```ts
class CharacterMovement extends Component<CharacterParams>
```

Capsule character movement against static geometry: walk, run, crouch, jump, step up, slopes, ground snapping,
moving platforms. The same component moves the player and NPCs; they differ only in who sets the move input.
The entity's node must be a Babylon Mesh (it carries the collision ellipsoid); its origin is at the feet.

- `p: Required<Omit<CharacterParams, 'groundMask'>> & { groundMask?: string[] }`
- `velocity: Vector3`
- `grounded: boolean`
- `groundNormal: Vector3`
- `groundMesh: BABYLON.AbstractMesh | null`
- `crouching: boolean`
- `running: boolean`
- `submerged: number` — 0..1: the part of the body inside water or mud (capability D); swimming when most of it is and the feet are off the ground
- `swimming: boolean`
- `yaw: number`
- `flying: boolean` — flying (UE: MOVE_Flying): no gravity, no ground; the vertical speed follows `setVerticalInput` times `verticalSpeed`; the horizontal speed is walk/run speed as on the ground
- `verticalSpeed: number` — m/s at full vertical input in flying mode
- `prevPosition: Vector3` — where the body was at the previous fixed step (camera interpolation)
- `get mesh(): BABYLON.Mesh`
- `get height()`
- `get speed2d()`
- `onAttach()`
- `onDetach()`
- `setMoveInput(dir: BABYLON.Vector3, run = false)` — Desired movement in world space; its length (0..1) scales the speed. The vertical part is used only while swimming: Unreal swims along the view direction, pitch included.
- `jump()`
- `setVerticalInput(v: number)` — Flying mode: -1..1, up positive.
- `setFlying(on: boolean)` — Switch flying mode on or off (off: the character falls and lands by the normal rules).
- `motionState()` — what an Animator needs to know (see MotionSource in
- `setCrouch(on: boolean)`
- `shift(d: BABYLON.Vector3): BABYLON.Vector3` — Move the capsule horizontally by `d` now, with collisions and step-ups, outside the velocity model (room-scale VR: the player walked in the room). Returns the distance actually moved.
- `teleport(pos: BABYLON.Vector3)`
- `onFixedUpdate(dt: number)`
- `renderPosition(alpha: number, out = new BABYLON.Vector3())` — The interpolated position for the render frame (the camera follows this).

### PlayerController

*class* · `packages/character/src/player.ts:41`

```ts
class PlayerController extends Component<PlayerParams>
```

The player controller: input actions -> movement and camera. First and third person; the third-person body faces
where it moves, the first-person body faces where the camera looks.

- `viewOverride: ViewOverride | null` — Another owner of the view (a VR headset: the head owns the camera). While it is set, the controller does not move or aim the camera rig, `look` / `turn` are left to the owner, and "forward" is `yaw()`.
- `rig: CameraRig`
- `movement: CharacterMovement`
- `onAttach()`
- `get view(): ViewMode`
- `setView(v: ViewMode)`
- `toggleView()`
- `onFixedUpdate(dt: number)`
- `onUpdate(dt: number)`
- `onDetach()`

## Functions

### easeInOut

*function* · `packages/character/src/camera.ts:6`

```ts
function easeInOut(a: number, exp = 2): number
```

UE's FMath::InterpEaseInOut(0, 1, a, exp): slow at both ends.

### spawnCharacter

*function* · `packages/character/src/movement.ts:433`

```ts
function spawnCharacter(world: World, name: string, position: BABYLON.Vector3, params: CharacterParams & { layer?: string } = {}): { entity: Entity; movement: CharacterMovement; mesh: BABYLON.Mesh }
```

A character entity: an invisible Mesh with the collision ellipsoid, a Collider on the Pawn layer and CharacterMovement.

## Interfaces

### CameraRigOptions

*interface* · `packages/character/src/camera.ts:23`

```ts
interface CameraRigOptions
```

- `view?: ViewMode`
- `eyeHeight?: number` — metres above the feet where the eyes are (first person) and the boom pivots (third person)
- `distance?: number` — third person: distance behind the pivot, and its limits for zoom
- `minDistance?: number`
- `maxDistance?: number`
- `shoulder?: number` — third person: sideways offset of the pivot (over the shoulder)
- `pitchMin?: number`
- `pitchMax?: number`
- `probe?: number` — third person: radius kept free between the camera and the walls
- `mask?: number` — layers the spring arm collides with

### CharacterParams

*interface* · `packages/character/src/movement.ts:5`

```ts
interface CharacterParams
```

Parameters follow UE's Character Movement Component, in metres and seconds.

- `radius?: number`
- `height?: number`
- `crouchHeight?: number`
- `eyeHeight?: number`
- `walkSpeed?: number`
- `runSpeed?: number`
- `crouchSpeed?: number`
- `jumpVelocity?: number` — initial vertical speed of a jump (UE: JumpZVelocity)
- `gravity?: number`
- `mass?: number` — kg: how much push a character has against water or mud (capability D), with `thrust`
- `bodyDensity?: number` — kg/m³: below the density of the water it floats, above it sinks (people are about 985)
- `thrust?: number` — m/s²: the push the character can make against drag in a medium (swimming, wading); the speed it reaches there follows from it
- `swimSpeed?: number` — m/s: UE MaxSwimSpeed. Set, a character in a dense medium (swimming) moves at exactly this speed whatever the walk, run or crouch state, as Unreal's swimming mode does; unset, the speed follows from `thrust` and the drag
- `buoyancy?: number` — UE Buoyancy: 1 = neutral (the weight is carried completely in the medium), below 1 sinks, above 1 rises. Unset: the density ratio medium / bodyDensity decides
- `outOfWaterZ?: number` — UE OutofWaterZ, m/s: the upward speed of the water jump (swimming against a ledge, the input pointing up)
- `jumpOutOfWaterPitch?: number` — UE JumpOutOfWaterPitch, degrees: the water jump needs the swim input to point at least this far above the horizon
- `maxOutOfWaterStepHeight?: number` — UE MaxOutOfWaterStepHeight, m: how far above the body's centre the ledge may be for a water jump
- `swimAcceleration?: number` — m/s²: UE MaxAcceleration while swimming (the push along the 3D swim input)
- `fluidFriction?: number` — UE PhysicsVolume FluidFriction (0.3 by default) of the water; with BrakingDecelerationSwimming 0 a stopped swimmer coasts by it times BrakingFrictionFactor 2
- `maxWindAccel?: number` — m/s²: the most the wind (the `flow` service) can push the character; 0 turns the wind off for it (a game's cap)
- `maxStepHeight?: number`
- `walkableAngle?: number` — steepest slope that can be walked, degrees (UE: WalkableFloorAngle)
- `acceleration?: number`
- `braking?: number`
- `airControl?: number` — fraction of the ground acceleration available in the air
- `snapDistance?: number` — how far below the feet the ground is still "ground" when walking down
- `groundMask?: string[]` — layer names the character collides with when probing the ground
- `faceMovement?: boolean` — turn the body to face where it moves (third person); first person sets the yaw from the camera
- `turnRate?: number`
- `flyAcceleration?: number` — flying mode: m/s²: how fast the vertical speed follows `setVerticalInput`

### ExternalBoom

*interface* · `packages/character/src/camera.ts:12`

```ts
interface ExternalBoom
```

A boom on a point of the game's own (a mount's seat): UE's spring arm with camera lag and an absolute rotation.

- `pivot: () => BABYLON.Vector3` — where the boom is fixed, world space, metres (read every frame)
- `arm: number` — boom length, metres
- `socketZ?: number` — lift of the camera above the boom's end (UE: SocketOffset.Z), metres
- `lag?: number` — camera lag speed (UE: CameraLagSpeed); 0 = no lag

### PlayerActions

*interface* · `packages/character/src/player.ts:8`

```ts
interface PlayerActions
```

The names of the game's actions that the controller reads. Anything left out is simply not used.

- `move?: string`
- `look?: string`
- `turn?: string`
- `jump?: string`
- `run?: string`
- `crouch?: string`
- `view?: string`
- `zoom?: string`

### PlayerParams

*interface* · `packages/character/src/player.ts:19`

```ts
interface PlayerParams
```

- `actions?: PlayerActions`
- `camera?: CameraRigOptions`
- `turnSpeed?: number` — rad/s at full `turn`
- `alwaysRun?: boolean` — a console has no run button: run when the stick is fully pushed, or always
- `bodyInFirstPerson?: boolean` — first person: show the body (arms/legs)
- `body?: BABYLON.AbstractMesh[]` — meshes that make up the visible body; hidden in first person unless bodyInFirstPerson

### ViewOverride

*interface* · `packages/character/src/player.ts:32`

```ts
interface ViewOverride
```

- `yaw(): number` — the yaw "move forward" follows, radians

## Types

### ViewMode

*type* · `packages/character/src/camera.ts:3`

```ts
type ViewMode = 'first' | 'third'
```

