Roblox includes various control schemes for mobile devices (phones and tablets). Players can choose which control scheme they want to use by changing the mode in the in-game Settings menu.
In many cases, the slight differences between the control schemes don’t matter much to how the game plays and you can let players decide what scheme they like. However, if you feel that one of the schemes suits your game better than the others, you can enforce which one the player uses. To do this, set the
StarterPlayer to the scheme you want.
Included Control Schemes
Thumbstick is the default control scheme for Roblox games on mobile devices. It features a virtual thumbstick on the left and a “jump” button on the right. The thumbstick floats, meaning that when the player pushes the stick far enough, the center of the stick will move with the player’s finger. When the player lets go, the thumbstick snaps back to the original position.
Thumbstick is a good generic controller. However It becomes harder to use if you have a lot of GUI elements on the screen since the floating thumbstick can move anywhere on the screen. If your screen GUI is mostly empty, this is a good control scheme to use.
Thumbpad is very similar to the Thumbstick scheme. Movement controls are on the left and a “jump” button is on the right. The primary difference between Thumbpad and Thumbstick is that the Thumbpad controls do not float.
Thumbpad should be used when you have GUI elements on the screen that could potentially be covered by the floating controls of the Thumbstick.
DPad is a control scheme where all of the movement controls are consolidated into one widget on the left-hand side of the screen. Pressing on the outside of the widget moves the character, while pressing the center makes the character jump. While this widget is a little larger than the Thumbstick or Thumbpad controls, it opens up the lower-right corner of the screen for other UI elements.
DPad works well if you need the space normally occupied by the “jump” button in the Thumbstick or Thumbpad schemes. DPad also works well when jumping isn’t as important in your game and you want the player’s right hand to be able to perform other game actions.
Click to Move
Click to Move does not add any UI elements to the screen by default. Instead, when the player taps on the screen, the character tries to reach the touched position. A small sphere will appear where the player taps to give feedback to the player. If a path can be found to the point, the sphere will be white. If there is no valid path, the sphere will flash red.
If the player tries to reach an invalid point more than three times in a row, the Thumbstick control scheme will appear to help the player reach the desired point. The Thumbstick controls will disappear the next time the player taps a valid point on the screen.
Since this scheme doesn’t normally display any GUI elements, it’s ideal when you want to use the screen space for other purposes, or if you want to keep a simple and clean look for your game. Jumping, however, is harder with this control scheme and should not be used if jumping is a key mechanic in your game.
Sometimes the standard Roblox control schemes will not work for your game, in which case you should make your own custom controls. The best way to do this is to overwrite the
LocalScript named ControlScript that normally gets replicated into the
Player instance when a player joins the game.
In the following example, we will create custom controls for mobile for a character that is always running. Swiping left or right will make the character strafe left and right. Swiping up will make the character run straight ahead.
In StarterPlayer → StarterPlayerScripts, add two new
LocalScript|LocalScripts, one called ControlScript and one called CameraScript. These will override the default movement and camera controls that Roblox provides.
In the camera script, we will simply attach the camera behind the character. In the CameraScript script, paste this code:
-- This code should go in the 'CameraScript' script within 'StarterPlayerScripts' local Camera = game.Workspace.CurrentCamera local Player = game.Players.LocalPlayer local function OnCharacterAdded(character) wait() Camera.CameraType = Enum.CameraType.Attach Camera.CameraSubject = character:WaitForChild("HumanoidRootPart") end Player.CharacterAdded:connect(OnCharacterAdded)
In the ControlScript script, we need to do two things:
First, we need to make the player character start running forward as soon as it spawns. The humanoid
Humanoid/Move|Move()function will be useful for this. The first argument of this function is the direction you want the character to move. The second argument sets whether you want that direction to be relative to the camera or to the world. Since we want the character to run away from the camera, we will set the first argument to
Vector3.new(0, 0, -1)and the second argument to
We will also be using the
Humanoid/Move|Move()function to strafe the character. When you use this function to move a character side to side, the character will turn by default. We want the character to strafe in this case, so we will also set
-- This code should go in the 'ControlScript' script within 'StarterPlayerScripts' local Player = game.Players.LocalPlayer local function OnCharacterAdded(character) local humanoid = character:WaitForChild("Humanoid") humanoid:Move(Vector3.new(0, 0, -1), true) humanoid.AutoRotate = false end Player.CharacterAdded:connect(OnCharacterAdded)
If we run the game now, the character will start running forward without stopping. We need to add a function to move the character when the player swipes on the screen. We will bind the function to the
local UserInputService = game:GetService("UserInputService") local function OnSwipe(swipeDirection) local character = Player.Character if not character then return end local humanoid = character:FindFirstChild("Humanoid") if not humanoid then return end if swipeDirection == Enum.SwipeDirection.Up then humanoid:Move(Vector3.new(0, 0, -1), true) elseif swipeDirection == Enum.SwipeDirection.Left then humanoid:Move(Vector3.new(-1, 0, -1), true) elseif swipeDirection == Enum.SwipeDirection.Right then humanoid:Move(Vector3.new(1, 0, -1), true) end end UserInputService.TouchSwipe:connect(OnSwipe)
In the function, we first do some checks to make sure that the character and humanoid exist, just in case the player swipes the screen while the character is spawning. Next, we move the character based on the direction of the swipe. The
UserInputService/TouchSwipe|TouchSwipe event passes a value from the
Enum/SwipeDirection|SwipeDirection enumeration. Based on which value was passed in, we then move the character in the appropriate direction.