Roblox accepts input from USB gamepads such as Xbox and PlayStation controllers. Since gamepads come in different varieties, you need to follow additional setup to verify that a player's gamepad inputs are usable in your experience.
To set up gamepad inputs, you can use UserInputService to detect connected gamepads for a player's device, verify supported inputs that are compatible with Roblox, receive input, and more.
When binding gamepad inputs, see common control schemas to create a consistent gamepad experience for players. After inputs are set, you can enhance the player's experience by including haptic feedback on supported controllers.
Detect gamepads
You can detect whether a player's device currently has a gamepad active using the UserInputService.GamepadEnabled property.
Detecting Gamepad
local UserInputService = game:GetService("UserInputService")if UserInputService.GamepadEnabled thenprint("Player has gamepad enabled...")end
You can check for connected gamepads via UserInputService.GamepadConnected and UserInputService.GamepadDisconnected events. These events fire when a device is connected or disconnected respectively, and both events pass a Enum.UserInputType to the connected function indicating which gamepad caused the event. In most cases, the connected gamepad is Gamepad1.
Checking Connection and Disconnection
local UserInputService = game:GetService("UserInputService")
UserInputService.GamepadConnected:Connect(function(gamepad)
print("User has connected controller: " .. tostring(gamepad))
end)
UserInputService.GamepadDisconnected:Connect(function(gamepad)
print("User has disconnected controller: " .. tostring(gamepad))
end)
You can also query whether a particular controller is connected using the UserInputService:GetGamepadConnected() method. This takes a Enum.UserInputType as an argument and only accepts values of Gamepad1 through Gamepad8.
Query Specific Gamepad Connection
local UserInputService = game:GetService("UserInputService")if UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad1) thenprint("Gamepad1 is connected")elseif UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad2) thenprint("Gamepad2 is connected")end
Verify supported inputs
Since gamepads can have different sets of inputs, you should check which inputs are supported with UserInputService:GetSupportedGamepadKeyCodes(). This method takes a Enum.UserInputType as an argument and returns a table with a list of all available inputs for the specified controller.
Verifying Supported Inputs
local UserInputService = game:GetService("UserInputService")local availableInputs = UserInputService:GetSupportedGamepadKeyCodes(Enum.UserInputType.Gamepad2)print("This controller supports the following controls:")for _, control in availableInputs doprint(control)end
Receive input
You can use UserInputService to bind controls directly from a gamepad. When detecting gamepad events through this service, use the InputBegan event to detect when the button was initially pressed and 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.
UserInputService Button Press Detection
local UserInputService = game:GetService("UserInputService")
UserInputService.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonA then
print("Button A pressed on Gamepad1")
end
end
end)
Gamepad state
You can detect the current state of all buttons and sticks on a gamepad with the UserInputService:GetGamepadState() method. This is useful if you need to check the current gamepad inputs when a distinct event occurs in your experience, such as checking if specific buttons are being pressed when a character touches an object.
Checking State of Gamepad Inputs
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local leftFoot = character:WaitForChild("LeftFoot")
-- When left foot comes into contact with something, check the gamepad input state
leftFoot.Touched:Connect(function(hit)
local state = UserInputService:GetGamepadState(Enum.UserInputType.Gamepad1)
for _, input in state do
-- If the ButtonR2 is currently held, print out a message
if input.KeyCode == Enum.KeyCode.ButtonR2 and input.UserInputState == Enum.UserInputState.Begin then
print("Character's left foot touched something while holding right trigger")
end
end
end)
Trigger pressure
You can detect how much pressure is being placed on gamepad triggers by checking the Position.Z value of the input trigger.
Testing Trigger Pressure
local UserInputService = game:GetService("UserInputService")
UserInputService.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonL2 then
print("Pressure on left trigger has changed:", input.Position.Z)
elseif input.KeyCode == Enum.KeyCode.ButtonR2 then
print("Pressure on right trigger has changed:", input.Position.Z)
end
end
end)
Common control schemas
Gamepads come in a variety of shapes and sizes. As with any method of player input, it's best to create some consistency across different games and experiences.

The following are common input binds that will help players immediately feel familiar and comfortable with the gamepad controls:
Input | Common use cases |
---|---|
ButtonA | Accepts player prompts or GUI selections. Alternatively used for primary actions such as jumping. |
ButtonB | Cancels player prompts or GUI selections. Alternatively used for secondary actions such as a dodge, roll, or sprint. |
Thumbstick1 | Generally associated with character movement. |
Thumbstick2 | Generally associated with camera movement. |
ButtonL2, ButtonR2 | Generally used for primary actions, such as shooting. |
ButtonL1, ButtonR1, ButtonX, ButtonY | Secondary actions such as reloading, targeting, or accessing an inventory or minimap. |
Haptic feedback
Many gamepad controllers have motors built in to provide haptic feedback. Adding rumbles and vibrations can greatly enhance a player's experience and provide subtle feedback beyond visuals or audio.
Roblox supports haptics for the following devices:
- Android and iOS phones supporting haptics including most iPhone, Pixel, and Samsung Galaxy devices
- PlayStation gamepads
- Xbox gamepads
- Quest Touch controller
Haptic feedback is managed through HapticEffect instances which can be set to a specific Type such as GameplayCollision or UIClick.
Once a HapticEffect is in place, you can initiate it through the Play() method, for instance:
local Workspace = game:GetService("Workspace")local effect = Instance.new("HapticEffect")effect.Type = Enum.HapticEffectType.GameplayExplosioneffect.Parent = Workspace-- Play the haptic effecteffect:Play()
Controller emulation
The Controller Emulator lets you accurately emulate gamepad input directly in Studio. The default controller is a generic gamepad, but you can select alternatives for PlayStation, Xbox, and Quest devices from the upper‑left picker menu.


While playtesting, you can control the experience with the virtual controller using your mouse.
You can also click Edit mappings in the upper‑right corner to view and edit key mappings for the virtual controller, for example E to ButtonL2 or 9 to ButtonA. These mappings are saved like other Studio settings (per controller, per user, per computer) and are translated to gamepad events in both the emulator window and the 3D viewport.