Skip to content

Reading Input

Call input methods directly on this.world inside onUpdate() to query keyboard and mouse state each frame. There is no world.input accessor — all methods are on the World instance itself.

ts
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";

export default class Example extends Behaviour {
  onUpdate() {
    // held this frame
    if (this.world.getKey(KeyboardKeys.Space)) { /* … */ }

    // only true on the first frame the key goes down
    if (this.world.getKeyDown(KeyboardKeys.E)) { /* … */ }

    // only true on the frame the key is released
    if (this.world.getKeyUp(KeyboardKeys.E)) { /* … */ }
  }
}

API

All methods are called directly on this.world:

MethodDescription
this.world.getKey(key)true while the key is held.
this.world.getKeyDown(key)true only on the first frame the key is pressed.
this.world.getKeyUp(key)true only on the frame the key is released.
this.world.getMouse(button)true while the mouse button is held. "left" / "middle" / "right".
this.world.getMouseDown(button)true only on the first frame the button is pressed.
this.world.getMouseUp(button)true only on the frame the button is released.
this.world.getMousePosition(){ x, y } in viewport pixels.
this.world.getMouseDelta(){ x, y } pointer movement since the last frame.
this.world.consumeMouseDelta(){ x, y } movement since last frame; zeroes the delta after reading.
this.world.getScrollDelta(){ x, y } scroll wheel delta since the last frame.

KeyboardKeys reference

All constants are available from the KeyboardKeys import. Pass any of them to getKey / getKeyDown / getKeyUp.

ts
import { KeyboardKeys } from "@relu-interactives/spatial-ecs";

Letters

KeyboardKeys.A through KeyboardKeys.Z

Digits

KeyboardKeys.Digit0 through KeyboardKeys.Digit9

ConstantKey
KeyboardKeys.ArrowUp↑ Arrow
KeyboardKeys.ArrowDown↓ Arrow
KeyboardKeys.ArrowLeft← Arrow
KeyboardKeys.ArrowRight→ Arrow
KeyboardKeys.SpaceSpace
KeyboardKeys.EnterEnter / Return
KeyboardKeys.EscapeEscape
KeyboardKeys.TabTab
KeyboardKeys.BackspaceBackspace
KeyboardKeys.DeleteDelete
KeyboardKeys.InsertInsert
KeyboardKeys.HomeHome
KeyboardKeys.EndEnd
KeyboardKeys.PageUpPage Up
KeyboardKeys.PageDownPage Down

Modifier keys

Generic variants match either the left or right physical key. Use the specific variant when the side matters.

ConstantPhysical key
KeyboardKeys.ShiftEither Shift key
KeyboardKeys.ShiftLeftLeft Shift
KeyboardKeys.ShiftRightRight Shift
KeyboardKeys.ControlEither Ctrl key
KeyboardKeys.ControlLeftLeft Ctrl
KeyboardKeys.ControlRightRight Ctrl
KeyboardKeys.AltAlt / Option
KeyboardKeys.MetaCmd (macOS) / Win key
KeyboardKeys.CapsLockCaps Lock

Function keys

KeyboardKeys.F1 through KeyboardKeys.F12

Punctuation & symbols

ConstantKey
KeyboardKeys.Minus-
KeyboardKeys.Equal=
KeyboardKeys.BracketLeft[
KeyboardKeys.BracketRight]
KeyboardKeys.Backslash\
KeyboardKeys.Semicolon;
KeyboardKeys.Quote'
KeyboardKeys.Backquote`
KeyboardKeys.Comma,
KeyboardKeys.Period.
KeyboardKeys.Slash/

Other

ConstantKey
KeyboardKeys.NumLockNum Lock
KeyboardKeys.ScrollLockScroll Lock
KeyboardKeys.PausePause / Break
KeyboardKeys.PrintScreenPrint Screen
KeyboardKeys.ContextMenuContext Menu

Examples

WASD movement with sprint

ts
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";

export default class Movement extends Behaviour {
  speed = 5;
  sprintMultiplier = 2;

  onUpdate() {
    const step = this.speed * (this.world.getKey(KeyboardKeys.Shift) ? this.sprintMultiplier : 1) * this.deltaTime;

    if (this.world.getKey(KeyboardKeys.W)) this.transform.position.z -= step;
    if (this.world.getKey(KeyboardKeys.S)) this.transform.position.z += step;
    if (this.world.getKey(KeyboardKeys.A)) this.transform.position.x -= step;
    if (this.world.getKey(KeyboardKeys.D)) this.transform.position.x += step;
  }
}

One-shot action on key press and mouse click

getKeyDown fires only on the frame the key transitions from up to down, so it is safe to use for one-shot actions.

ts
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";

export default class ActionHandler extends Behaviour {
  onUpdate() {
    if (this.world.getKeyDown(KeyboardKeys.Space)) {
      console.log("Jump!");
    }

    if (this.world.getMouseDown("left")) {
      const pos = this.world.getMousePosition();
      console.log("Fired at", pos.x, pos.y);
    }
  }
}

Distinguishing left vs right modifier

ts
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";

export default class ModifierDemo extends Behaviour {
  onUpdate() {
    if (this.world.getKeyDown(KeyboardKeys.ControlLeft)) {
      console.log("Left Ctrl");
    }
    if (this.world.getKeyDown(KeyboardKeys.ControlRight)) {
      console.log("Right Ctrl");
    }

    // Matches either Shift key
    if (this.world.getKey(KeyboardKeys.Shift)) {
      console.log("Shift held");
    }
  }
}

Mouse-delta camera look

ts
import { Behaviour } from "@relu-interactives/spatial-ecs";

export default class CameraLook extends Behaviour {
  sensitivity = 0.002;

  onUpdate() {
    const { x, y } = this.world.consumeMouseDelta();
    this.transform.rotation.y -= x * this.sensitivity;
    this.transform.rotation.x -= y * this.sensitivity;
  }
}

For InputSystem internals and pointer-lock details, see the InputSystem guide.