Roblox accepts input from USB gamepads such as Xbox and Playstation controllers. Since gamepads can come in different varieties, you need to follow additional setup to verify that a user's gamepad inputs are usable in your experience.

To set up gamepad inputs, you can use UserInputService to perform the following:

When binding gamepad inputs, see common control schemas to create a consistent gamepad experience between experiences.

After your inputs are set, you can additionally customize your gamepads by including vibration feedback on supported controllers. See Haptic Feedback for instructions on verifying and activating vibrations.

Detecting Gamepads

You can detect whether a user's device currently has a gamepad active using the UserInputService.GamepadEnabled property.

Use the following sample code to print out a console message if the GamepadEnabled property is true:

1local UserInputService = game:GetService("UserInputService")
3if UserInputService.GamepadEnabled then
4 print("Player has gamepad enabled...")

You can connect up to eight local gamepads to a client at once. You can check for connected gamepads with GamepadConnected and GamepadDisconnected events. These events will fire when a device is connected or disconnected respectively. Both events will pass a UserInputType to the connected function indicating which gamepad caused the event. In most cases, the connected gamepad is UserInputType.Gamepad1.

Use the following code sample to print out the specific gamepad that is connected and disconnected:

1local UserInputService = game:GetService("UserInputService")
4 print("User has connected controller: " .. tostring(gamepad))
8 print("User has disconnected controller: " .. tostring(gamepad))

You can also query whether a particular controller is connected using the UserInputService:GetGamepadConnected() function. This takes a UserInputType as an argument and only accepts values of UserInputType.Gamepad1 through UserInputType.Gamepad8.

Use the following code sample to check for a specific gamepad and print a message if it is connected:

1local UserInputService = game:GetService("UserInputService")
2if UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad1) then
3 print("Gamepad1 is connected")
4elseif UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad2) then
5 print("Gamepad2 is connected")

Verifying Supported Inputs

Since gamepads can have different sets of inputs, check which inputs are supported with UserInputService:GetSupportedGamepadKeyCodes(). This function takes a UserInputType as an argument and returns a table with a list of all available inputs for the specified controller.

Use the following code sample to print out a list of available inputs detected from Gamepad 2:

1local UserInputService = game:GetService("UserInputService")
3local availableInputs = UserInputService:GetSupportedGamepadKeyCodes(Enum.UserInputType.Gamepad2)
4print("This controller supports the following controls:")
5for _, control in pairs(availableInputs) do
6 print(control)

Receiving Input

There are three ways to receive input from a gamepad:


You can use ContextActionService for binding controls to both gamepads and other input sources such as mobile touchscreen buttons or binding multiple functions to a single button input on any device. For example, use ContextActionService to bind an OpenSpellBook action to the right trigger (R2) on a gamepad and the B key on a keyboard in one function.

Use the following code sample to bind an OpenSpellBook action to the gamepad's R2 button and the B key on the keyboard:

1local ContextActionService = game:GetService("ContextActionService")
3local function openSpellBook(actionName, inputState, inputObject)
4 if inputState == Enum.UserInputState.Begin then
5 -- Open spell book
6 end
9ContextActionService:BindAction("OpenSpellBook", openSpellBook, false, Enum.KeyCode.ButtonR2, Enum.KeyCode.B)


You can use UserInputService to bind controls directly from a gamepad. When detecting gamepad events with UserInputService, use UserInputService.InputBegan to detect when the button was initially pressed and UserInputService.InputEnded to detect when the button is released.

In the handling function, the InputObject.UserInputType property indicates which gamepad fired the event and InputObject.KeyCode indicates the specific button or stick that fired it.

Use the following sample code to listen for an UserInputService.InputBegan event where the A button is pressed on Gamepad1:

1local UserInputService = game:GetService("UserInputService")
4 if input.UserInputType == Enum.UserInputType.Gamepad1 then
5 if input.KeyCode == Enum.KeyCode.ButtonA then
6 print("Button A pressed on Gamepad1")
7 end
8 end

Gamepad Input State

You can detect the current state of all buttons and sticks on a gamepad with the UserInputService:GetGamepadState() function. This is useful if you need to check the current gamepad inputs when a distinct event occurs in your experience. For example, you may want to check if specific buttons are being pressed when a character touches an object.

Use the following code sample to detect if the Gamepad1 R2 button is being held when the player character's left foot comes contacts a surface:

1local UserInputService = game:GetService("UserInputService")
3local player = game.Players.LocalPlayer
4local character = player.Character
5if not character or not character.Parent then
6 character = player.CharacterAdded:Wait()
9local leftFoot = character:WaitForChild("LeftFoot")
11-- When leftFoot comes into contact with something, check the gamepad input state
13 local state = UserInputService:GetGamepadState(Enum.UserInputType.Gamepad1)
14 for _, input in pairs(state) do
16 -- If the ButtonR2 is currently held then print out a message
17 if input.KeyCode == Enum.KeyCode.ButtonR2 and input.UserInputState == Enum.UserInputState.Begin then
18 print("Character's left foot touched something while holding right trigger")
19 end
20 end

Common Control Schemas

Gamepads come in a variety of shapes and sizes. As with any method of user input, it's best to create some consistency across different games and applications.

The following are common input binds that will help users immediately feel familiar and comfortable with the gamepad controls:

Input Common Use-cases
A button Accepts user prompts or GUI selections. Alternatively used for primary actions in an experience, such as jumping.
B button Cancels user prompts or GUI selections. Alternatively used for secondary actions in an experience, such as a dodge, roll, or sprint.
Left Thumbstick Generally associated with character movement.
Right Thumbstick Generally associated with camera movement.
Right Trigger Generally used for primary actions, such as shooting.
R1, L1 and X and Y buttons Secondary actions such as reloading, targeting or accessing an inventory or minimap.

Haptic Feedback

Many gamepad controllers, such as Xbox One controllers, have motors built in to provide haptic feedback. Adding rumbles and vibrations can greatly enhance a user's experience and provide subtle feedback beyond visuals or audio. You can use the HapticService to verify vibration support before turning on the controller motors.

Checking for Vibration Support

Not all controllers support vibration so it is important to check if the plugged-in controllers have support before attempting to use the controller motors. To check if a given controller has rumble support at all, you can call HapticService:IsVibrationSupported().

Use the following sample code to verify if vibration is supported on gamepad 1:

1local HapticService = game:GetService("HapticService")
2local isVibrationSupported = HapticService:IsVibrationSupported(Enum.UserInputType.Gamepad1)

Some controllers have multiple motors for various scales of vibration. Once you have checked if a gamepad supports vibration, you should also check if it supports the motors you intend to use. The Xbox One controller has 4 motors:

  • Large: in the left side of the controller. Good for generic rumble.
  • Small: in the right side of the controller. Good for more subtle rumbles(tire slipping, electric shock, etc.).
  • Left Trigger: underneath the left trigger. Good for braking, gun reloading, etc.
  • Right Trigger: underneath the right trigger. Good for recoil, acceleration, etc.

The user might not have a controller that supports all of these motors. Many only support the Large and Small motors (no triggers). You can use HapticService:IsMotorSupported() to see if the user's controller supports the motor you want to use.

Use the following sample code to verify if large vibration motors are supported on gamepad 1:

1local HapticService = game:GetService("HapticService")
2local isVibrationSupported = HapticService:IsVibrationSupported(Enum.UserInputType.Gamepad1)
3local largeSupported = false
4if isVibrationSupported then
5 largeSupported = HapticService:IsMotorSupported(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Large)

Turning on Motors

Once you have confirmed that a user's gamepad supports vibration you can start using the gamepad motors. You can use HapticService:SetMotor() to turn on a specific motor on a gamepad. This function takes the gamepad and the amplitude of the vibration as arguments. The amplitude can be any value between 0 and 1.

The following sample code sets the amplitude for gamepad 1's large motor to .5:

1local HapticService = game:GetService("HapticService")
2HapticService:SetMotor(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Large, .5)

You can also use HapticService:GetMotor() to get the current vibration amplitude of a given motor. Use the following code sample to print the current amplitude for gamepad 1's large motor:

1local HapticService = game:GetService("HapticService")
2print(HapticService:GetMotor(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Large)

The following code is a sample implementation of vibration when a user character gets into a vehicle, where the vibration is based on the throttle of the vehicle:

1-- Services
2local HapticService = game:GetService("HapticService")
3local Players = game:GetService("Players")
4local RunService = game:GetService("RunService")
6-- Make sure you are running in a LocalScript.
7local player = Players.LocalPlayer
8assert(player,"This should be running in a LocalScript!")
10-- Setup Haptic Feedback Listener
11local function updateHapticFeedback()
12 -- Check if you currently have a character.
13 local character = player.Character
14 if character then
15 -- Do you have a Humanoid?
16 local humanoid = character:FindFirstChildOfClass("Humanoid")
17 if humanoid then
18 -- Are you in a vehicle seat?
19 local seatPart = humanoid.SeatPart
20 if seatPart and seatPart:IsA("VehicleSeat") then
21 -- Measure the current speed of the vehicle by taking the magnitude of the seat's velocity.
22 local speed = seatPart.Velocity.Magnitude
24 -- Measure the current throttle from the user.
25 local throttle = math.abs(seatPart.ThrottleFloat)
27 -- Compute how much the controller should be vibrating.
28 local vibrationScale = math.min(1, (speed * throttle) / seatPart.MaxSpeed)
30 -- Apply the vibration.
31 HapticService:SetMotor(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Small, vibrationScale)
33 -- Return so the motor doesn't get reset.
34 return
35 end
36 end
37 end
39 -- If nothing is happening, turn off the motor.
40 HapticService:SetMotor(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Small, 0)
43-- Connect the haptic feedback listener to be updated 60 times a second.