Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[RELEASED] Safe Area Helper for "notched" phones (iPhone X, Google Pixel 3 XL, etc.)

Discussion in 'Assets and Asset Store' started by Firemaw, Oct 15, 2018.

  1. prawn-star

    prawn-star

    Joined:
    Nov 21, 2012
    Posts:
    63
    Hi
    Does this asset allow for the little bevels at the bottom of an S9?
    I'm using Unity 2018.4.7?
     
    MilenaRocha likes this.
  2. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi @prawn-star, I don't believe it does, but I haven't tested it myself. From what I've tested on the AVD for the Google Pixel 3 XL, the safe area only covers the notch side itself and not the bevelled edges.
     
  3. prawn-star

    prawn-star

    Joined:
    Nov 21, 2012
    Posts:
    63
    Thanks for the quick response

    Do you know if there's a way to find this in native Android?. Happy to extend the UnityPlayer
     
  4. jedai747

    jedai747

    Joined:
    Oct 31, 2018
    Posts:
    77
    if i Instantiated my canvas this plugin crash my UI
     
  5. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi @jedai747 Can u provide more details about your setup? Check that you are using the correct script (not the demo one) and that you are not placing it on the canvas root but on a child panel. See the linked article for more details on correct usage.
     
  6. The_Arrival

    The_Arrival

    Joined:
    Dec 3, 2014
    Posts:
    82
    Have encountered the same issue: Autorotate is off, the whole App is in Portrait, but for a certain screen i´m forcing the App into Landscape Left.
    The issue is, that the safe are gets changed one frame before the screenorientation is finally applied. I´ve done a quickfix by also caching the screenorientation and do ApplySafeArea in cases of safeArea Changes OR Orientation changes


    Code (CSharp):
    1. if (safeArea != LastSafeArea || Screen.orientation != LastOrientation) {
    2.                 Debug.Log("Something changed. Orientation = " + Screen.orientation);
    3.                 ApplySafeArea (safeArea);
    4.             }
    5.  
    6.  

    Code (CSharp):
    1. void ApplySafeArea (Rect r)
    2.         {
    3.             LastSafeArea = r;
    4.             LastOrientation = Screen.orientation;
    5.  
    6.             // Ignore x-axis?
    7.             if (!ConformX) {
    8.                 r.x = 0;
    9.                 r.width = Screen.width;
    10.             }
    11.  
    12.             // Ignore y-axis?
    13.             if (!ConformY) {
    14.                 r.y = 0;
    15.                 r.height = Screen.height;
    16.             }
    17.  
    18.             // Convert safe area rectangle from absolute pixels to normalised anchor coordinates
    19.             Vector2 anchorMin = r.position;
    20.             Vector2 anchorMax = r.position + r.size;
    21.             anchorMin.x /= Screen.width;
    22.             anchorMin.y /= Screen.height;
    23.             anchorMax.x /= Screen.width;
    24.             anchorMax.y /= Screen.height;
    25.             Panel.anchorMin = anchorMin;
    26.             Panel.anchorMax = anchorMax;
    27.  
    28.             Debug.LogFormat ("New safe area applied to {0}: x={1}, y={2}, w={3}, h={4} on full extents w={5}, h={6}",
    29.                 name, r.x, r.y, r.width, r.height, Screen.width, Screen.height);
    30.         }
     
    xaldin-76 likes this.
  7. woodsmic

    woodsmic

    Joined:
    Jan 5, 2018
    Posts:
    12
    Hi,

    I can't get this working.. I am testing on the x-code simulator.. Should it work on there or do I need a physical device to test on?

    It just displays full screen on every x-code simulated device. On the unity editor, pressing A does seem to do something.. Just not on the actual simulator.

    Thanks, Mike.
     
  8. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi @woodsmic can you describe your component setup? The "A" button will do nothing on a target device or simulator because in this case we are using the device's safe area. If you are using the SafeArea.cs component on canvas panels as described in our article, then yes it should work in a simulator the same as a real device, assuming you are testing on a notched simulation device such as iPhone X.
     
  9. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Thanks for your contributions and testing @henriqueranj and @The_Arrival - new version 1.0.4 has integrated these fixes for having auto-rotation off and setting manual orientation via code.

    @eshan-mathur also changed: SafeAreaDemo now destroys only the MonoBehaviour instead of the whole GameObject.
     
    karmington2 likes this.
  10. drorriov

    drorriov

    Joined:
    Jun 7, 2014
    Posts:
    43
    Would just settings 'Resolution and Presentation/Render outside safe area = false' for android removes the need to your SafeArea for Pixel3XL or it can work together?
     
    Last edited: Dec 6, 2019
  11. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi @drorriov enabling that setting will simply allow your UI to draw underneath the notch. To query the safe area and make sure your UI doesn't go under it depending on the orientation, you will need to use the SafeArea code. Please see the article linked in the asset store description for more details.
     
  12. drorriov

    drorriov

    Joined:
    Jun 7, 2014
    Posts:
    43
    Thank you for your reply!
    Sorry I meant to set to 'false' (edited question).
    From what I read Setting 'renderOutsideSafeArea' false with fullscreen enabled will automatically display a black bar for the notch and render to the remaining screen.', without the need to change any UI elements. For my case for android, this is the required result.
    I did some virtual devices tests for devices with notches (the game is fixed on portrait mode), and it did place a black bar where the notch is and rendered the whole screen correctly below (using Unity 2019.2.12).
    I did not test on a physical device with a notch.
    https://issuetracker.unity3d.com/is...tch-area-is-not-rendered-on-android-9-devices (read bottom comment)

    All I am suggesting that for some developers it might be enough for Android. With iOS you do not have this option and the safe area code is necessary.
     
  13. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Ah yes that's true @drorriov you can render the notch as a black bar on Android using that setting and avoid the safe area.
     
  14. drorriov

    drorriov

    Joined:
    Jun 7, 2014
    Posts:
    43
    I wish there would be that option for iOS also, which would save for some of us a lot of headaches.
     
    Firemaw likes this.
  15. joker_yash96

    joker_yash96

    Joined:
    May 9, 2019
    Posts:
    7
    Can Someone Help me to apply it. I'm finding it difficult. and FYI I want to apply to IOS devices.

    Thanks in Advance
     
  16. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
  17. iseta

    iseta

    Joined:
    May 5, 2016
    Posts:
    48
    Hey!
    Just wanted to say that the package is very helpful and very easy to implement. I'm not sure if this is too much to ask, but do you have a list of devices where it works? It doesn't seems to be working on my Xiaomi Redmi Note 7, however, I'm using Unity 2018.3, so I'll test it in 2019 or later to check it out, thank you a lot!

    EDIT: Nevermind, I'm truly sorry but it seemed to be an issue on my end. Turns out you need to enable the "Render outside safe area" under Resolution and Presentation on Player Settings.
     
    Last edited: Mar 27, 2020
  18. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    No worries @iseta glad you got it working!
     
  19. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    188
    I have a problem with Androids - the UI just doesn't exist. I don't have the devices that have this problem, so I can't investigate what exactly is going on. I have seen reports that this is the case on Galaxy Note 10+ and Xiaomi Redmi Note 7.
     
    Last edited: Apr 5, 2020
  20. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi @unnanego can you provide any more information? Does it work on PC and other Android devices? Did you set it up the way as described in our article?
     
  21. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    188
    It's working on Galaxy Note 8 and S10 (these are the two devices that I have, but they don't have a notch) and on all iPhones and iPads.
     
  22. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    I'm sorry @unnanego but it's very hard to determine based on the lack of information. I don't have those test devices either. Given they are new devices, it might be to do with them running on the latest version of Android. Have you tried this in the Android emulator?
     
  23. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    188
    Android emulator only has pixel devices, in Unity everything works fine even in the new simulator(

    It's weird that I'm the only one with this problem, there's nothing unusual that I did - it's just an empty RectTransform with some UI buttons childed to it...
     
  24. victoranyirah

    victoranyirah

    Joined:
    Feb 5, 2017
    Posts:
    2
    Hello, SafeArea.cs is not woring when attached to my Canvas for some reason. Here's an image of me running it
     

    Attached Files:

  25. CodeBombQuinn

    CodeBombQuinn

    Joined:
    Apr 17, 2018
    Posts:
    23
    I've never attached directly to a Canvas for this. I always have 1 RectTransform object underneath the canvas that I attach SafeArea to, then I put everything inside that and anchor them properly. Hope that helps.
     
    Firemaw likes this.
  26. Marek_Bakalarczuk

    Marek_Bakalarczuk

    Joined:
    Dec 28, 2012
    Posts:
    112
    When I attach it to a RectTransform and build to device it show black screen. Second run is correct
     
  27. Boliver0482

    Boliver0482

    Joined:
    Oct 19, 2019
    Posts:
    45
    Hello, hopefully someone can give me a nudge in the right direction.

    I've tried to implement this in an existing project. Works great at run time in the unity editor, but when deployed to a device (Samsung S10+) just get a blank screen. Been exploring further and finding that the object in the scene the SafeArea script is applied to (and all its children) don't render when on the device. If I echo out the r.x, r.y, r.width, etc values to the device screen, these are correct. If I try and echo the x an y of one of the objects not being rendered I get Not a Number - so not just rendering off screen.

    If I deploy the standard demo scene provided to the same device, then that works. Same as if I create a new scene in my project to mirror what the demo scene does - it works fine. However, in my existing scenes get the behaviour described. Tried to mirror all camera and canvas settings in my scene to the demo scene, no luck with that. Deleted everything out of my scene apart from a simple UI, still no joy.

    What am I missing? Many Thanks.
     
  28. Boliver0482

    Boliver0482

    Joined:
    Oct 19, 2019
    Posts:
    45

    Hello, so after playing further, I can confirm that this actually only happens on the first scene to load and only on the device itself. Effectively the object linked to the SafeArea script and the any children it have fail to render, yet if you echo out the safe area coordinates from the SafeArea.cs script, all appears well.

    For example, I have several scenes. If I add SafeArea.cs to any scene and put that scene at location 0 in the scene hierarchy, that scene will have the issue on the device. Scenes loaded after the first scene will work fine.

    Adding a singleton to the first scene, and reloading that scene within On Start of the singleton will resolve the issue showing it only impacts the default scene. Using a coroutine to force wait on a frame On Start does nothing.

    I'm presuming this is an issue with Unity or Android and how it reports the SafeArea initially? Anyone got further with it? I'm not the most technical to know what next steps to take.

    Edit: To confirm the test scene and a very similar scene I built will work, I only get this issue in my larger project.

    Thanks,

    Bob.
     
    Last edited: May 9, 2020
  29. Venzel

    Venzel

    Joined:
    May 7, 2018
    Posts:
    19
    Hi @Firemaw!
    Thank you for this beautiful asset!
    Is it possible to get or calculate safe zone top offset value?
     
  30. rmuk

    rmuk

    Joined:
    Feb 18, 2015
    Posts:
    65
    We are seeing the same issue as Boliver0482, Marek_Bakalarcz, and unnanego. The script is causing problems on some android devices that have notches and cutouts.

    Here is the info we have gathered so far:
    - Using the notch simulator in Android's devices settings does NOT trigger this bug. It only shows on actual devices with a physical notch.
    - It happens the first time you run the app and then if you close and re-open it, it will sometimes work
    - We had reports of it not working on a Samsung Note 9, and a Note 10+.
     
  31. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    I received a report via the Asset Store page as follows:

    "I didn't have this issues in Unity 2019.1.14f, but it occurs on Unity 2019.2.21f. And it only occurs on some Samsung devices (tested on Note 10+, A71 and S20) Debug.LogFormat ("New safe area applied to {0}: x={1}, y={2}, w={3}, h={4} on full extents w={5}, h={6}", The safe area Refresh() function got called twice on these device, and the first time all these Log above yield zero (x, y, w, h) , lead to Panel.anchorMin and Panel.anchorMax become NaN. Then the screen become buggy, all the UI inside SafeArea disappear. I added a check for valid anchor to hot fix this issues"​

    Code (CSharp):
    1. bool isValid = anchorMin.x >= 0 && anchorMin.y >= 0 && anchorMax.x >= 0 && anchorMax.y >= 0;
    2.  
    3. if (isValid)
    4. {
    5.   Panel.anchorMin = anchorMin;
    6.   Panel.anchorMax = anchorMax;
    7. }
    I do not have any of the Samsung test devices in question, but I am suspecting that the cause is the Screen.width and Screen.height are returning 0 on startup (possible Unity or hardware bug), which is resulting in a divide by 0 error leading to NaN values. I will put both checks into the code for this.

    Edit: This update is now live as v1.0.6
     
    Last edited: Aug 15, 2020
  32. andreyib

    andreyib

    Joined:
    Jul 3, 2020
    Posts:
    10
    @Firemaw thank you for the tool! I faced a problem with this tool though. It works perfectly if used normally. BUT it stops working if I try to embed Unity as Android library. Unity opens full screen with no cutouts safezone changes (as if turned off). For now, the only way to have some usable alternative is to turn off "renderoutsidesafezone" and do not use this tool if Unity needs to be embeded as a library.

    Could you suggest some tweaks to make it work for such a use case? Thank you!
     
  33. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi @andreyib, you're welcome! What do you mean by using it as a library?
     
  34. andreyib

    andreyib

    Joined:
    Jul 3, 2020
    Posts:
    10
  35. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Not sure, never tried that. But all source code is provided so you're welcome to try and convert it for use that way. Otherwise if you are making a native app you could just use the native Android libraries for cutouts as that is what the Safe Area code wraps anyway.
     
  36. andreyib

    andreyib

    Joined:
    Jul 3, 2020
    Posts:
    10
    I'll let you know if I manage to make it work. For now I can confirm, it does not work for Unity as Android library. I use "RederOutsideSafeArea" option Off as the best workaround.
     
    Firemaw likes this.
  37. Mike01923

    Mike01923

    Joined:
    Jun 19, 2015
    Posts:
    190
    I've noticed that if the device's orientation changes, each time I enable a menu that hasn't seen the new orientation yet and has a notch will visibly shift the menu after it's been enabled. I'm using the enabled / disable technique for menu navigation

    Is there a solution you would recommend to have all disabled menu game objects update their safe area so the user cannot see it shift?
     
  38. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    @Mike01923 I've not noticed this before. Maybe you have very complex UI menus that take a long time to enable/load so you are noticing a one frame load. Have you set up SafeArea.cs components as per the "How To" article?

    If so, you could try turning off the panel's Alpha render for one frame until the safe area settles, then turn the Alpha back on. This could potentially be done in a script using OnEnable and a CanvasGroup component. E.g.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class SafeAreaSettle : MonoBehaviour
    6. {
    7.     CanvasGroup CvsGrp = null;
    8.  
    9.     void OnEnable ()
    10.     {
    11.         StartCoroutine (HidePanel ());
    12.     }
    13.  
    14.     IEnumerator HidePanel ()
    15.     {
    16.         if (CvsGrp == null)
    17.             CvsGrp = gameObject.AddComponent<CanvasGroup> ();
    18.  
    19.         CvsGrp.alpha = 0f;
    20.         yield return null;
    21.         CvsGrp.alpha = 1f;
    22.     }
    23. }
    Or if the OnEnable is occurring too late, then turn off the Alpha before panel activation.
     
    Mike01923 likes this.
  39. jj1991

    jj1991

    Joined:
    Jul 19, 2017
    Posts:
    18
    Hi, the script doesn't seem to work correctly on the iPhones with notch in Landscape mode in iOS 15. Anyone have a similar problem? I investigated the Screen.area function from unity and it seems to show wrong values.
     
  40. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    What values are you getting and what phone model are you using? Does it have a safe area but the size is wrong or is there no safe area at all?
     
  41. jj1991

    jj1991

    Joined:
    Jul 19, 2017
    Posts:
    18
    Hi, the Safearea in portrait is correct (top notch and bottom home-bar), when I go into landscape, the Screen.safearea returns xMin= 0 and xMax = 0 (goes over the notch). I have an iPhone 12 Pro. It works correctly in the unity device simulator. I am ofcourse using the SafeArea Helper and since it's working in the device simulator and used to work before ios15 my guess is that something changed in iOS 15 and is reporting different values to unity's Screen.safearea function. I started experimenting using my own iOS native code to get the values from apple (top: 0, bottom: 63, left: 141, right:141), so far they seem to be correct other than the one's I get from Unity's function, still have some problems with the setting up the rect in unity though.
     
    Last edited: Oct 14, 2021
  42. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Might be an issue with Unity's Screen.safeArea then, not this addon, as it just uses Unity's built-in function. I'd suggest logging it in the Unity Issue Tracker.
     
  43. FanStudioUK

    FanStudioUK

    Joined:
    Mar 31, 2013
    Posts:
    22
    Hey guys, I have some issues on iPhone 13/14 Pro Max, it seems like it's not reading the correct rotation...
    Did anyone elese experienced this problem? Is there any fix or update pending?

    Thanks!
     
  44. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi, what version of Unity are you using? You can try updating or reporting to the Issue Tracker as this plugin just wraps the internal Unity Screen.safeArea code that handles rotation.
     
  45. singlearrowgames

    singlearrowgames

    Joined:
    Oct 14, 2018
    Posts:
    5
    Hi, I'm using the same asset (Cartoon GUI Pack) as you are in the video tutorial
    for my game. I have set it to portrait and resolution as 1080x1920. The issue is when I click on the daily rewards button, the popup panel doesn't stay in the safe area. I think its because the popup is a prefab and opens outside the HomeArea object where the safe area script is attached. However when I apply the safe area script to the rewards prefab and then click on the daily rewards button, it takes up the entire screen. Can you tell me how I can fix this?
     
  46. OSahin

    OSahin

    Joined:
    Nov 1, 2018
    Posts:
    2
    Hi! I am looking for a way to have Android safe areas be centered and symmetrical like on Apple phones.

    upload_2022-12-16_13-53-47.png

    Android phones all have different safe areas where the camera side has an offset but the bottom side has no offset between the screen and the edge. Apple however applies the same offset to the bottom side as done on the camera side, leaving the safe area centered in the screen. Is there a way to modify the safe area for Android phones to achieve the same result as Apple?

    Thanks in advance for the replies.
     
  47. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi, yes please refer to the guide document linked in the Asset Store. You can either spawn the prefab under a fullscreen Canvas that already has the SafeArea script; or, if the prefab is spawned outside your base Canvas, you will need to add an invisible panel parent to the prefab that is full screen with the Safe Area script on it, as it will not work properly on a panel that has been shrunken already.
     
  48. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi, the safe area on Android is only "aware" of the side the notch is on. If you wanted to offset the opposite side to create a centering effect, you would need to write a script that manually checks the landscape orientation at runtime and adds an offset.
     
  49. blue-Assassin17

    blue-Assassin17

    Joined:
    Feb 17, 2020
    Posts:
    5
    @Firemaw Thank you for this great asset!

    Code (CSharp):
    1.                
    2.                     // Fill borders
    3.                     _topFill.anchorMin = new Vector2(0, anchorMax.y);
    4.                     _topFill.anchorMax = Vector2.one;
    5.  
    6.                     _rightFill.anchorMin = new Vector2(anchorMax.x, 0);
    7.                     _rightFill.anchorMax = Vector2.one;
    8.  
    9.                     _botttomFill.anchorMin = Vector2.zero;
    10.                     _botttomFill.anchorMax = new Vector2(1, anchorMin.y);
    11.  
    12.                     _leftFill.anchorMin = Vector2.zero;
    13.                     _leftFill.anchorMax = new Vector2(anchorMin.x, 1);

    upload_2023-1-2_11-20-14.png

    I added this to fill in any unsafe areas in my project and it has been working well so far. I've only tested it in the device simulator, but it may be useful for others looking for a similar solution. If anyone has any suggestions for better workarounds or alternative approaches, I'm open to hearing them.

    edit:

    Code (CSharp):
    1.             // Check for invalid screen startup state on some Samsung devices (see below)
    2.             if (Screen.width > 0 && Screen.height > 0)
    3.             {
    4.                 // Convert safe area rectangle from absolute pixels to normalised anchor coordinates
    5.                 Vector2 anchorMin = r.position;
    6.                 Vector2 anchorMax = r.position + r.size;
    7.                 anchorMin.x /= Screen.width;
    8.                 anchorMin.y /= Screen.height;
    9.                 anchorMax.x /= Screen.width;
    10.                 anchorMax.y /= Screen.height;
    11.  
    12.                 // Fix for some Samsung devices (e.g. Note 10+, A71, S20) where Refresh gets called twice and the first time returns NaN anchor coordinates
    13.                 // See https://forum.unity.com/threads/569236/page-2#post-6199352
    14.                 if (anchorMin.x >= 0 && anchorMin.y >= 0 && anchorMax.x >= 0 && anchorMax.y >= 0)
    15.                 {
    16.                     Panel.anchorMin = anchorMin;
    17.                     Panel.anchorMax = anchorMax;
    18.  
    19.                     // Fill borders
    20.                     _topFill.anchorMin = new Vector2(0, anchorMax.y);
    21.                     _topFill.anchorMax = Vector2.one;
    22.  
    23.                     _rightFill.anchorMin = new Vector2(anchorMax.x, 0);
    24.                     _rightFill.anchorMax = Vector2.one;
    25.  
    26.                     _botttomFill.anchorMin = Vector2.zero;
    27.                     _botttomFill.anchorMax = new Vector2(1, anchorMin.y);
    28.  
    29.                     _leftFill.anchorMin = Vector2.zero;
    30.                     _leftFill.anchorMax = new Vector2(anchorMin.x, 1);
    31.  
    32.                 }
    33.             }
    34.  
     
    Last edited: Jan 2, 2023
  50. Firemaw

    Firemaw

    Joined:
    Aug 24, 2015
    Posts:
    56
    Hi @blue-Assassin17 you can also turn off the ConformX and ConformY options to ignore screen safe areas on the horizontal and vertical axes. See the linked blog post on the asset store description for usage instructions. Thanks!