Update: Notched Screen Support - fully released to mobile clients
Hi Developers!
We want to share how Roblox will be rendered on notched mobile devices going forward and allow you to try this out as a Studio Beta feature.
Notched screen support allows your experiences to use every pixel of mobile displays, regardless of their shape. We believe this will make your experiences feel even more immersive.
-
Current: if a phone has a notch that pushes into the screen, Roblox displays a black bar in the area around the notch
-
Future: We will remove the black bar and render Roblox across the entire screen for all experiences
- The 3D viewport will fill the entire visible screen area, including the notch area
- UI in ScreenGuis will automatically adapt to notched screens
We aim to preserve existing UI layouts as much as possible, but there are some important differences that you should be aware of:
-
ScreenGui content will be inset on both sides into the screenâs safe area, ensuring that UI does not sit underneath the hardware notch.
-
GuiObjects that cover the entire safe area and were previously full screen, will be expanded by default to cover the notch area (i.e. full screen backgrounds are still full screen).
-
New ScreenGui properties will allow you to further customize how this works.
Hereâs an example of what notch screen support looks like in Livetopia:
How can I try out Notched Screen Support?
You can preview this change as a Studio Beta feature with notched emulation devices that have been added to the emulator to test your experiences. The emulated devices allow you to see what your UI will look like on mobile devices with different notch types.
Hereâs how to enable the Studio Beta for Notched Screen Support and test the feature:
-
Go to File â Beta Features and click the checkbox next to âNotched Screen Supportâ:
-
Restart Roblox Studio.
-
Open the Studio Device Emulator by clicking on the âTestâ tab, then click the âDeviceâ button:
-
Click on the device selector in the toolbar and change the emulation device to one with a notch:
-
Try the new emulation devices that have notches or screen cutouts:
- iPhone X
- iPhone XR
- Samsung Galaxy A51
- Xiaomi Redmi Note 9
- iPhone 14 Pro
Remember - you can test both landscape and portrait display modes by clicking the button to the right of the device model to rotate the emulated screen.
Details
- What are ânotchedâ screens?
- How will Roblox be rendered on notched displays?
- What is a safe area?
- Do I have to update my experiences to support notched screens?
- How is UI in ScreenGuis automatically adapted for notched displays?
- Design Tips: How to update your UI for notched devices
What are ânotchedâ screens?
Recently, mobile devices have come out with new screen shapes that arenât simple rectangles. Modern mobile displays can include notches, hole punch cutouts, and rounded corners. Here are some examples:
How will Roblox be rendered on notched displays?
We are making 3 core changes to how Roblox is rendered on notched displays:
-
The 3D viewport now fills the entire display area, including the area around the notch:
-
By default, UI in ScreenGuis is automatically adapted to support notched displays. This allows existing and new UI that is authored for rectangular displays, to work on non-rectangular displays:
-
For backwards compatibility on notched screens, Lua APIs which refer to the 3D viewport (such as Camera.ViewportSize) now refer to the device safe area viewport. This change wonât break existing games using the 3D viewport APIs. Additional details on behavior changes can be found below.
What is a safe area?
Safe areas are screen regions that help us simplify UI design across different devices. Portrait and Landscape safe areas are shown in the diagram below.
-
The Device Safe Area (shown in green) is a rectangular screen region that is not occluded by any hardware screen cutouts from notches or camera hole punches.
-
The Core UI Safe Area (shown in blue) is a rectangular screen region within the Device Safe Area that does not include the Roblox top bar.
Do I have to update my experiences to support notched screens?
For the 3D viewport portion of your experience, no action is needed to use the full-screen area! The 3D viewport will automatically fill the entire available screen area, including the notch area.
For the 2D UI portion of your experience, we anticipate that most experiences wonât need major changes. Weâve added several automatic UI adaptation features to make many existing UIs automatically compatible with notched screens (see the next section). However, we still encourage you to test your experience on notched devices in the Studio Device Emulator.
The following types of UI may need adjustments to provide optimal notch support:
-
Separate UI objects that donât individually cover the screen are not automatically extended. If you have multiple Frames that cover different parts of the screen, but each one doesnât individually cover the entire screen, these Frames wonât be automatically extended to the fullscreen area. For example, if you have a Frame covering the top bar, and another covering the rest of the screen, neither Frame will be extended!
-
âEdge-anchoredâ UI that is designed to be at the edge of the screen and do not work as well as floating elements
-
Animated UI that transitions from onscreen â offscreen or vice versa.
See below for more details on the automatic UI adaption features as well as some additional tips on how to author UI that works on all screen types.
New ScreenGui APIs
We are adding 3 new properties to ScreenGui so that you can customize how your screen-space UI is adapted to notched screens. Please read the following collapsed sections for an in-depth explanation of how each new API works.
New Property | Type | Default Value | Description |
---|---|---|---|
ScreenGui. ScreenInsets | Enum. ScreenInsets | CoreUISafeInsets | The insets that are applied to all children of this ScreenGui. This can be None , DeviceSafeInsets , or CoreUISafeInsets . This corresponds to the safe areas described above. |
ScreenGui. SafeAreaCompatibility | Enum. SafeAreaCompatibility | FullscreenExtension | What transformations, if any, are applied to this ScreenGuiâs descendants to improve safe area compatibility. The current options are None and FullscreenExtension . |
ScreenGui. ClipToDeviceSafeArea | boolean | true | If true, all descendants are clipped to the device safe area. |
Extended Functionality
We are investigating a new UI component to extend specific GuiObjects within a ScreenGui, to the edges of the fullscreen area (beyond the safe area). Weâd like to understand whether the existing functionality in the Beta is adequate or whether additional control is required. Please let us know!
How is UI in ScreenGuis automatically adapted for notched displays?
We can use the safe areas defined above to automatically adapt the most common types of UI to notched displays. Here are the 3 adaptation techniques that we are using:
- Adding safe area insets
- Automatic background expansion
- Clipping to Device Safe Area
  1. Adding safe area insets
Click to show...
To ensure UI isnât cut-off in existing experiences when running on displays with notches and screen cutouts, we modify the boundaries of each ScreenGui as follows:
- ScreenGuis with IgnoreGuiInset=false use the Core UI Safe Area bounds.
- ScreenGuis with IgnoreGuiInset=true use the Device Safe Area bounds.
This effectively adds safe area insets to each ScreenGui:
How can I customize safe area insets?
You can customize the safe area insets applied to a ScreenGui using the new ScreenGui.ScreenInsets
property.
The ScreenInsets
property controls whether the ScreenGuiâs content are laid out in the fullscreen area, or in one of the 2 safe areas defined above.
New Property | Type | Default Value | Description |
---|---|---|---|
ScreenGui. ScreenInsets | Enum. ScreenInsets | CoreUISafeInsets | The insets that are applied to all children of this ScreenGui. This can be None , DeviceSafeInsets , or CoreUISafeInsets . This corresponds to the safe areas described above. |
Example
You can put UI that is meant to be part of the âbackgroundâ (i.e. OK to sit underneath a notch) in a ScreenGui with ScreenInsets=None. On the other hand, any UI that needs to be entirely visible (like text or buttons) should be placed in a ScreenGui with ScreenInsets=CoreUISafeInsets or DeviceSafeInsets.
Example, where the left menu is placed in a ScreenGui with ScreenInsets=CoreUISafeInsets, while the background ScreenGui has ScreenInsets=None:
  2. Automatic background expansion
Click to show...
Some types of UI elements will look better if they are not inset into the safe area. For example, fullscreen backgrounds such as loading screens, feel more immersive if they cover the entire visible area.
To support this use case, we automatically detect âfullscreenâ GuiObjects and expand their backgrounds to cover the fullscreen area. Hereâs what this looks like in action:
How does GuiObject background extension work?
We define the âbackgroundâ of a GuiObject to be the color specified by GuiObject.BackgroundColor3
. For ImageLabel/ImageButton, the Image is part of the background. For VideoFrame, the video is part of the background.
We define the âcontentâ of a GuiObject to be the area containing any text content (for TextLabel, TextButton, TextBox Instances), and the area containing the GuiObjectâs children. We show the background and content areas for each type of GuiObject below:
If a GuiObject is in a ScreenGui with SafeAreaCompaibility = FullscreenExtension and the GuiObjectâs bounds cover the Device Safe Area, then only the background of the GuiObject is extended to cover the Fullscreen Area.
How can I customize fullscreen background expansion?
You can enable/disable automatic fullscreen background expansion using the new ScreenGui.SafeAreaCompatibility
property:
New Property | Type | Default Value | Description |
---|---|---|---|
ScreenGui. SafeAreaCompatibility | Enum. SafeAreaCompatibility | FullscreenExtension | What transformations, if any, are applied to this ScreenGuiâs descendants to improve safe area compatibility. The current options are None and FullscreenExtension . |
  3. Clipping to Device Safe Area
Click to show...
On a notched screen, GuiObjects that are located just outside the screen boundaries might now be visible due to safe area insets pushing in the ScreenGui boundaries.
To ensure GuiObjects that are positioned off screen on rectangular screens, are still not visible to notch phone users, we automatically clip ScreenGui contents outside the Device Safe Area. This clips the âunsafe areaâ outside the Device Safe Area, because this area is normally off screen on rectangular screens. Hereâs what this looks like:
How can I customize safe area clipping?
Weâve added the ScreenGui.ClipToDeviceSafeArea
property to control the ScreenGuiâs clipping behavior:
New Property | Type | Default Value | Description |
---|---|---|---|
ScreenGui. ClipToDeviceSafeArea | boolean | true | If true, all descendants are clipped to the device safe area. |
Design Tips: How to update your UI for notched devices
Click to show...
-
Edge Anchored UI
If your experience contains UI elements that are anchored to one or more screen edges, check how these look on a notched device with the Studio Device Emulator. Consider a âfloatingâ UI design that will work on all types of mobile devices.
-
UI animation on and off screen
If your experience animates UI elements from offscreen to onscreen, or vice versa, consider setting ScreenGui.ClipToDeviceSafeArea=false on the ancestor ScreenGui. This will prevent GuiObjects from being clipped as they travel on/off the screen. You may need to add offsets to the offscreen position of GuiObjects to ensure they move completely off screen, due to the visible area outside of the safe area. -
Off screen placeholder for UI animation
A method to handle offscreen animations with safe area insets is to create a hidden âplaceholderâ GuiObject in a ScreenGui with ScreenInsets=None. Make sure this placeholder is outside of the ScreenGuiâs visible area. This ensures the placeholder GuiObject is always offscreen for any value of the safe area insets. When tweening a GuiObject offscreen, set its final position to be the placeholder GuiObjectâs AbsolutePosition.
Behavior changes to existing 3D viewport APIs to ensure backwards compatibility
Click to show...
Weâve changed how several existing viewport-related APIs work on notched screens to achieve maximum backwards compatibility. Some experiences have positioned 2D GuiObjects in ScreenGuis that are meant to sync up with 3D objects in the 3D viewport. Insetting ScreenGuiâs will also require insetting 3D viewport APIs.
Every API that references the âviewportâ on a device without hardware safe area insets now uses the device safe area viewport. Each API that utilized the âinsetâ viewport (aka âScreen spaceâ) uses the Core UI safe area viewport.
Example: Camera:ViewportPointToRay()
Here is an example of how Camera:ViewportPointToRay()
works on a notched device:
On a rectangular device, Camera:ViewportPointToRay(0, 0)
returns the ray corresponding to the top left of the screen. On a notched device, Camera:ViewportPointToRay(0, 0)
returns the ray corresponding to the top left of the device safe area viewport (below, right):
Example: Camera.ViewportSize
On a rectangular display, Camera.ViewportSize
returns a Vector2 corresponding to the fullscreen width and height (below, left). On a notched display, Camera.ViewportSize
returns the size of the device safe area viewport (below, right).
Note that Camera.ViewportSize
may be smaller than what might be considered the âfull-screen sizeâ on a notched mobile phone, as it is the size of the safe area, not the full screen.
Example: AbsolutePosition Coordinates
The GuiBase2d.AbsolutePosition property as well as InputObject.Position both use Core UI Safe Inset coordinates, where the origin is at the top left of the Core UI Safe Area. On devices with safe area insets, note that this coordinate system becomes inset by the hardware safe area insets:
List of APIs that are inset by hardware safe area insets
Instance Type | Property/method using device safe inset viewport | Property/method using Core UI safe inset viewport |
---|---|---|
Camera | ViewportSize ViewportPointToRay WorldToViewportPoint |
ScreenPointToRay WorldToScreenPoint |
InputObject | Position | |
UserInputService | TouchTapInWorld GetMouseLocation |
TouchTap TouchPan TouchPinch TouchRotate TouchLongPress |
Mouse | ViewSizeX ViewSizeY |
X, Y |
GuiBase2d | AbsolutePosition | |
GuiObject | MouseMoved MouseLeave MouseEnter MouseWheelBackward MouseWheelForward TouchTap TouchPan TouchPinch TouchRotate TouchSwipe TouchLongPress |
InputBegan InputChanged InputEnded DragStopped |
GuiButton | MouseButton1Down MouseButton1Up MouseButton2Down MouseButton2Up |
Advanced: How can I get the deviceâs safe area inset sizes?
Click to show...
For more complex UI with safe-area-aware animations, it may be necessary to get the safe area sizes. Hereâs a helper function to do this. If you think this would be useful to include as a built-in function, please let us know!
type inset4 = {left: number, top: number, right: number, bottom: number}
local function getHardwareSafeAreaInsets()
local playerGui = game.Players.LocalPlayer.PlayerGui
assert(playerGui)
local fullscreenGui = playerGui:FindFirstChild("_FullscreenTestGui")
if not fullscreenGui then
fullscreenGui = Instance.new("ScreenGui")
fullscreenGui.Name = "_FullscreenTestGui"
fullscreenGui.Parent = playerGui
fullscreenGui.ScreenInsets = Enum.ScreenInsets.None
end
local deviceGui = playerGui:FindFirstChild("_DeviceTestGui")
if not deviceGui then
deviceGui = Instance.new("ScreenGui")
deviceGui.Name = "_DeviceTestGui"
deviceGui.Parent = playerGui
deviceGui.ScreenInsets = Enum.ScreenInsets.DeviceSafeInsets
end
local tlInset = deviceGui.AbsolutePosition - fullscreenGui.AbsolutePosition
local brInset = fullscreenGui.AbsolutePosition + fullscreenGui.AbsoluteSize
- (deviceGui.AbsolutePosition + deviceGui.AbsoluteSize)
local result: inset4 = {left = tlInset.X, top = tlInset.Y, right = brInset.X, bottom = brInset.Y}
return result
end
Why are we making the above changes?
Click to show...
Weâd like to explain the considerations and reasons behind this update.
A changing landscape of mobile displays
Traditionally, screen displays have been simple rectangles. However, improvements to display technology have allowed for an increasingly large variety of screen configurations. New mobile devices are likely to have notches or cutouts, and screen displays will continue to vary in size and shape going forward.
The current Roblox approach of placing the viewport in the largest unobstructed rectangle looks increasingly poor on these creative screen shapes and requires non-rectangular areas of the screen to be blacked out. Roblox will continue to expand our device support going forward, new devices and unique screen shapes will be released, and your experiences need to look amazing on every screen shape or size we support!
The core fullscreen change
The core solution is to extend the 3D viewport so that it fills the display regardless of shape. This is the standard approach today that 3D games take to ensure that there is immersive and engaging content that fills the entire display.
This change works well for 3D content. However, the GUI system and related APIâs such as Camera:WorldToScreenPoint
work in screen space. If the GUI system remains coupled to the 3D viewport, we run the risk of cutting off or covering up important UI!
The challenge of ScreenGui.IgnoreGuiInset
Most developers who have worked with GUIs will be familiar with the IgnoreGuiInset property on ScreenGuiâs. This property controls whether the Roblox Core UI inset (currently a top-edge inset of 36 pixels) should be applied to the ScreenGui. This property caused us particular difficulty because when IgnoreGuiInset is true, the developer might intend either of the following:
- The ScreenGui viewport should exactly match the 3D viewport, to align a GUI with something in 3D space. That is, the developer intends zero insets for all 4 edges of the screen.
- Ignore the top bar so that additional items may be placed alongside the Roblox menu button within the top bar area. The developer only intends there to be zero inset for the screenâs top edge, but there should be insets on the other 3 screen edges.
Previously these two meant the same thing because the Roblox menu and top bar was always positioned at the top left corner of the viewport. With notch screen support, the ambiguity of which inset(s) IgnoreGuiInset refers to means that we canât just make ScreenGuis with IgnoreGuiInset=true take up the full 3D viewport anymore because UI in these ScreenGuis could sit under a hardware notch.
Other solutions would break the legacy use cases and negatively impact some experiences. Solving with the smaller viewport (safe area) ensures the UI doesnât appear under a notch and still allows legacy experiences to take advantage of the extended screen space, so thatâs what we went for.
Known Issues
Reminder: Automatic fullscreen extension wonât extend groups of GuiObjects that each cover only part of the screen. See here for more info.
- ScreenGui.ClipToDeviceSafeArea does not clip rotated GuiObjects
- Some screen-position-related APIs donât currently support safe area insets, see the table in âBehavior changes to existing 3D viewport APIs to ensure backwards compatibilityâ.
- CanvasGroup, ViewportFrame, and VideoFrame donât currently extend their backgrounds as part of the GuiObject fullscreen extension. However, they should do this in the future
- Mac Only: resizing GuiObjects in the UI Editor doesnât work for notched devices
Fixed in v559:
- Reading
Camera.ViewportSize
in a callback toCamera:GetPropertyChangedSignal("ViewportSize")
returns a stale value until the next frame is rendered. - GuiObject BorderSizePixel and UIStroke arenât included in the size used for detecting fullscreen background expansion
- UIStroke is not affected by background expansion
Feedback
We want to hear your feedback on the notch screen support after you test the changes. Is this a welcome change? Weâd also like to hear about any issues you run into or any suggestions you may have.