Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commite8beb5604c

README.md

camera_controls

Camera control utilities — fly and orbit controllers built on the entity camera API (entity.find("camera").camera.*). Each controller activates an input map and subscribes to the move, look, zoom and flyVertical controls on it, so the same camera answers from a keyboard, a pad and a touch surface. Each call returns an object with update(dt) plus introspection methods; call :update(dt) once per frame from your component update, and :release() when the controller goes away.

Deprecated: prefer @builtin::controller.* components on the camera entity. This compatibility module remains for controllers that need custom orbit logic (e.g. model_viewer auto-rotate) and will be removed after full migration.

Exports

  • M.createFlyController(opts: FlyOpts?) -> FlyController — fly controller driven by move, look, zoom and flyVertical.
  • M.createOrbitController(opts: OrbitOpts?) -> OrbitController — orbit-around-center controller: look orbits, move pans the center, zoom changes the distance.

Types:

  • FlyOpts = { inputMap?, moveSpeed?, rotateSpeed?, zoomSpeed?, distance?, minDistance?, maxDistance?, logMouse? }
  • OrbitOpts = { inputMap?, center?, distance?, yaw?, pitch?, minPitch?, maxPitch?, minDistance?, maxDistance?, invertPitchInput?, moveSpeed?, rotateSpeed?, zoomSpeed? }
  • FlyController = { update, release, lastMousePos, distance }
  • OrbitController = { update, release, setCenter, setDistance, setYawPitch, yawPitch, distance, lastMousePos }

Usage

local CameraControls = require("@builtin::modules.extras.camera_controls")

local ctrl = CameraControls.createOrbitController({
    center      = { x = 0, y = 0.8, z = 0 },
    distance    = 5,
    moveSpeed   = 5,
    rotateSpeed = 0.005,
    zoomSpeed   = 0.1,
})

-- in update(dt):
ctrl:update(dt)
local mousePos = ctrl:lastMousePos() -- { x, y } or nil

-- when the controller goes away:
ctrl:release()

Notes

  • opts.inputMap names the map; @builtin::inputMaps.editor is the default. Each controller holds its own activation, so two of them do not share one reading, and :release() is what takes the controls back out of the live set.
  • Each constructor calls Zin.autoTick.start() so the controls keep dispatching across frames.
  • Vertical movement comes from the flyVertical control, which a map is free to leave out — a map without it drives everything else.
  • The look control carries its own gate, so a mouse steers only while the camera is being flown while a stick or a touch drag steers whenever it is pushed.
  • WASM-safe: no string.format numeric formats, no Rust APIs.