UserInputService
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 ContextActionService, a service which allows you to bind functions to multiple user inputs.
Code Samples
-- 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.
Describes whether the device being used by a user has an available gamepad.
Describes whether the user's device has a gyroscope.
Describes whether the user's device has a keyboard available.
Determines whether the user's mouse can be moved freely or is locked.
Scales the delta (change) output of the user's Mouse.
Describes whether the user's device has a mouse available.
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.
Determines the size of the on-screen keyboard.
Describes whether an on-screen keyboard is currently visible on the user's screen.
Describes whether the user's current device has a touch-screen available.
Indicates whether the user is using a virtual reality headset.
Methods
Returns whether the given Enum.UserInputType gamepad supports a button corresponding with the given Enum.KeyCode.
Returns an array of Enum.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 Enum.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 Enum.KeyCode.
Returns an array of InputObjects associated with the keys currently being pressed down.
Returns the Enum.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 Enum.KeyCode.
Returns an array of KeyCodes that the gamepad associated with the given Enum.UserInputType supports.
Determines whether a particular button is pressed on a particular gamepad.
Returns whether the given key is currently held down.
Returns whether the given mouse button is currently held down.
Returns true if the specified Enum.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.
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 Enum.UserInputType of the gamepad that was disconnected.
Fired when a user begins interacting via a Human-Computer Interface device - such as a mouse or gamepad.
Fired when a user changes how they're interacting via a Human-Computer Interface device.
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 Enum.UserInputType is changed.
- PointerAction(wheel : number,pan : Vector2,pinch : number,gameProcessedEvent : bool):RBXScriptSignal
Fires when the user performs a specific pointer action (wheel, pinch, pan).
Fired when the client loses focus on a TextBox.
Fired when the client focuses on a TextBox.
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 : Enum.UserInputState,gameProcessedEvent : bool):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.
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 : Enum.UserInputState,gameProcessedEvent : bool):RBXScriptSignal
Fired when a user drags at least one finger on a TouchEnabled device - such as the screen of a mobile device.
- TouchPinch(touchPositions : Array,scale : number,velocity : number,state : Enum.UserInputState,gameProcessedEvent : bool):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 : Enum.UserInputState,gameProcessedEvent : bool):RBXScriptSignal
Fires when a user rotates two fingers on a TouchEnabled device - such as the screen of a mobile device.
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 : Enum.SwipeDirection,numberOfTouches : number,gameProcessedEvent : bool):RBXScriptSignal
Fired when a user swipes their fingers on a TouchEnabled device - such as the screen of a mobile device.
Fired when a user taps their finger on a TouchEnabled device - such as the screen of a mobile device.
Fires when a user taps the game world on a TouchEnabled device - such as the screen of a mobile device.
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
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.AccelerometerEnabledif accelerometerEnabled thenprint("Accelerometer enabled!")elseprint("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
local Workspace = game:GetService("Workspace")
local UserInputService = game:GetService("UserInputService")
local ball = script.Parent:WaitForChild("Ball")
local mass = ball:GetMass()
local gravityForce = ball:WaitForChild("GravityForce")
local function moveBall(gravity)
gravityForce.Force = gravity.Position * Workspace.Gravity * mass
end
if UserInputService.AccelerometerEnabled then
UserInputService.DeviceGravityChanged:Connect(moveBall)
end
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
This property describes whether the device being used by a user has an available gamepad. If gamepads are available, you can use UserInputService:GetConnectedGamepads() to retrieve a list of connected gamepads.
As UserInputService is client-side only, this property can only be used in a LocalScript.
See also:
Code Samples
local UserInputService = game:GetService("UserInputService")
local function getActiveGamepad()
local activeGamepad = nil
local connectedGamepads = UserInputService:GetConnectedGamepads()
if #connectedGamepads > 0 then
for _, gamepad in connectedGamepads do
if activeGamepad == nil or gamepad.Value < activeGamepad.Value then
activeGamepad = gamepad
end
end
end
if activeGamepad == nil then -- Nothing is connected; set up for "Gamepad1"
activeGamepad = Enum.UserInputType.Gamepad1
end
return activeGamepad
end
if UserInputService.GamepadEnabled then
local activeGamepad = getActiveGamepad()
print(activeGamepad)
end
GyroscopeEnabled
This property describes whether the user's device has a gyroscope.
A gyroscope is a 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.GyroscopeEnabledif gyroIsEnabled thenprint("Gyroscope is enabled!")elseprint("Gyroscope is not enabled!")end
As UserInputService is client-side only, this property can only be used in a LocalScript.
Code Samples
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
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
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 Enum.MouseBehavior Enum. The default value is Enum.MouseBehavior.Default.
It can be set to three values:
- Default: The mouse moves freely around the user's screen.
- LockCenter: The mouse is locked, and cannot move from, the center of the user's screen.
- 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
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
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
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
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
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 thenprint("The user's device has an available mouse!")elseprint("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
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
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
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
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.
As UserInputService is client-side only, this property can only be used in a LocalScript, or a Script with RunContext set to Enum.RunContext.Client.
See also OnScreenKeyboardVisible and OnScreenKeyboardSize.
Code Samples
local UserInputService = game:GetService("UserInputService")
print(UserInputService.OnScreenKeyboardPosition)
OnScreenKeyboardSize
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.
As UserInputService is client-side only, this property can only be used in a LocalScript, or a Script with RunContext set to Enum.RunContext.Client.
See also OnScreenKeyboardVisible and OnScreenKeyboardPosition.
OnScreenKeyboardVisible
This property describes whether an on-screen keyboard is currently visible on the user's screen.
As UserInputService is client-side only, this property can only be used in a LocalScript, or a Script with RunContext set to Enum.RunContext.Client.
See also OnScreenKeyboardSize and OnScreenKeyboardPosition.
TouchEnabled
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 thenprint("The user's device has a touchscreen!")elseprint("The user's device does not have a touchscreen!")end
See also:
Code Samples
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
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.VREnabledif isUsingVR thenprint("User is using a VR headset!")elseprint("User is not using a VR headset!")end
As UserInputService is client-side only, this property can only be used in a LocalScript.
See also:
Code Samples
local VRService = game:GetService("VRService")
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 VRService.VREnabled then
-- Set the initial CFrame
head.CFrame = VRService:GetUserCFrame(Enum.UserCFrame.Head)
-- Track VR headset movement and mirror for character's head
VRService.UserCFrameChanged:Connect(TrackHead)
end
Methods
GamepadSupports
This function returns whether the given Enum.UserInputType gamepad supports a button corresponding with the given Enum.KeyCode. This function is used to determine valid gamepad inputs.
To determine which Enum.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
The Enum.UserInputType of the gamepad.
The Enum.KeyCode of the button in question.
Returns
Whether the given gamepad supports a button corresponding with the given Enum.KeyCode.
Code Samples
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 Enum.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
local UserInputService = game:GetService("UserInputService")
local function getActiveGamepad()
local activeGamepad = nil
local connectedGamepads = UserInputService:GetConnectedGamepads()
if #connectedGamepads > 0 then
for _, gamepad in connectedGamepads do
if activeGamepad == nil or gamepad.Value < activeGamepad.Value then
activeGamepad = gamepad
end
end
end
if activeGamepad == nil then -- Nothing is connected; set up for "Gamepad1"
activeGamepad = Enum.UserInputType.Gamepad1
end
return activeGamepad
end
if UserInputService.GamepadEnabled then
local activeGamepad = getActiveGamepad()
print(activeGamepad)
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
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
local UserInputService = game:GetService("UserInputService")
local bubble = script.Parent:WaitForChild("Bubble")
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
camera.CFrame = CFrame.new(0, 20, 0) * CFrame.Angles(-math.pi / 2, 0, 0)
if UserInputService.GyroscopeEnabled then
-- Bind event to when gyroscope detects change
UserInputService.DeviceGravityChanged:Connect(function(accel)
-- Move the bubble in the world based on the gyroscope data
bubble.Position = Vector3.new(-8 * accel.Position.X, 1.8, -8 * accel.Position.Z)
end)
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:
- The delta property describes the amount of rotation that last happened
- The CFrame is the device's current rotation relative to its default reference frame.
Code Samples
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
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 Enum.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
The Enum.UserInputType of the gamepad in question.
Returns
Whether a gamepad associated with Enum.UserInputType is connected.
Code Samples
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 Enum.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
The Enum.UserInputType corresponding with the gamepad in question.
Returns
An array of InputObjects representing the current state of all available inputs for the given gamepad.
GetImageForKeyCode
This method takes the requested Enum.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 an 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
The Enum.KeyCode for which to fetch the associated image.
Returns
The returned image asset ID.
Code Samples
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
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 Enum.UserInputType returned would be 'Keyboard'.
The UserInputService.LastInputTypeChanged event can be used to track when the last Enum.UserInputType used by the user changes.
As UserInputService is client-side only, this function can only be used in a LocalScript.
Returns
The Enum.UserInputType associated with the user's most recent input.
Code Samples
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 |
---|---|
MouseButton1 | The left mouse button. |
MouseButton2 | The right mouse button. |
MouseButton3 | The 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
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
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)
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
GetMouseLocation
This function returns a Vector2 representing the current screen location of the player's Mouse in pixels relative to the top left corner. This does not account for the GUI inset.
If the location of the mouse pointer is offscreen or the player's device does not have a mouse, the returned value will be undetermined.
As UserInputService is client-side only, this function can only be used in a LocalScript.
Returns
Code Samples
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local gui = script.Parent
local screenGui = gui.Parent
screenGui.IgnoreGuiInset = true
local function moveGuiToMouse()
local mouseLocation = UserInputService:GetMouseLocation()
gui.Position = UDim2.fromOffset(mouseLocation.X, mouseLocation.Y)
end
moveGuiToMouse()
RunService:BindToRenderStep("moveGuiToMouse", 1, moveGuiToMouse)
GetNavigationGamepads
This function returns an array of gamepad UserInputTypes that are connected and enabled for GUI navigation. This list is in descending order of priority, meaning it can be iterated over to determine which gamepad should have navigation control.
Whether a connected gamepad is a navigation gamepad only determines which gamepad(s) control the navigation GUIs. This does not influence navigation controls.
Since UserInputService is client-side only, this function can only be used in a LocalScript.
See also:
- UserInputService:SetNavigationGamepad(), to enable or disable a gamepad for GUI navigation
- UserInputService:IsNavigationGamepad(), to verify if a gamepad is enabled for GUI navigation
- UserInputService:GetConnectedGamepads(), to return all gamepads connected regardless of GUI navigational control
Returns
An array of UserInputTypes that can be used for GUI navigation, in descending order of priority.
GetStringForKeyCode
GetStringForKeyCode returns a string representing a key the user should press in order to input a given Enum.KeyCode, keeping in mind their keyboard layout. For key codes that require some modifier to be held, this function returns the key to be pressed in addition to the modifier. See the examples below for further explanation.
When using Roblox with a non‑QWERTY keyboard layout, key codes are mapped to equivalent QWERTY positions. For example, pressing A on an AZERTY keyboard results in Enum.KeyCode.Q. This mapping can lead to mismatched information on experience UI elements. For example, "Press M to open the map" is inaccurate on an AZERTY keyboard; it would need to be "Press ? to open the map" which is in the same position as M on QWERTY. This function solves this issue by providing the actual key to be pressed while using non‑QWERTY keyboard layouts.
local UserInputService = game:GetService("UserInputService")local textLabel = script.Parentlocal mapKey = Enum.KeyCode.MtextLabel.Text = "Press " .. UserInputService:GetStringForKeyCode(mapKey) .. " to open the map"
Examples on QWERTY Keyboard
KeyCode | Return Value |
---|---|
Enum.KeyCode.Q | Q |
Enum.KeyCode.W | W |
Enum.KeyCode.Equals | = |
Enum.KeyCode.At | 2 because @ is typed with Shift2 |
Examples on AZERTY Keyboard
KeyCode | Return Value |
---|---|
Enum.KeyCode.Q | A |
Enum.KeyCode.W | Z |
Enum.KeyCode.Equals | = |
Enum.KeyCode.At | É |
Gamepad Usage
GetStringForKeyCode() returns the string mapping for the Enum.KeyCode for the most recently connected gamepad. If the connected controller is not supported, the function returns the default string conversion for the requested key code.
The following example shows how you can map custom assets for ButtonA:
local UserInputService = game:GetService("UserInputService")local imageLabel = script.Parentlocal key = Enum.KeyCode.ButtonAlocal mappings = {ButtonA = "rbxasset://BUTTON_A_ASSET", -- Replace with the desired ButtonA assetButtonCross = "rbxasset://BUTTON_CROSS_ASSET" -- Replace with the desired ButtonCross asset}local mappedKey = UserInputService:GetStringForKeyCode(key)local image = mappings[mappedKey]imageLabel.Image = image
Gamepad Mappings
The directional pad key codes do not have any differences based on device. Enum.KeyCode.ButtonSelect has slightly different behavior in some cases. Use both PlayStation mappings to ensure users see the correct buttons.
KeyCode | PlayStation Return Value | Xbox Return Value |
---|---|---|
Enum.KeyCode.ButtonA | ButtonCross | ButtonA |
Enum.KeyCode.ButtonB | ButtonCircle | ButtonB |
Enum.KeyCode.ButtonX | ButtonSquare | ButtonX |
Enum.KeyCode.ButtonY | ButtonTriangle | ButtonY |
Enum.KeyCode.ButtonL1 | ButtonL1 | ButtonLB |
Enum.KeyCode.ButtonL2 | ButtonL2 | ButtonLT |
Enum.KeyCode.ButtonL3 | ButtonL3 | ButtonLS |
Enum.KeyCode.ButtonR1 | ButtonR1 | ButtonRB |
Enum.KeyCode.ButtonR2 | ButtonR2 | ButtonRT |
Enum.KeyCode.ButtonR3 | ButtonR3 | ButtonRS |
Enum.KeyCode.ButtonStart | ButtonOptions | ButtonStart |
Enum.KeyCode.ButtonSelect | ButtonTouchpad and ButtonShare | ButtonSelect |
System Images for KeyCodes
When using a Enum.KeyCode that may be better represented as an image, such as for an ImageLabel in a user interface, you can use the following legacy icons. However, it's recommended that you use GetImageForKeyCode() as a more modern, cross‑platform method to retrieve Xbox and PlayStation controller icons.
KeyCode | Image | Asset ID |
---|---|---|
Enum.KeyCode.ButtonX | rbxasset://textures/ui/Controls/xboxX.png | |
Enum.KeyCode.ButtonY | rbxasset://textures/ui/Controls/xboxY.png | |