First-Person Controller
Write a first-person character controller - WASD movement, mouse-look, and jump, with real capsule collision against the level - as an ordinary script you attach to a player object.
Awaken does not bake a controller into the engine. Instead the engine exposes two generic primitives every game needs - mouse-look input (pointer lock + per-frame mouse deltas) and a capsule move-and-slide helper - and you write the controller logic on top of them as a normal script. This tutorial builds the standard rig on those primitives - a capsule player, a camera the script drives, and a per-frame update that looks, moves, and collides - all using the ScriptApi surface (api.moveAndSlide, api.input) the engine provides for it.
Coming soon
This tutorial is being written. The step outline below is final and the two engine primitives it relies on - api.moveAndSlide and api.input.mouseDX/mouseDY - are already implemented, so you can follow the shape today. Finished prose, a tuned sample script, and screenshots are on the way. A ready-made player prefab shipped as starter content is planned but not yet bundled - for now you assemble the rig yourself, which this tutorial teaches.
What you will build
A player you can walk around a level in first person. The capsule collides with walls and floors (slopes and small steps are handled by the character controller), the mouse looks around after you click to lock the pointer, Space jumps, and the camera follows at eye height. The controller is a single script asset with tunable Inspector params, so you can reuse it in any project.
The rig
- Player - a GameObject with a capsule Collider at human size (radius ≈ 0.35 m, height ≈ 1.8 m) and the controller Script attached. The capsule is what collides; there is no
RigidBody- the character controller is kinematic, so you move it and physics resolves the slide. - Camera - an ordinary Camera object that the script keeps at the player's eye height and pitches up/down. You hand it to the script as a
camerareference param, so the controller stays generic.
Before you start
- Complete Make Your First Game - you need the create/script/Play loop.
- Read Input (mouse deltas + pointer lock) and Physics: Character Controller (how
moveAndSlideresolves collisions).
Steps
Build the player. Create → Capsule, rename it
Player, and add a Collider (kind: capsule, radius 0.35, height 1.8) in the Inspector. See Colliders.Add a camera. Create → Camera. You will reference it from the script rather than parenting it, so the script can control its exact pose each frame.
Declare the controller's params. In the Code panel, start a
ScriptBehaviorwhose public fields become Inspector controls (see Inspector Parameters):tsexport default class implements ScriptBehavior { camera: Entity; // object picker - assign your Camera moveSpeed = 5; // m/s mouseSensitivity = 0.0025; jumpHeight = 1.2; // m eyeHeight = 1.6; // m above the player origin gravity = 20; // m/s² private yaw = 0; private pitch = 0; private vy = 0; // onUpdate below… }Look. In
onUpdate, accumulateyaw -= api.input.mouseDX * this.mouseSensitivityandpitch -= api.input.mouseDY * this.mouseSensitivity(clamp pitch to ≈ ±1.55 rad). Rotate the player body byyawabout world-Y; applypitchto the camera. Mouse deltas are only non-zero while the pointer is locked - clicking the Game view locks it (api.input.pointerLocked). See Input.Move. Build a horizontal input vector from WASD in the player's yaw frame and scale by
moveSpeed.Gravity & jump. Integrate
this.vy -= this.gravity * dt; if grounded and Space is down, setthis.vy = Math.sqrt(2 * this.gravity * this.jumpHeight); zerovywhen grounded and falling.Collide. Move the capsule with the engine primitive and read back whether you landed:
tsconst { grounded } = api.moveAndSlide(move.x * dt, this.vy * dt, move.z * dt);The capsule is promoted to a kinematic character body on the first call; walls block, slopes and small steps are handled. See Character Controller.
Follow with the camera. Place the camera at
playerPos + (0, eyeHeight, 0)with the composed yaw·pitch rotation (reach it via thecameraref).Attach and assign. Add the Script component to
Player, then set thecameraparam to your Camera object in the Inspector.Play. Press ▶ Play, click the Game view to lock the pointer, and walk the level. Esc releases the pointer. Press ■ Stop to restore the scene.
📸 Screenshot - save as img/tutorials-fps-controller-params.png
The controller Script component in the Inspector: the camera object-picker (assigned to the scene Camera) above the moveSpeed, mouseSensitivity, jumpHeight, eyeHeight, and gravity fields.
Where to go next
- Give the level materials and mood with Author a Custom Material.
- Publish your playable build with Ship to a URL.
See also
- Input - pointer lock and
mouseDX/mouseDY - Physics: Character Controller - how
moveAndSlideresolves collisions - ScriptApi Reference -
moveAndSlide,raycast, and the full surface - Inspector Parameters - turning
camerainto an object-reference picker - Colliders - authoring the capsule collider