UserInputService

Show Deprecated
Not Creatable
Service
Not Replicated

UserInputService is a service used to detect and capture the different types of input available on a user's device.

The primary purpose of this service is to allow for experiences to cooperate with multiple forms of available input, such as gamepads, touch screens, and keyboards. It allows a LocalScript to perform different actions depending on the device and, in turn, provide the best experience for the end user.

Some usages of this service include detecting user input when they interact with GUIs, tools, and other game instances. In order to detect user input, the service must look for a service event. For example, the service can detect events such as when the user touches the screen of a mobile device using UserInputService.TouchStarted, or connects a gamepad such as an Xbox controller to their device using UserInputService.GamepadConnected.

Since this service is client-side only, it will only work when used in a LocalScript or a ModuleScript required by a LocalScript. As UserInputService is client-side only, users in the game can only detect their own input - and not the input of others.

See also:

Code Samples

UserInputService

-- We must get the UserInputService before we can use it
local UserInputService = game:GetService("UserInputService")
-- A sample function providing one usage of InputBegan
local function onInputBegan(input, _gameProcessed)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
print("The left mouse button has been pressed!")
end
end
UserInputService.InputBegan:Connect(onInputBegan)

Summary

Properties

Describes whether the user's device has an accelerometer.

READ ONLY
NOT REPLICATED

Describes whether the device being used by a user has an available gamepad.

READ ONLY
NOT REPLICATED

Describes whether the user's device has a gyroscope.

READ ONLY
NOT REPLICATED

Describes whether the user's device has a keyboard available.

READ ONLY
NOT REPLICATED

Determines whether the user's mouse can be moved freely or is locked.

Scales the delta (change) output of the user's Mouse.

NOT REPLICATED

Describes whether the user's device has a mouse available.

READ ONLY
NOT REPLICATED

The content ID of the image used as the user mouse icon.

Determines whether the Mouse icon is visible.

Determines the position of the on-screen keyboard.

READ ONLY
NOT REPLICATED

Determines the size of the on-screen keyboard.

READ ONLY
NOT REPLICATED

Describes whether an on-screen keyboard is currently visible on the user's screen.

READ ONLY
NOT REPLICATED

Describes whether the user's current device has a touch-screen available.

READ ONLY
NOT REPLICATED

Indicates whether the user is using a virtual reality headset.

READ ONLY
NOT REPLICATED

Methods

GamepadSupports(gamepadNum: UserInputType, gamepadKeyCode: KeyCode): boolean  

Returns whether the given UserInputType gamepad supports a button corresponding with the given KeyCode.


Returns an array of UserInputType gamepads currently connected.


Returns an InputObject that describes the device's current acceleration.


Returns an InputObject describing the device's current gravity vector.


Returns an InputObject and a CFrame,describing the device's current rotation vector.


Returns the currently TextBox the client is currently focused on.


Returns whether a gamepad with the given UserInputType''gamepadNum'' is connected.


Returns an array of InputObjects for all available inputs on the given gamepad, representing each input's last input state.


Returns an image for the requested KeyCode.


Returns an array of InputObjects associated with the keys currently being pressed down.


Returns the UserInputType associated with the user's most recent input.


Returns an array of InputObjects corresponding with the mouse buttons currently being held down.


Returns the change, in pixels, of the position of the player's Mouse in the last rendered frame. Only works if the mouse is locked.


Returns the current screen location of the player's Mouse relative to the top left corner of the screen.


Returns an array of gamepads connected and enabled for GUI navigation in descending order of priority.


Returns a string representing a key the user should press in order to input a given KeyCode.


Returns an array of KeyCodes that the gamepad associated with the given UserInputType supports.


Returns a CFrame describing the position and orientation of a specified virtual reality device.

IsGamepadButtonDown(gamepadNum: UserInputType, gamepadKeyCode: KeyCode): boolean  

Determines whether a particular button is pressed on a particular gamepad.

IsKeyDown(keyCode: KeyCode): boolean  

Returns whether the given key is currently held down.


Returns whether the given mouse button is currently held down.


Returns true if the specified UserInputType gamepad is allowed to control the navigation GUIs.


Recenters the CFrame of the VR headset to the current orientation of the headset worn by the user.

SetNavigationGamepad(gamepadEnum: UserInputType, enabled: boolean): void  

Sets whether or not the specified Gamepad can move the GUI navigator.

Events


Fired when a user moves a device that has an accelerometer. Used to track real-world device movement within a Roblox game.


Fired when the force of gravity changes on a device that has an enabled accelerometer - such as a mobile device.


Fired when a user rotates a device that has a gyroscope.


Fires when a gamepad is connected to the client. Passes the ''gamepadNum'' of the gamepad that was connected.


Fires when a gamepad is disconnected from the client. Passes the UserInputType of the gamepad that was disconnected.

InputBegan(input: InputObject, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user begins interacting via a Human-Computer Interface device - such as a mouse or gamepad.

InputChanged(input: InputObject, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user changes how they're interacting via a Human-Computer Interface device.

InputEnded(input: InputObject, gameProcessedEvent: boolean): RBXScriptSignal  

Fires when a user stops interacting via a Human-Computer Interface device.


Fires whenever the client makes a request for their character to jump.


Fires when the client's UserInputType is changed.

PointerAction(wheel: number, pan: Vector2, pinch: number, gameProcessedEvent: boolean): RBXScriptSignal  

Fires when the user performs a specific pointer action (wheel, pinch, pan).


Fired when the client loses focus on a TextBox.

TextBoxFocused(textboxFocused: TextBox): RBXScriptSignal  

Fired when the client focuses on a TextBox.

TouchEnded(touch: InputObject, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user releases their finger from the screen on a TouchEnabled device - such as the screen of a mobile device.

TouchLongPress(touchPositions: Array, state: UserInputState, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user holds at least one finger for a short amount of time on the same screen position on a TouchEnabled device - such as the screen of a mobile device.

TouchMoved(touch: InputObject, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user moves their finger on a TouchEnabled device - such as the screen of an Apple iPad or iPhone or a Google Android phone.

TouchPan(touchPositions: Array, totalTranslation: Vector2, velocity: Vector2, state: UserInputState, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user drags at least one finger on a TouchEnabled device - such as the screen of an mobile device.

TouchPinch(touchPositions: Array, scale: number, velocity: number, state: UserInputState, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user pinches their fingers on a TouchEnabled device - such as the screen of a mobile device.

TouchRotate(touchPositions: Array, rotation: number, velocity: number, state: UserInputState, gameProcessedEvent: boolean): RBXScriptSignal  

Fires when a user rotates two fingers on a TouchEnabled device - such as the screen of a mobile device.

TouchStarted(touch: InputObject, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user places their finger on a TouchEnabled device - such as the screen of an Apple iPad or iPhone or a Google Android phone.

TouchSwipe(swipeDirection: SwipeDirection, numberOfTouches: number, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user swipes their fingers on a TouchEnabled device - such as the screen of a mobile device.

TouchTap(touchPositions: Array, gameProcessedEvent: boolean): RBXScriptSignal  

Fired when a user taps their finger on a TouchEnabled device - such as the screen of a mobile device.

TouchTapInWorld(position: Vector2, processedByUI: boolean): RBXScriptSignal  

Fires when a user taps the game world on a TouchEnabled device - such as the screen of a mobile device.


Fires when the CFrame of a specified Virtual Reality device changes.


Fires when the window of the Roblox client loses focus on the user's screen.


Fires when the window of the Roblox client gains focus on the user's screen.

Properties

AccelerometerEnabled

Read Only
Not Replicated

This property describes whether the user's device has an accelerometer

An accelerometer is a component found in most mobile devices that measures acceleration (change in speed).

For example, the following code snippet demonstrates how to check if the user's device has an accelerometer.


local userInputService = game:GetService("UserInputService")
local accelerometerEnabled = UserInputService.AccelerometerEnabled
if accelerometerEnabled then
print("Accelerometer enabled!")
else
print("Accelerometer not enabled!")
end

If the device has an enabled accelerometer, you can get it's current acceleration by using the UserInputService:GetDeviceAcceleration() function or track when the device's acceleration changes by using the UserInputService.DeviceAccelerationChanged event.

As UserInputService is client-side only, this property can only be used in a LocalScript.

Code Samples

Move a Ball using the Accelerometer

local UserInputService = game:GetService("UserInputService")
local Ball = workspace.Ball
local RealGravity = Instance.new("BodyForce")
RealGravity.Parent = Ball
local AntiGravity = Instance.new("BodyForce")
AntiGravity.Parent = Ball
AntiGravity.force = Vector3.new(0, workspace.Gravity * Ball:GetMass(), 0)
local function MoveBall(gravity)
RealGravity.force = gravity.Position * workspace.Gravity * workspace.Ball:GetMass()
end
if UserInputService.AccelerometerEnabled then
UserInputService.DeviceGravityChanged:Connect(MoveBall)
end
Create a Gyroscopic Camera

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
local camera = workspace.CurrentCamera
local currentRotation = camera.CFrame -- CFrame.new(Vector3.new(0,0,0), Vector3.new(0,0,0))
local lastInputFrame = nil
local upsideDown = false
task.wait()
local orientationSet = false
local function GravityChanged(gravity)
if not orientationSet then
upsideDown = (gravity.Position.X < -0.5 or gravity.Position.Z > 0.5)
orientationSet = true
end
end
local function RotationChanged(_rotation, rotCFrame)
if orientationSet then
if not lastInputFrame then
lastInputFrame = rotCFrame
end
local delta = rotCFrame * lastInputFrame:inverse()
local x, y, z = delta:ToEulerAnglesXYZ()
if upsideDown then
delta = CFrame.Angles(-x, y, z)
else
delta = CFrame.Angles(x, -y, z)
end
currentRotation = currentRotation * delta
lastInputFrame = rotCFrame
end
end
local function HideCharacter()
for _, limb in pairs(character:GetChildren()) do
if limb:IsA("Part") then
limb.Transparency = 1
end
end
end
if UserInputService.GyroscopeEnabled then
UserInputService.DeviceGravityChanged:Connect(GravityChanged)
UserInputService.DeviceRotationChanged:Connect(RotationChanged)
HideCharacter()
RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, function()
camera.CFrame = CFrame.new(head.Position - Vector3.new(0, 8, 10)) * currentRotation
camera.Focus = CFrame.new(currentRotation * Vector3.new(0, 0, -10))
end)
end

GamepadEnabled

Read Only
Not Replicated

This property describes whether the device being used by a user has an available gamepad.


local userInputService = game:GetService("UserInputService")
if userInputService.GamepadEnabled then
print("Gamepad enabled")
else
print("Gamepad not enabled")
end

If gamepads are available, you can use UserInputService:GetConnectedGamepads() to retrieve a list of connected gamepads and UserInputService:GetNavigationGamepads() to retrieve a list of connected gamepads that also controlnavigation GUIs.

As UserInputService is client-side only, this property can only be used in a LocalScript.

See also:

Code Samples

How to Use the Right Gamepad for Input

local UserInputService = game:GetService("UserInputService")
function GetActiveGamepad()
local activateGamepad = nil
local navigationGamepads = {}
navigationGamepads = UserInputService:GetNavigationGamepads()
if #navigationGamepads > 1 then
for _index, gamepad in ipairs(navigationGamepads) do
if activateGamepad == nil or gamepad.Value < activateGamepad.Value then
activateGamepad = gamepad
end
end
else
local connectedGamepads = {}
connectedGamepads = UserInputService:GetConnectedGamepads()
if #connectedGamepads > 0 then
for _index, gamepad in ipairs(connectedGamepads) do
if activateGamepad == nil or gamepad.Value < activateGamepad.Value then
activateGamepad = gamepad
end
end
end
if activateGamepad == nil then -- nothing is connected, at least set up for gamepad1
activateGamepad = Enum.UserInputType.Gamepad1
end
end
return activateGamepad
end
if UserInputService.GamepadEnabled then
print(GetActiveGamepad())
end

GyroscopeEnabled

Read Only
Not Replicated

This property describes whether the user's device has a gyroscope.

A gyroscope is an component found in most mobile devices that detects orientation and rotational speed.

If a user's device has a gyroscope, you can use incorporate it into your game using the UserInputService:GetDeviceRotation() function and UserInputService.DeviceRotationChanged event.


local UserInputService = game:GetService("UserInputService")
local gyroIsEnabled = UserInputService.GyroscopeEnabled
if (gyroIsEnabled) then
print("Gyroscope is enabled!")
else
print("Gyroscope is not enabled!")
end

As UserInputService is client-side only, this property can only be used in a LocalScript.

Code Samples

Create a Gyroscopic Camera

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
local camera = workspace.CurrentCamera
local currentRotation = camera.CFrame -- CFrame.new(Vector3.new(0,0,0), Vector3.new(0,0,0))
local lastInputFrame = nil
local upsideDown = false
task.wait()
local orientationSet = false
local function GravityChanged(gravity)
if not orientationSet then
upsideDown = (gravity.Position.X < -0.5 or gravity.Position.Z > 0.5)
orientationSet = true
end
end
local function RotationChanged(_rotation, rotCFrame)
if orientationSet then
if not lastInputFrame then
lastInputFrame = rotCFrame
end
local delta = rotCFrame * lastInputFrame:inverse()
local x, y, z = delta:ToEulerAnglesXYZ()
if upsideDown then
delta = CFrame.Angles(-x, y, z)
else
delta = CFrame.Angles(x, -y, z)
end
currentRotation = currentRotation * delta
lastInputFrame = rotCFrame
end
end
local function HideCharacter()
for _, limb in pairs(character:GetChildren()) do
if limb:IsA("Part") then
limb.Transparency = 1
end
end
end
if UserInputService.GyroscopeEnabled then
UserInputService.DeviceGravityChanged:Connect(GravityChanged)
UserInputService.DeviceRotationChanged:Connect(RotationChanged)
HideCharacter()
RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, function()
camera.CFrame = CFrame.new(head.Position - Vector3.new(0, 8, 10)) * currentRotation
camera.Focus = CFrame.new(currentRotation * Vector3.new(0, 0, -10))
end)
end

KeyboardEnabled

Read Only
Not Replicated

This property describes whether the user's device has a keyboard available. This property is true when the user's device has an available keyboard, and false when it does not.

It can be used to determine whether the user has an available keyboard - which can be important if you want to check if you can use UserInputService:IsKeyDown() or UserInputService:GetKeysPressed() to check for keyboard input.

As UserInputService is client-side only, this property can only be used in a LocalScript.

Code Samples

Check if Keyboard is Enabled

local UserInputService = game:GetService("UserInputService")
if UserInputService.KeyboardEnabled then
print("The user's device has an available keyboard!")
else
print("The user's device does not have an available keyboard!")
end

MouseBehavior

This property sets how the user's mouse behaves based on the MouseBehavior Enum. The default value is Enum.MouseBehavior.Default.

It can be set to three values:

  1. Default: The mouse moves freely around the user's screen.
  2. LockCenter: The mouse is locked, and cannot move from, the center of the user's screen.
  3. LockCurrentPosition: The mouse is locked, and cannot move from, it's current position on the user's screen at the time of locking.

The value of this property does not affect the sensitivity of events tracking mouse movement. For example, GetMouseDelta returns the same Vector2 screen position in pixels regardless of whether the mouse is locked or able to move freely around the user's screen. As a result, default scripts like those controlling the camera are not impacted by this property.

This property is overridden if a GuiButton with Modal enabled is GuiButton.Visible unless the player's right mouse button is down.

Note that, if the mouse is locked, UserInputService.InputChanged will still fire when the player moves the mouse and will pass in the Delta that the mouse attempted to move by. Additionally, if the player is kicked from the game, the mouse will be forcefully unlocked.

As UserInputService is client-side only, this property can only be used in a LocalScript.

Code Samples

Create a Binoculars Script

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head", false)
local mouse = player:GetMouse()
local zoomed = false
local camera = game.Workspace.CurrentCamera
local target = nil
local originalProperties = {
FieldOfView = nil,
_CFrame = nil,
MouseBehavior = nil,
MouseDeltaSensitivity = nil,
}
local AngleX, TargetAngleX = 0, 0
local AngleY, TargetAngleY = 0, 0
-- Reset camera back to CFrame and FieldOfView before zoom
local function ResetCamera()
target = nil
camera.CameraType = Enum.CameraType.Custom
camera.CFrame = originalProperties._CFrame
camera.FieldOfView = originalProperties.FieldOfView
UserInputService.MouseBehavior = originalProperties.MouseBehavior
UserInputService.MouseDeltaSensitivity = originalProperties.MouseDeltaSensitivity
end
local function ZoomCamera()
-- Allow camera to be changed by script
camera.CameraType = Enum.CameraType.Scriptable
-- Store camera properties before zoom
originalProperties._CFrame = camera.CFrame
originalProperties.FieldOfView = camera.FieldOfView
originalProperties.MouseBehavior = UserInputService.MouseBehavior
originalProperties.MouseDeltaSensitivity = UserInputService.MouseDeltaSensitivity
-- Zoom camera
target = mouse.Hit.Position
local eyesight = head.Position
camera.CFrame = CFrame.new(eyesight, target)
camera.Focus = CFrame.new(target)
camera.FieldOfView = 10
-- Lock and slow down mouse
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.MouseDeltaSensitivity = 1
-- Reset zoom angles
AngleX, TargetAngleX = 0, 0
AngleY, TargetAngleY = 0, 0
end
-- Toggle camera zoom/unzoom
local function MouseClick()
if zoomed then
-- Unzoom camera
ResetCamera()
else
-- Zoom in camera
ZoomCamera()
end
zoomed = not zoomed
end
local function MouseMoved(input)
if zoomed then
local sensitivity = 0.6 -- anything higher would make looking up and down harder; recommend anything between 0~1
local smoothness = 0.05 -- recommend anything between 0~1
local delta = Vector2.new(input.Delta.x / sensitivity, input.Delta.y / sensitivity) * smoothness
local X = TargetAngleX - delta.y
local Y = TargetAngleY - delta.x
TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X
TargetAngleY = (Y >= 80 and 80) or (Y <= -80 and -80) or Y
AngleX = AngleX + (TargetAngleX - AngleX) * 0.35
AngleY = AngleY + (TargetAngleY - AngleY) * 0.15
camera.CFrame = CFrame.new(head.Position, target)
* CFrame.Angles(0, math.rad(AngleY), 0)
* CFrame.Angles(math.rad(AngleX), 0, 0)
end
end
local function InputBegan(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
MouseClick()
end
end
local function InputChanged(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseMovement then
MouseMoved(input)
end
end
if UserInputService.MouseEnabled then
UserInputService.InputBegan:Connect(InputBegan)
UserInputService.InputChanged:Connect(InputChanged)
end
Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

MouseDeltaSensitivity

Not Replicated

This property determines the sensitivity of the user's Mouse.

The sensitivity determines the extent to which a movement of the physical mouse translates to a movement of the mouse in-game. This can be used to adjusted how sensitive events tracking mouse movement, like GetMouseDelta, are to mouse movement.

This property does not affect the movement of the mouse icon. Nor does it affect the Camera Sensitivity setting found in the Settings tab of the client's Settings menu, which also adjusts the sensitivity of events tracking mouse movement.

This property has a maximum value of 10 and a minimum value of 0. A lower value corresponds to lower sensitivity, and a higher value to higher sensitivity.

When sensitivity is 0, events that track the mouse's movement will still fire but all parameters and properties indicating the change in mouse position will return Vector2.new(), or Vector3.new() in the case of InputObject.Delta. For example, GetMouseDelta will always return (0, 0).

Code Samples

Create a Binoculars Script

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head", false)
local mouse = player:GetMouse()
local zoomed = false
local camera = game.Workspace.CurrentCamera
local target = nil
local originalProperties = {
FieldOfView = nil,
_CFrame = nil,
MouseBehavior = nil,
MouseDeltaSensitivity = nil,
}
local AngleX, TargetAngleX = 0, 0
local AngleY, TargetAngleY = 0, 0
-- Reset camera back to CFrame and FieldOfView before zoom
local function ResetCamera()
target = nil
camera.CameraType = Enum.CameraType.Custom
camera.CFrame = originalProperties._CFrame
camera.FieldOfView = originalProperties.FieldOfView
UserInputService.MouseBehavior = originalProperties.MouseBehavior
UserInputService.MouseDeltaSensitivity = originalProperties.MouseDeltaSensitivity
end
local function ZoomCamera()
-- Allow camera to be changed by script
camera.CameraType = Enum.CameraType.Scriptable
-- Store camera properties before zoom
originalProperties._CFrame = camera.CFrame
originalProperties.FieldOfView = camera.FieldOfView
originalProperties.MouseBehavior = UserInputService.MouseBehavior
originalProperties.MouseDeltaSensitivity = UserInputService.MouseDeltaSensitivity
-- Zoom camera
target = mouse.Hit.Position
local eyesight = head.Position
camera.CFrame = CFrame.new(eyesight, target)
camera.Focus = CFrame.new(target)
camera.FieldOfView = 10
-- Lock and slow down mouse
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.MouseDeltaSensitivity = 1
-- Reset zoom angles
AngleX, TargetAngleX = 0, 0
AngleY, TargetAngleY = 0, 0
end
-- Toggle camera zoom/unzoom
local function MouseClick()
if zoomed then
-- Unzoom camera
ResetCamera()
else
-- Zoom in camera
ZoomCamera()
end
zoomed = not zoomed
end
local function MouseMoved(input)
if zoomed then
local sensitivity = 0.6 -- anything higher would make looking up and down harder; recommend anything between 0~1
local smoothness = 0.05 -- recommend anything between 0~1
local delta = Vector2.new(input.Delta.x / sensitivity, input.Delta.y / sensitivity) * smoothness
local X = TargetAngleX - delta.y
local Y = TargetAngleY - delta.x
TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X
TargetAngleY = (Y >= 80 and 80) or (Y <= -80 and -80) or Y
AngleX = AngleX + (TargetAngleX - AngleX) * 0.35
AngleY = AngleY + (TargetAngleY - AngleY) * 0.15
camera.CFrame = CFrame.new(head.Position, target)
* CFrame.Angles(0, math.rad(AngleY), 0)
* CFrame.Angles(math.rad(AngleX), 0, 0)
end
end
local function InputBegan(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
MouseClick()
end
end
local function InputChanged(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseMovement then
MouseMoved(input)
end
end
if UserInputService.MouseEnabled then
UserInputService.InputBegan:Connect(InputBegan)
UserInputService.InputChanged:Connect(InputChanged)
end

MouseEnabled

Read Only
Not Replicated

This property describes whether the user's device has a mouse available. This property is true when the user's device has an available mouse, and false when it does not.


local UserInputService = game:GetService("UserInputService")
if (UserInputService.MouseEnabled) then
print("The user's device has an available mouse!")
else
print("The user's device does not have an available mouse!")
end

It is important to check this before using UserInputService mouse functions such as UserInputService:GetMouseLocation().

As UserInputService is client-side only, this property can only be used in a LocalScript.

See also:

Code Samples

Create a Binoculars Script

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head", false)
local mouse = player:GetMouse()
local zoomed = false
local camera = game.Workspace.CurrentCamera
local target = nil
local originalProperties = {
FieldOfView = nil,
_CFrame = nil,
MouseBehavior = nil,
MouseDeltaSensitivity = nil,
}
local AngleX, TargetAngleX = 0, 0
local AngleY, TargetAngleY = 0, 0
-- Reset camera back to CFrame and FieldOfView before zoom
local function ResetCamera()
target = nil
camera.CameraType = Enum.CameraType.Custom
camera.CFrame = originalProperties._CFrame
camera.FieldOfView = originalProperties.FieldOfView
UserInputService.MouseBehavior = originalProperties.MouseBehavior
UserInputService.MouseDeltaSensitivity = originalProperties.MouseDeltaSensitivity
end
local function ZoomCamera()
-- Allow camera to be changed by script
camera.CameraType = Enum.CameraType.Scriptable
-- Store camera properties before zoom
originalProperties._CFrame = camera.CFrame
originalProperties.FieldOfView = camera.FieldOfView
originalProperties.MouseBehavior = UserInputService.MouseBehavior
originalProperties.MouseDeltaSensitivity = UserInputService.MouseDeltaSensitivity
-- Zoom camera
target = mouse.Hit.Position
local eyesight = head.Position
camera.CFrame = CFrame.new(eyesight, target)
camera.Focus = CFrame.new(target)
camera.FieldOfView = 10
-- Lock and slow down mouse
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.MouseDeltaSensitivity = 1
-- Reset zoom angles
AngleX, TargetAngleX = 0, 0
AngleY, TargetAngleY = 0, 0
end
-- Toggle camera zoom/unzoom
local function MouseClick()
if zoomed then
-- Unzoom camera
ResetCamera()
else
-- Zoom in camera
ZoomCamera()
end
zoomed = not zoomed
end
local function MouseMoved(input)
if zoomed then
local sensitivity = 0.6 -- anything higher would make looking up and down harder; recommend anything between 0~1
local smoothness = 0.05 -- recommend anything between 0~1
local delta = Vector2.new(input.Delta.x / sensitivity, input.Delta.y / sensitivity) * smoothness
local X = TargetAngleX - delta.y
local Y = TargetAngleY - delta.x
TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X
TargetAngleY = (Y >= 80 and 80) or (Y <= -80 and -80) or Y
AngleX = AngleX + (TargetAngleX - AngleX) * 0.35
AngleY = AngleY + (TargetAngleY - AngleY) * 0.15
camera.CFrame = CFrame.new(head.Position, target)
* CFrame.Angles(0, math.rad(AngleY), 0)
* CFrame.Angles(math.rad(AngleX), 0, 0)
end
end
local function InputBegan(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
MouseClick()
end
end
local function InputChanged(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseMovement then
MouseMoved(input)
end
end
if UserInputService.MouseEnabled then
UserInputService.InputBegan:Connect(InputBegan)
UserInputService.InputChanged:Connect(InputChanged)
end

MouseIcon

The MouseIcon property determines the image used as the pointer. If blank, a default arrow is used. While the cursor hovers over certain UI objects such as an ImageButton, TextButton, TextBox, or ProximityPrompt, this image will be overridden and temporarily ignored.

To hide the cursor entirely, do not use a transparent image. Instead, set UserInputService.MouseIconEnabled to false.

Code Samples

UserInputService.MouseIcon

local UserInputService = game:GetService("UserInputService")
-- In order to restore the cursor to what it was set to previously, it will need to be saved to a variable
local savedCursor = nil
local function setTemporaryCursor(cursor: string)
-- Only update the saved cursor if it's not currently saved
if not savedCursor then
savedCursor = UserInputService.MouseIcon
end
UserInputService.MouseIcon = cursor
end
local function clearTemporaryCursor()
-- Only restore the mouse cursor if there's a saved cursor to restore
if savedCursor then
UserInputService.MouseIcon = savedCursor
-- Don't restore the same cursor twice (might overwrite another script)
savedCursor = nil
end
end
setTemporaryCursor("http://www.roblox.com/asset?id=163023520")
print(UserInputService.MouseIcon)
clearTemporaryCursor()
print(UserInputService.MouseIcon)

MouseIconEnabled

This property determines whether the Mouse icon is visible When true the mouse's icon is visible, when false it is not.

For example, the code snippet below hides the mouse's icon.


local userInputService = game:GetService("UserInputService")
userInputService.MouseIconEnabled = false

As UserInputService is client-side only, this property can only be used in a LocalScript.

Code Samples

Hide Mouse During Keyboard Input

local UserInputService = game:GetService("UserInputService")
local mouseInput = {
Enum.UserInputType.MouseButton1,
Enum.UserInputType.MouseButton2,
Enum.UserInputType.MouseButton3,
Enum.UserInputType.MouseMovement,
Enum.UserInputType.MouseWheel,
}
local keyboard = Enum.UserInputType.Keyboard
local function toggleMouse(lastInputType)
if lastInputType == keyboard then
UserInputService.MouseIconEnabled = false
return
end
for _, mouse in pairs(mouseInput) do
if lastInputType == mouse then
UserInputService.MouseIconEnabled = true
return
end
end
end
UserInputService.LastInputTypeChanged:Connect(toggleMouse)

OnScreenKeyboardPosition

Read Only
Not Replicated

This property describes the position of the on-screen keyboard in pixels. The keyboard's position is Vector2.new(0, 0) when it is not visible.

The code snippet below prints the position of the keyboard.


local userInputService = game:GetService("UserInputService")
print(userInputService.OnScreenKeyboardPosition)

As UserInputService is client-side only, this property can only be used in a LocalScript.

On screen keyboard

See also:

Code Samples

UserInputService.OnScreenKeyboardPosition

local UserInputService = game:GetService("UserInputService")
print(UserInputService.OnScreenKeyboardPosition)

OnScreenKeyboardSize

Read Only
Not Replicated

This property describes the size of the on-screen keyboard in pixels. The keyboard's size is Vector2.new(0, 0) when it is not visible.

The code snippet below prints the size of the keyboard.


local userInputService = game:GetService("UserInputService")
print(userInputService.OnScreenKeyboardSize)

As UserInputService is client-side only, this property can only be used in a LocalScript.

On screen keyboard

See also:

OnScreenKeyboardVisible

Read Only
Not Replicated

This property describes whether an on-screen keyboard is currently visible on the user's screen.

The code snippet below prints whether the keyboard is visible.


local userInputService = game:GetService("UserInputService")
local keyboardIsVisible = userInputService.OnScreenKeyboardIsVisible
if (keyboardIsVisible) then
print("On-screen keyboard is visible!")
else
print("On-screen keyboard is not visible!")
end

As UserInputService is client-side only, this property can only be used in a LocalScript.

On screen keyboard

See also:

TouchEnabled

Read Only
Not Replicated

This property describes whether the user's current device has a touch screen available.

The property is used to determine if the user's device has a touch screen, and therefore if touch events will fire. If TouchEnabled is true, you can use UserInputService events such as UserInputService.TouchStarted and UserInputService.TouchEnded to track when a user starts and stops touching the screen of their device.

The code snippet below prints whether the user's device has a touch screen.


local userInputService = game:GetService("UserInputService")
if userInputService.TouchEnabled then
print("The user's device has a touchscreen!")
else
print("The user's device does not have a touchscreen!")
end

See also:

Code Samples

Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

VREnabled

Read Only
Not Replicated

This property describes whether the user is using a virtual reality (VR) device.

If a VR device is enabled, you can interact with its location and movement through functions such as UserInputService:GetUserCFrame(). You can also react to VR device movement using the UserInputService.UserCFrameChanged event.


local userInputService = game:GetService("UserInputService")
local isUsingVR = userInputService.VREnabled
if (isUsingVR) then
print("User is using a VR headset!")
else
print("User is not using a VR headset!")
end

As UserInputService isclient-side only, this property can only be used in a LocalScript.

See also:

Code Samples

VR Head Tracking

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
local function TrackHead(inputType, value)
if inputType == Enum.UserCFrame.Head then
head.CFrame = value
end
end
if UserInputService.VREnabled then
-- Set the inital CFrame
head.CFrame = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)
-- Track VR headset movement and mirror for character's head
UserInputService.UserCFrameChanged:Connect(TrackHead)
end

Methods

GamepadSupports

This function returns whether the given UserInputType gamepad supports a button corresponding with the given KeyCode. This function is used to determine valid gamepad inputs.

To determine which UserInputType gamepads are connected, use UserInputService:GetConnectedGamepads().

As UserInputService is client-side only, this function can only be used in a LocalScript.

See also:

Parameters

gamepadNum: UserInputType

The UserInputType of the gamepad.

gamepadKeyCode: KeyCode

The KeyCode of the button in question.


Returns

Whether the given gamepad supports a button corresponding with the given KeyCode.

Code Samples

Binding Functions to Gamepad Controls

local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local controller = Enum.UserInputType.Gamepad1
local buttonX = Enum.KeyCode.ButtonX
local function isSupported(gamepad, keycode)
return UserInputService:GamepadSupports(gamepad, keycode)
end
local function action()
print("Action")
end
if isSupported(controller, buttonX) then
ContextActionService:BindAction("sample action", action, false, buttonX)
end

GetConnectedGamepads

This function returns an array of UserInputType gamepads currently connected. If no gamepads are connected, this array will be empty. Additionally, it only returns UserInputType objects that are gamepads. For instance, this event will return a connected Gamepad1 object but not a Keyboard object.

For example, the following code snippet retrieves the connected gamepads and stores them in a variable named connectedGamepads.


local userInputService = game:GetService("UserInputService")
local connectedGamepads = userInputService:GetConnectedGamepads()

To check if a specific gamepad is connected, use UserInputService:GetGamepadConnected().

As UserInputService is client-side only, this function can only be used in a LocalScript.

See also:


Returns

An array of UserInputTypes corresponding with the gamepads connected to the user's device.

Code Samples

How to Use the Right Gamepad for Input

local UserInputService = game:GetService("UserInputService")
function GetActiveGamepad()
local activateGamepad = nil
local navigationGamepads = {}
navigationGamepads = UserInputService:GetNavigationGamepads()
if #navigationGamepads > 1 then
for _index, gamepad in ipairs(navigationGamepads) do
if activateGamepad == nil or gamepad.Value < activateGamepad.Value then
activateGamepad = gamepad
end
end
else
local connectedGamepads = {}
connectedGamepads = UserInputService:GetConnectedGamepads()
if #connectedGamepads > 0 then
for _index, gamepad in ipairs(connectedGamepads) do
if activateGamepad == nil or gamepad.Value < activateGamepad.Value then
activateGamepad = gamepad
end
end
end
if activateGamepad == nil then -- nothing is connected, at least set up for gamepad1
activateGamepad = Enum.UserInputType.Gamepad1
end
end
return activateGamepad
end
if UserInputService.GamepadEnabled then
print(GetActiveGamepad())
end

GetDeviceAcceleration

The GetDeviceAcceleration function determines the current acceleration of the user's device. It returns an InputObject that describes the device's current acceleration.

In order for this to work, the user's device must have an enabled accelerometer. To check if a user's device has an enabled accelerometer, you can check the UserInputService.AccelerometerEnabled property.

If you want to track when the user's device's acceleration changes instead, you can use the UserInputService.DeviceAccelerationChanged event.

Since it only fires locally, it can only be used in a LocalScript.


Returns

Code Samples

Print Device Acceleration

local UserInputService = game:GetService("UserInputService")
local accelerometerEnabled = UserInputService.AccelerometerEnabled
if accelerometerEnabled then
local acceleration = UserInputService:GetDeviceAcceleration().Position
print(acceleration)
else
print("Cannot get device acceleration because device does not have an enabled accelerometer!")
end

GetDeviceGravity

This function returns an InputObject describing the device's current gravity vector.

The gravity vector is determined by the device's orientation relative to the real-world force of gravity. For instance, if a device is perfectly upright (portrait), the gravity vector is Vector3.new(0, 0, -9.18). If the left side of the device is pointing down, the vector is Vector3.new(9.81, 0, 0). Finally, if the back of the device is pointing down, the vector is Vector3.new(0, -9.81, 0).

This function might be used to enable the user's device to impact or control gravity within the game or move in-game objects such as a ball.

Gravity is only tracked for players using a device with an enabled gyroscope - such as a mobile device.

To check if a user's device has an enabled gyroscope, check the value of UserInputService.GyroscopeEnabled. If the device has an enabled gyroscope, you can also use the UserInputService.DeviceGravityChanged event to track when force of gravity on the user's device changes.

As UserInputService is client-side only, this function can only be used in a LocalScript.


Returns

Code Samples

Moving Objects with the Gyroscope

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local label = script.Parent
local bubble = workspace.Bubble
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
camera.CFrame = CFrame.new(Vector3.new(0, 20, 0), Vector3.new(0, 0, 0))
if UserInputService.GyroscopeEnabled then
-- Bind event to when gyroscope detects change
UserInputService.DeviceGravityChanged:Connect(function(accel)
-- Display accelerometer output to a TextLabel
label.Text = string.format("%.2f", accel.Position.X)
.. "\n"
.. string.format("%.2f", accel.Position.Y)
.. "\n"
.. string.format("%.2f", accel.Position.Z)
-- Move the bubble in the world based on the gyroscope data
bubble.Position = Vector3.new(0, 1.8, -8 * accel.Position.Z)
end)
else
-- Kindly turn away users who do not have an gyroscope
local message = Instance.new("Message")
message.Text = "This game only works on a device with a gyroscope."
message.Parent = player.PlayerGui
end

GetDeviceRotation

This function returns an InputObject and a CFrame describing the device's current rotation vector.

This is fired with an InputObject. The Position property of the input object is a Enum.InputType.Gyroscope that tracks the total rotation in each local device axis.

Device rotation can only be tracked on devices with a gyroscope.

As this function fires locally, it can only be used in a LocalScript.


Returns

A tuple containing two properties:

  1. The delta property describes the amount of rotation that last happened
  2. The CFrame is the device's current rotation relative to its default reference frame.

Code Samples

Print Device Rotation

local UserInputService = game:GetService("UserInputService")
local gyroEnabled = UserInputService:GyroscopeEnabled()
if gyroEnabled then
local _inputObj, cframe = UserInputService:GetDeviceRotation()
print("CFrame: {", cframe, "}")
else
print("Cannot get device rotation because device does not have an enabled gyroscope!")
end

GetFocusedTextBox

This function returns the TextBox the client is currently focused on. A TextBox can be manually selected by the user, or selection can be forced using the TextBox:CaptureFocus() function. If no TextBox is selected, this function will return nil.

As UserInputService is client-side only, this function can only be used in a LocalScript.

See also:


Returns

Code Samples

Ignore User Input When a TextBox Is Focused

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local jumpKey = Enum.KeyCode.J
local isJumping = false
local function InputBegan(input, _gameProcessedEvent)
local TextBoxFocused = UserInputService:GetFocusedTextBox()
-- Ignore input event if player is focusing on a TextBox
if TextBoxFocused then
return
end
-- Make player jump when user presses jumpKey Key on Keyboard
if input.UserInputType == Enum.UserInputType.Keyboard and input.KeyCode == jumpKey then
if not isJumping then
isJumping = true
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
end
local function StateChanged(_oldState, newState)
-- Prevent player from jumping again using jumpKey if already jumping
if newState == Enum.HumanoidStateType.Jumping then
isJumping = true
-- Allow player to jump again after landing
elseif newState == Enum.HumanoidStateType.Landed then
isJumping = false
end
end
UserInputService.InputBegan:Connect(InputBegan)
humanoid.StateChanged:Connect(StateChanged)

GetGamepadConnected

This function returns whether a gamepad with the given UserInputType is connected to the client.

This can be used to check if a specific gamepad, such as 'Gamepad1' is connected to the client's device.

To retrieve a list of all connected gamepads, use UserInputService:GetConnectedGamepads().

As UserInputService is client-side only, this function can only be used in a LocalScript.

See also:

Parameters

gamepadNum: UserInputType

The UserInputType of the gamepad in question.


Returns

Whether a gamepad associated with UserInputType is connected.

Code Samples

Check Whether a Gamepad is Connected

local UserInputService = game:GetService("UserInputService")
local isConnected = UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad1)
if isConnected then
print("Gamepad1 is connected to the client")
else
print("Gamepad1 is not connected to the client")
end

GetGamepadState

This function returns an array of InputObjects for all available inputs on the given UserInputType gamepad, representing each input's last input state.

To find the UserInputTypes of connected gamepads, use UserInputService:GetConnectedGamepads().

As this function only fires locally, it can only be used in a LocalScript.

See also:

Parameters

gamepadNum: UserInputType

The UserInputType corresponding with the gamepad in question.


Returns

An array of InputObjects representing the current state of all available inputs for the given gamepad.

Code Samples

Mapping and Polling GamepadStates

local UserInputService = game:GetService("UserInputService")
local states = UserInputService:GetGamepadState(Enum.UserInputType.Gamepad1)
local statesByKeyCode = {}
for _, state in pairs(states) do
statesByKeyCode[state.KeyCode] = state
end
local thumbstick1 = statesByKeyCode[Enum.KeyCode.Thumbstick1]
while true do
task.wait(0.1)
print(thumbstick1.Position)
end

GetImageForKeyCode

This method takes the requested KeyCode and returns the associated image for the currently connected gamepad device (limited to Xbox, PlayStation and Windows). This means that if the connected controller is a Xbox One controller, the user sees Xbox assets. Similarly, if the connected device is a PlayStation controller, the user sees PlayStation assets. If you want to use custom assets, see GetStringForKeyCode().

Parameters

keyCode: KeyCode

The KeyCode for which to fetch the associated image.


Returns

The returned image asset ID.

Code Samples

UserInputService - Get Image For KeyCode

local UserInputService = game:GetService("UserInputService")
local imageLabel = script.Parent
local key = Enum.KeyCode.ButtonA
local mappedIconImage = UserInputService:GetImageForKeyCode(key)
imageLabel.Image = mappedIconImage

GetKeysPressed

This function returns an array of InputObjects associated with the keys currently being pressed down.

This array can be iterated through to determine which keys are currently being pressed, using the InputObject.KeyCode values.

To check if a specific key is being pressed, use UserInputService:IsKeyDown().

As UserInputService is client-side only, this function can only be used in a LocalScript.


Returns

An array of InputObjects associated with the keys currently being pressed.

Code Samples

Double Jump Key Combo

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local actionKey = Enum.KeyCode.LeftShift
local canJump = true
local canDoubleJump = false
local function jumpRequest()
local keysPressed = UserInputService:GetKeysPressed()
for _, key in ipairs(keysPressed) do
if key.KeyCode == actionKey and canJump then
canJump = false
canDoubleJump = true
end
end
end
local function stateChanged(oldState, newState)
-- Double jump during freefall if able to
if oldState == Enum.HumanoidStateType.Jumping and newState == Enum.HumanoidStateType.Freefall and canDoubleJump then
canDoubleJump = false
task.wait(0.2)
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
-- Allow player to jump again after they land
if oldState == Enum.HumanoidStateType.Freefall and newState == Enum.HumanoidStateType.Landed then
canJump = true
end
end
UserInputService.JumpRequest:Connect(jumpRequest)
humanoid.StateChanged:Connect(stateChanged)

GetLastInputType

This function returns 'Enum.UserInputType` associated with the user's most recent input.

For example, if the user's previous input had been pressing the spacebar, the UserInputType returned would be 'Keyboard'.

The UserInputService.LastInputTypeChanged event can be used to track when the last UserInputType used by the user changes.

As UserInputService is client-side only, this function can only be used in a LocalScript.


Returns

The UserInputType associated with the user's most recent input.

Code Samples

UserInputService:GetLastInputType

local UserInputService = game:GetService("UserInputService")
local lastInput = UserInputService:GetLastInputType()
if lastInput == Enum.UserInputType.Keyboard then
print("Most recent input was via keyboard")
end

GetMouseButtonsPressed

This function returns an array of InputObjects corresponding to the mouse buttons currently being pressed down.

Mouse buttons that are tracked by this function include:

Name Description
MouseButton1The left mouse button.
MouseButton2The right mouse button.
MouseButton3The middle mouse button.

If the user is not pressing any mouse button down when the function is called, it will return an empty array.

As UserInputService is client-side only, this function can only be used in a LocalScript.


Returns

An array of InputObjects corresponding to the mouse buttons currently being currently held down.

Code Samples

Check which MouseButtons are Pressed

local UserInputService = game:GetService("UserInputService")
-- InputBegan is a UserInputService event that fires when the player
-- begins interacting via a Human-User input device
UserInputService.InputBegan:Connect(function(_input, _gameProcessedEvent)
-- Returns an array of the pressed MouseButtons
local buttons = UserInputService:GetMouseButtonsPressed()
local m1Pressed, m2Pressed = false, false
for _, button in pairs(buttons) do
if button.UserInputType.Name == "MouseButton1" then
print("MouseButton1 is pressed")
m1Pressed = true
end
if button.UserInputType.Name == "MouseButton2" then
print("MouseButton2 is pressed")
m2Pressed = true
end
if m1Pressed and m2Pressed then
print("Both mouse buttons are pressed")
end
end
end)

GetMouseDelta

This function returns the change, in pixels, of the position of the player's Mouse in the last rendered frame as a Vector2. This function only works if the mouse has been locked using the UserInputService.MouseBehavior property. If the mouse has not been locked, the returned Vector2 values will be zero.

The sensitivity of the mouse, determined in the client's settings and UserInputService.MouseDeltaSensitivity, will influence the result.

As UserInputService is client-side only, this function can only be used in a LocalScript.


Returns

Change in movement of the mouse.

Code Samples

Getting Mouse Delta

local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local function OnRenderStep()
local delta = UserInputService:GetMouseDelta()
print("The mouse has moved", delta, "since the last step.")
end
RunService:BindToRenderStep("MeasureMouseMovement", Enum.RenderPriority.Input.Value, OnRenderStep)
Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end