CurrentScreenOrientation is not always accurate

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:

  1. Have “ScreenOrientation” in ScreenGui set to “Portrait”
  2. Add a script that sets your ScreenOrientation in PlayerGui to “Sensor” after a few seconds of you being in the place
  3. Print the current orientation

This is consistent across Studio and iOS.

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).

1 Like

Mind sharing this code? This bug is sort of messing with some features we want to release.

Code:
https://pastebin.com/qeSHF8vK

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)
6 Likes

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.

3 Likes

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.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.