Over half of all Roblox sessions are played on mobile devices, so it's important to consider cross-platform accessibility when designing an experience for a wide audience. For mobile inputs, design around the device orientation that you intend players to use in your experience, and consider that the player may have other input devices connected such as a bluetooth mouse/keyboard or gamepad.
Device orientation
On phones and tablets, the device orientation considerably affects the player experience and interaction. For example, landscape mode is best operated with two thumbs while portrait mode may lend itself to one-finger interface.
By default, Roblox experiences run in landscape mode, allowing the experience to switch between landscape "left" and landscape "right" as the player's device rotates. However, experiences can be locked to a particular orientation if desired.
Orientation modes
There are five different orientation modes, including two sensor-based modes and three locked modes.
Sensor modes | |
---|---|
Landscape sensor | The default Roblox setting in which the experience always appears in landscape mode (no portrait mode) and the device detects its physical orientation to ensure the experience view is always oriented upward. |
Sensor | The device detects its physical orientation to ensure the experience view is always oriented upward, switching between landscape and portrait mode as needed. |
Locked modes | |
---|---|
Landscape left | On devices with a physical home button, the home button is to the left of the display. On devices with a virtual home/nav bar, its touch region is at the bottom of the display. |
Landscape right | On devices with a physical home button, the home button is to the right of the display. On devices with a virtual home/nav bar, its touch region is at the bottom of the display. |
Portrait | On devices with a physical home button, the home button is below the display. On devices with a virtual home/nav bar, its touch region is at the bottom of the display. |
Orientation properties
When setting an orientation, you can set the starting orientation, the in-experience orientation, and the current orientation.
Starting orientation
StarterGui.ScreenOrientation sets the default orientation for a place. Acceptable values include:
Because this property affects all new players who join the experience, you can set its value in StarterGui.ScreenOrientation within Studio.
In-experience orientation
PlayerGui.ScreenOrientation explicitly changes the experience's orientation for a player. When this property is set to one of the Enum.ScreenOrientation enums in a LocalScript, the experience will immediately orient itself to match the setting. This can be useful when an experience needs to provide a particular experience like locking the view to portrait for a minigame.
The following code sample in a LocalScript sets the screen orientation to portrait:
local Players = game:GetService("Players")local playerGUI = Players.LocalPlayer:WaitForChild("PlayerGui")task.wait(2)playerGUI.ScreenOrientation = Enum.ScreenOrientation.Portrait
Current orientation
PlayerGui.CurrentScreenOrientation gets the current device orientation. Possible values include:
The following code prints the player's current screen orientation:
local Players = game:GetService("Players")local playerGUI = Players.LocalPlayer:WaitForChild("PlayerGui")print(playerGUI.CurrentScreenOrientation)
Detect other devices
In cross-platform experiences, it's important to reference the player's preferred input options by displaying input options for the actively used device. For example, a mobile device can have a mouse and keyboard or gamepad connected, or it's possible that a desktop has a touchscreen enabled. If multiple input sources are enabled, you can use GetLastInputType() to get the player's last used input device.
As a foundation, you can use the following ModuleScript, placed within ReplicatedStorage and renamed to UserInputModule, to fetch the player's input type, after which you can adapt the UI layout or context to your experience's specific needs.
local UserInputService = game:GetService("UserInputService")
local UserInput = {}
local inputTypeString
-- If device has active keyboard and mouse, assume those inputs
if UserInputService.KeyboardEnabled and UserInputService.MouseEnabled then
inputTypeString = "Keyboard/Mouse"
-- Else if device has touch capability but no keyboard and mouse, assume touch input
elseif UserInputService.TouchEnabled then
inputTypeString = "Touch"
-- Else if device has an active gamepad, assume gamepad input
elseif UserInputService.GamepadEnabled then
inputTypeString = "Gamepad"
end
function UserInput.getInputType()
local lastInputEnum = UserInputService:GetLastInputType()
if lastInputEnum == Enum.UserInputType.Keyboard or string.find(tostring(lastInputEnum.Name), "MouseButton") or lastInputEnum == Enum.UserInputType.MouseWheel then
inputTypeString = "Keyboard/Mouse"
elseif lastInputEnum == Enum.UserInputType.Touch then
inputTypeString = "Touch"
elseif string.find(tostring(lastInputEnum.Name), "Gamepad") then
inputTypeString = "Gamepad"
end
return inputTypeString, lastInputEnum
end
return UserInput
Once the UserInputModule script is in place, use the following code sample in a LocalScript to get the user's last input type:
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Require modulelocal UserInputModule = require(ReplicatedStorage:WaitForChild("UserInputModule"))local currentUserInput, inputEnum = UserInputModule.getInputType()print(currentUserInput, inputEnum)