Roblox accepts input from USB gamepads such as Xbox and Playstation controllers. A game can support up to eight local controllers per client.
You can detect whether a player’s device currently has a gamepad active using the
UserInputService/GamepadEnabled|UserInputService.GamepadEnabled property. Note that this property merely shows whether or not any gamepads are connected, not how many are plugged in or which slots they’re in.
local UserInputService = game:GetService("UserInputService") if UserInputService.GamepadEnabled then print("Player has gamepad enabled...") end
Since up to eight gamepads can be connected to a client at once, it’s important to know which are active. One method is to listen to the
UserInputService/GamepadDisconnected|GamepadDisconnected events which will fire when a device is enabled or disabled respectively. Both will pass a
Enum/UserInputType enum to the connected function indicating which gamepad caused the event (in most cases it will be
Enum.UserInputType.Gamepad1 but if your game supports local multiplayer, you should confirm this).
local UserInputService = game:GetService("UserInputService") UserInputService.GamepadConnected:Connect(function(gamepad) print("Player has connected controller: " .. tostring(gamepad)) end) UserInputService.GamepadDisconnected:Connect(function(gamepad) print("Player has disconnected controller: " .. tostring(gamepad)) end)
You can also actively query whether a particular controller is connected using the
UserInputService/GetGamepadConnected|UserInputService:GetGamepadConnected() function. This takes a
Enum/UserInputType enum as an argument and only accepts values of
local UserInputService = game:GetService("UserInputService") if UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad1) then print("Gamepad1 is connected") elseif UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad2) then print("Gamepad2 is connected") end
There are three ways to get input from a gamepad:
ContextActionServiceif you plan to bind custom game controls to both gamepads and other input sources like keyboards or mobile touch controls.
- Listen for gamepad events directly using
- Query the state of a gamepad’s input with the
ContextActionService is especially useful for binding controls to both gamepads and other input sources. For example, if you want to bind a custom “open spell book” action to the right trigger (R2) on a gamepad and the B key on a keyboard,
ContextActionService can handle both cases in one function:
local ContextActionService = game:GetService("ContextActionService") local function openSpellBook(actionName, inputState, inputObject) if inputState == Enum.UserInputState.Begin then -- Open spell book end end ContextActionService:BindAction("OpenSpellBook", openSpellBook, false, Enum.KeyCode.ButtonR2, Enum.KeyCode.B)
ContextActionServicewill fire on all input states (
enum/UserInputState|End), so it's highly recommended that you check the
InputObject/UserInputState|UserInputStateas seen on line 4 to ensure the desired action only happens on the state you intend it to.
When detecting gamepad events with
UserInputService, all of the controls will fire the
UserInputService/InputEnded|InputEnded events. 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.
local UserInputService = game:GetService("UserInputService") UserInputService.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.Gamepad1 then if input.KeyCode == Enum.KeyCode.ButtonA then -- Button A pressed end end end)
Most gamepads also support analog controls. To detect input from these, use the
UserInputService/InputChanged|InputChanged event and detect the position of the input’s axis via
InputObject/Position. The thumbstick’s position will always be on the X and Y axes between the values of -1 and 1, while the trigger buttons will only have values between 0 and 1 on the Z axis (0 at its starting position; 1 when fully pressed).
local UserInputService = game:GetService("UserInputService") UserInputService.InputChanged:Connect(function(input, processed) if input.UserInputType == Enum.UserInputType.Gamepad1 then if input.KeyCode == Enum.KeyCode.Thumbstick1 then print(input.Position.X, input.Position.Y) end end end)
Gamepad Input State
The state of all the buttons and sticks on a gamepad can be detected at any time with the
UserInputService/GetGamepadState|UserInputService:GetGamepadState() function. This is useful if you need to detect gamepad input when a non-controller event occurs. For example, the following code detects when a character’s left foot touches something while the player is holding down the right trigger:
local UserInputService = game:GetService("UserInputService") local player = game.Players.LocalPlayer local character = player.Character if not character or not character.Parent then character = player.CharacterAdded:Wait() end local leftFoot = character:WaitForChild("LeftFoot") leftFoot.Touched:Connect(function(hit) local state = UserInputService:GetGamepadState(Enum.UserInputType.Gamepad1) for _, input in pairs(state) do 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)
Not all gamepads have the same number or types of inputs, so it’s important to check which inputs a connected gamepad has. You can do so with the
UserInputService/GetSupportedGamepadKeyCodes|UserInputService:GetSupportedGamepadKeyCodes() function which takes a
Enum/UserInputType enum as an argument and returns a table with a list of all available inputs for the specified controller.
local UserInputService = game:GetService("UserInputService") local availableInputs = UserInputService:GetSupportedGamepadKeyCodes(Enum.UserInputType.Gamepad2) print("This controller supports the following controls:") for _, control in pairs(availableInputs) do print(control) end
As with any method of user input, it’s best to create some consistency across different games and applications. This helps players immediately feel familiar and comfortable with your control scheme. Here are some suggested practices when implementing gamepad controls:
- If you implement any user prompts or GUI selection, the A button should be “accept.”
- For any GUI or any state that is modal, the B button should be “cancel.”
- On-screen hints for which buttons do what are helpful, especially for a complicated GUI like an inventory system, upgrade system, etc.
- Character movement should be tied to the left thumbstick.
- Camera movement should be tied to the right thumbstick.
- Primary actions usually happen with the right trigger (R2) or the A button.
- Secondary actions usually happen with the left trigger (L2) or the R1 and L1 buttons. If you’re tying a secondary action to a front-face button, X and Y are good choices.
- Allowing players to remap buttons can make your game much more accessible.