When you enter a game which has the ScreenOrientation set to Portrait manually, CurrentOrientation won’t reflect that. You have to rotate the device to Landscape and then go back to Portrait on your device.
Here is a screenshot showing the current orientation and what the code is reading:
Notice the “Changing to Enum.ScreenOrientation.LandscapeLeft”. It prints something like that accordingly WHENEVER the CurrentScreenOrientation is changed.
My repro:
Have “ScreenOrientation” in ScreenGui set to “Portrait”
Add a script that sets your ScreenOrientation in PlayerGui to “Sensor” after a few seconds of you being in the place
When you flip the phone upside down (let’s call it “upside-down portrait”), it also doesn’t detect that screen transition, it will be stuck on landscape if you were in landscape before. Nasty bugs with the init and not capturing certain transitions.
I worked around these issues for now by making a custom “screen orientation” signal that checks for size changes, it checks if the axes were flipped (only when touchenabled=true).
For the people reading along that don’t wanna download:
code listing
local DisplayMode = {}
-- Possible display modes:
DisplayMode.Regular = 0 -- pc and console
DisplayMode.Landscape = 1 -- mobile/tablet sideways
DisplayMode.Portrait = 2 -- mobile/tablet upright
-- Propagating changes in display mode:
local changedEvent = Instance.new("BindableEvent")
changedEvent.Event:connect(function() end)
DisplayMode.Changed = changedEvent.Event
local function mobileDetectChange()
-- When screen size changes:
local function screenSizeChanged()
-- Check state based on screen size, because freaking Roblox API doesn't work properly:
local isPortrait = workspace.Camera.ViewportSize.X < workspace.Camera.ViewportSize.Y
if isPortrait then
if DisplayMode.Current ~= DisplayMode.Portrait then
-- Switch to Portrait and notify listeners:
DisplayMode.Current = DisplayMode.Portrait
changedEvent:Fire(DisplayMode.Current)
end
else
if DisplayMode.Current ~= DisplayMode.Landscape then
-- Switch to Landscape and notify listeners:
DisplayMode.Current = DisplayMode.Landscape
changedEvent:Fire(DisplayMode.Current)
end
end
end
-- Listen for changes:
workspace.Camera:GetPropertyChangedSignal("ViewportSize"):connect(screenSizeChanged)
screenSizeChanged()
end
if not game:GetService("UserInputService").TouchEnabled or game:GetService("UserInputService").KeyboardEnabled or game:GetService("UserInputService").MouseEnabled
or game:GetService("UserInputService").GamepadEnabled or game:GetService("GuiService"):IsTenFootInterface() then
-- User is playing on a device with a non-touch screen/keyboard/mouse/gamepad/large screen, so assume pc/console mode:
DisplayMode.Current = DisplayMode.Regular
-- So that it works with Studio mobile emulator:
if game:GetService("RunService"):IsStudio() and game:GetService("UserInputService").TouchEnabled then
mobileDetectChange()
end
else
-- Assume mobile or tablet mode, start out as landscape until PlayerGui available:
DisplayMode.Current = DisplayMode.Landscape
mobileDetectChange()
end
return DisplayMode
Usage:
local DisplayMode = require((...).DisplayMode)
local function displayModeChanged(current)
if current == DisplayMode.Regular then
-- desktop, console
elseif current == DisplayMode.Portrait then
-- mobile portrait
elseif current == DisplayMode.Landscape then
-- mobile landscape
end
end
DisplayMode.Changed:connect(displayModeChanged)
-- Do code for starting mode of device:
displayModeChanged(DisplayMode.Current)
Thanks for the report, I’ll see if I can reproduce it here and fix it if necessary. I have a hunch, at least.
Also, FWIW, I recommend checking the screen proportions anyway. I did this when implementing the settings menu UI in portrait mode so that it works on desktop as well. I kind of consider this property to have been a mistake. It’s a little misleading; it was originally intended to let you differentiate between landscape left and landscape right, not between landscape and portrait.
Thoroughly agree, checking for viewport changes is much more intuitive to me and also simpler than having to wait for PlayerGui to exist etc.
What were the use cases for differentiating between landscape left and right anyway? Permanent positions for UI items (not relative to mode) if the developer wanted?
Can’t really remember, tbh. This is why I consider it mostly a mistake. I was probably thinking about correcting the accelerometer value, but we could just do that in-engine! I suppose someone might come up with a clever use of it some day.