Skip to content

UserInputService

Keyboard and mouse input on the player’s device.

  • Get it: import { UserInputService } from '@rally/sdk'

Use UserInputService in LocalScripts. On the server it exists, but its events never fire.

inputBegan and inputEnded report keys by their KeyboardEvent.code name ('KeyE', 'Space', 'ShiftLeft', 'ArrowUp') and mouse buttons as 'MouseLeft', 'MouseMiddle' and 'MouseRight'. Holding a key doesn’t repeat inputBegan. When the game loses focus, every held key and button is released. gameProcessed is true when the input went to UI (typing in a TextBox, clicking a button) rather than the game; games usually ignore those.

The backtick key opens the in-game developer console, so scripts don’t receive it (except while typing in a TextBox). On touch screens the game plays without changes: an on-screen joystick and jump button drive the default controls (and press KeyW/KeyA/KeyS/KeyD and Space), dragging the view fires mouseMoved, a tap is a MouseLeft click, fingers report as Touch1, Touch2, …, and every key your LocalScripts listen for gets an on-screen button (addTouchButton adds your own).

Type: Vector2 · Access: read-only

Where the pointer is, in pixels from the top-left of the game view.

Type: boolean · Access: read-only

The pointer is locked to the game (3D mouse look: click the game to lock, Esc to unlock). First-person games only turn the view while this is true.

Type: boolean · Access: read-only

True on devices with a touch screen.

Type: InputType · Access: read-only

'touch' or 'keyboardMouse': what the player used last. A touch laptop or a tablet with a keyboard switches as they do; the on-screen controls follow it.

Type: Vector2 · Access: read-only

Size of the game view in CSS pixels (a phone turning sideways changes it).

Type: SafeAreaInsets · Access: read-only

Pixels at each screen edge hidden by a notch, rounded corners or the home bar. Keep important UI inside them.

Type: boolean · Access: read/write

Show the on-screen joystick on touch devices (it drives the built-in controls).

Type: boolean · Access: read/write

Show the on-screen Jump button on touch devices.

Type: boolean · Access: read/write

On by default: the keys your LocalScripts compare against get on-screen buttons on touch devices.

Type: boolean · Access: read/write

The built-in WASD/arrow/space movement and camera controls. Turn off to drive the character and camera yourself.

Turning them off also stops mouse-wheel zoom and hides the on-screen touch controls.

isKeyDown(key: string): boolean

True while key is held: a key name such as 'KeyW' or a mouse button such as 'MouseLeft'.

addTouchButton(key: string, label?: string): void

Adds an on-screen touch button that presses key ('KeyF', 'MouseRight', …) while a finger is on it. Use it for keys your scripts build at run time, or with autoTouchButtons = false.

removeTouchButton(key: string): void

Takes away an on-screen button that addTouchButton added for key. Nothing happens if there isn’t one.

Arguments: input: InputObject, gameProcessed: boolean

Fires when a key or mouse button is pressed.

Arguments: input: InputObject, gameProcessed: boolean

Fires when a key or mouse button is released.

Arguments: delta: Vector2

Fires with pixels moved (mouse locked or not).

Arguments: type: InputType

Fires with the new lastInputType when the player switches between touch and keys or mouse.

Arguments: size: Vector2

Fires with the new viewportSize when the game view changes size (a window resized, a phone turned sideways).

Arguments: none

Fires when the on-screen buttons change (addTouchButton, removeTouchButton).

import { RemoteEvent, ReplicatedStorage, UserInputService, getChild, print } from '@rally/sdk';
const shoot = getChild(ReplicatedStorage, 'Shoot', RemoteEvent);
UserInputService.inputBegan.connect((input, gameProcessed) => {
if (gameProcessed) return; // typing in a text box, clicking a button
if (input.key === 'MouseLeft') shoot.fireServer(input.position);
if (input.key === 'KeyE') print('interact');
});
UserInputService.inputEnded.connect((input) => {
if (input.key === 'ShiftLeft') print('stopped sprinting');
});