Skip to content

Input and camera ​

Both belong to one player, so both are for ClientScripts. A server Script that touches input or camera gets an error saying so.

Keys ​

lua
input.onKey("E", function()        -- pressed (not while the player types in the chat or a text box)
    net.send("interact")
end)

if input.isDown("LeftShift") then  -- held right now?
    print("sprinting")
end

Key names: "A" to "Z", "Zero" to "Nine", "Space", "Return", "Tab", "Backspace", "Escape", "LeftShift", "RightShift", "LeftControl", "RightControl", "LeftAlt", "RightAlt", "Up", "Down", "Left", "Right".

For everything - mouse buttons too, and key releases - use the raw events:

lua
input.began:connect(function(inputObject, typing)
    if typing then return end            -- the player is typing in the chat or a box
    print(inputObject.type, inputObject.key)
end)

input.ended:connect(function(inputObject, typing)
    if inputObject.key == "LeftShift" then print("stopped sprinting") end
end)

Keys the game already uses

W A S D walk, Space jumps, Shift is camera lock, 1-0 pick tools, Tab the player list, Enter and / the chat, Esc the menu. Pick other keys for your game's own actions - E, F, Q, R...

On phones there is no keyboard: give every action a button on screen too (Scripting UI), or use a Prompt, which phones can tap.

What the mouse is over ​

lua
game.frame:connect(function()
    local hit = world:raycast(camera:ray())   -- from the camera through the pointer
    if hit then
        marker.position = hit.position
    end
end)

camera:ray(distance?) returns an origin and a direction through the pointer - the mouse, the middle of the screen in camera lock or first person, or the last touch - 1,000 units long unless you say.

The camera ​

Until a script changes it, the camera is the game's own: it follows the character, the mouse turns it, the wheel zooms, and it keeps out of walls.

MemberWhat it is
camera.mode"Follow" (the game's camera), "Fixed" (stays where a script puts it), "FirstPerson" (always the eyes)
camera.transformWhere it is and the way it looks. Setting it fixes the camera there
camera.positionWhere it is; setting it fixes the camera
camera.fovField of view, 20 to 100 degrees (45 to start)
camera.targetWhat "Follow" orbits: a part, another player, or nil for your own character
camera.minZoom, camera.maxZoomHow near and far the wheel zooms, 0.5 to 400 units
camera.offsetMoves the point the camera turns about (x right, y up, z behind)
camera.firstPersonTrue while the camera is the character's eyes (read-only)
camera.firstPersonArmsIn first person, draw the player's own arms (true)
camera.viewportSizeThe screen's size in UI points (read-only)
camera:toScreen(position)Where a point in the world is on the screen, and whether it is in front
camera:tween(goals, time)Smooth changes - a zoom, a cutscene

Examples ​

lua
-- An overhead camera
camera.transform = transform.lookAt(vec3(0, 60, 40), vec3(0, 0, 0))
camera.fov = 50

-- Back to normal
camera.mode = "Follow"
lua
-- A sprint that widens the view
input.began:connect(function(i, typing)
    if not typing and i.key == "LeftShift" then camera:tween({fov = 60}, 0.2) end
end)
input.ended:connect(function(i)
    if i.key == "LeftShift" then camera:tween({fov = 45}, 0.2) end
end)
lua
-- A cutscene: fly between two parts, then give the camera back
camera:tween({transform = world.Shot1.transform}, 2).completed:wait()
camera:tween({transform = world.Shot2.transform}, 3).completed:wait()
camera.mode = "Follow"
lua
-- Spectate another player
camera.target = someOtherPlayer
lua
-- A marker over a part, in screen UI
local where, inFront = camera:toScreen(world.Goal.position)
marker.visible = inFront
marker.position = dim.px(where.x, where.y)

First person ​

Every world lets players zoom all the way in to first person, as Roblox does. To change how the camera starts for everyone, insert Camera settings (Insert > Camera settings) and set its Mode, Min zoom, Max zoom, Field of view, Arms in first person and Offset in the Inspector. A Min zoom of 2 or more keeps players out of first person.

A ClientScript changes its own player's camera from there:

lua
-- A shooter: always first person, wide view, the pointer back for the shop
camera.mode = "FirstPerson"
camera.fov = 80

local shop = players.me.gui:waitFor("Shop")
input.onKey("B", function()
    shop.visible = not shop.visible
    input.mouseFree = shop.visible       -- show the pointer while the shop is open
end)

game.frame:connect(function()
    if camera.firstPerson then
        local hit = world:raycast(camera:ray(300))   -- what the crosshair is on
    end
end)

Camera lock ​

Players press Shift (or the padlock button on phones) for camera lock: the camera sits over the right shoulder, the pointer is hidden with a crosshair in the middle, and the body always faces where the camera looks. camera:ray() then goes through the crosshair. input.mouseFree = true frees the pointer here too.