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.