Search Unity

Bug Android Phones Returning Screen.safeArea Incorrectly

Discussion in 'Android' started by mace44, Feb 4, 2021.

  1. mace44

    mace44

    Joined:
    Feb 8, 2017
    Posts:
    15
    On any Android mobile phones I tried in the Device Simulator, the Safe Area option displays the safe area in green correctly.

    upload_2021-2-3_23-17-45.png
    (Samsung Galaxy S10e)

    However, when I attempt to run: Screen.safeArea.y Screen.safeArea.yMax, returns an incorrect value for Screen.safeArea.y: 0; But according to the Device Simulator, should be > 0

    upload_2021-2-3_23-21-52.png

    When switch the Device Simulator to iPhone XR, the Screen.safeArea.y returns 68 which looks to be correct.

    Not sure what's going on here.

    Using Unity 2020.2.2f1
     
  2. rjonaitis

    rjonaitis

    Unity Technologies

    Joined:
    Jan 5, 2017
    Posts:
    115
    Have you enabled "Render outside safe area" in the android player settings?
     
  3. mace44

    mace44

    Joined:
    Feb 8, 2017
    Posts:
    15
    Yes. It was checked.
    upload_2021-2-4_8-19-7.png

    After un-checking it, it does render below the notch but the Screen.safeScreen.y is still 0. I'm guess if I wanted to put something in the notch area, I would need to go positive in the Y which is different on iOS where the top of the notch is 0 and the Screen.safeScreen.y is 68 (or so). I wish it was consistent across platforms.
     
  4. rjonaitis

    rjonaitis

    Unity Technologies

    Joined:
    Jan 5, 2017
    Posts:
    115
    It is consistent. Unchecking the 'Render outside safe area' makes the screen space around notch unusable, so the whole app windows is moved down, making the 0 coordinate at the bottom of the notch.

    Anyway, leave the 'Render outside safe area' enabled, and see if the safe area coordinates changes after rotating device orientation.
     
  5. Toprakete

    Toprakete

    Joined:
    Oct 25, 2012
    Posts:
    2
    I am facing the same issue:
    I have a couple of Android devices with the front-facing camera within the screen area (Xiaomi Mi 10T Pro 5G, Google Pixel 5, Xiaomi Mi A3, Samsung Galaxy S10).
    On all of these devices Screen.safeArea returns wrong rects in portrait rotation and in portrait upside down rotation.
    The size of the safeArea rect (width and height) seems to be right, but the position (x,y or xMin,yMin) is not. min Position is alwas (0,0) in portrait rotation. In portrait upside down rotation the rect is at the bottom most position. I tried to illustrate this.
    blue: actual safe areo of device
    red: rect returned by Screen.safeArea

    safe_area.png


    In landscape left and landscape right orientation everything works as expected (blue and red area overlap completely).
    I'm using Unity 2020.3.7f1. and "Render outside safe area" is enabled.
     
  6. rjonaitis

    rjonaitis

    Unity Technologies

    Joined:
    Jan 5, 2017
    Posts:
    115
    Screen.safeArea is using screen space coordinates system (origin (0,0) is at left-bottom corner), so you are getting correct numbers.
    I suspect you are using those numbers in UICanvas (which uses UI space coordinates system, origin (0,0) is at left-top corner), so you get things upside down.
     
    gpom, gongon123 and Toprakete like this.
  7. Toprakete

    Toprakete

    Joined:
    Oct 25, 2012
    Posts:
    2
    Yes, you are absolutely right, that was my mistake. Thanks!
     
  8. Liason23

    Liason23

    Joined:
    Oct 8, 2020
    Posts:
    3
    I write a code Screen Safe area its looks pretty fine in Device Simulation but It's not running in build what should I do code files is attached below ...
     

    Attached Files:

  9. LE-Peter

    LE-Peter

    Joined:
    Sep 15, 2020
    Posts:
    44
    This is inconsistent..?

    On Android:
    Render outside safe area enabled -> Screen.safeArea.y = 0
    Render outside safe area disabled -> Screen.safeArea.y = 0

    On iOS:
    No render outside safe area option -> Screen.safeArea.y = 68

    So on Android the Screen.safeArea does nothing useful? I want to render the entire app outside the safe area, but I need to know the safe area to move elements away from any notches/ cameras that will get in the way.

    I would expect, that when rendering outside safe area is enabled, that Screen.safeArea.y would return a value greater than 0... and when rendering outside safe area is disabled, Screen.safeArea.y = 0.
     
    Last edited: Nov 24, 2021
    kendallstarr likes this.
  10. rjonaitis

    rjonaitis

    Unity Technologies

    Joined:
    Jan 5, 2017
    Posts:
    115
    That is how it works. Also the values change depending on screen orientation.
    There is an exception, some Android devices that are running Android OS version <9 and have a notch (there are only couple of models running android 8.1), do not provide API to get the safe area size, so in those cases 'Screen.safeArea' will just return fullscreen rectangle.
     
  11. LE-Peter

    LE-Peter

    Joined:
    Sep 15, 2020
    Posts:
    44
    Samsung Galaxy S10*, on Android 11 always returns 0 for Screen.safeArea.y.
    So do all of the Android devices in Device Simulator (I'm using v2.2.4).

    Rotating the Device Simulator to landscape gives an accurate value for Screen.safeArea.x, going back to portrait and Screen.safeArea.y is always 0.



    * I'm only working with 1 device while I dev. Our QA reported the issue on all their test devices too.
     
  12. rjonaitis

    rjonaitis

    Unity Technologies

    Joined:
    Jan 5, 2017
    Posts:
    115
    `Screen.safeArea is using screen space coordinates system (origin (0,0) is at left-bottom corner)`, so .y is going to be the same (in portrait) with or without notch, because only the height of safeArea will be different.

    in your example on iOS device .y is not the notch size, it's the size of the "on screen home button".
     
  13. LE-Peter

    LE-Peter

    Joined:
    Sep 15, 2020
    Posts:
    44
    So, how do I get the safe area from the top..? The bit that everyone is going to want from the API..

    upload_2021-11-24_16-15-52.png
     
  14. rjonaitis

    rjonaitis

    Unity Technologies

    Joined:
    Jan 5, 2017
    Posts:
    115
    You can do the math in many ways, one of them is "offsetFromTop = Screen.height - (Screen.safeArea.y + Screen.safeArea.height)"
     
    NEXBRAIN likes this.
  15. LE-Peter

    LE-Peter

    Joined:
    Sep 15, 2020
    Posts:
    44
    Don't you think this should be part of the safeArea API?
    So that it's easily accessible and that the same code isn't being re-written by every dev and every project that needs it and expects this to be part of the safeArea API?

    Sure, the bottom bit is good to have, but it is no where near as important as the notch areas at the top of the screens...
     
  16. rjonaitis

    rjonaitis

    Unity Technologies

    Joined:
    Jan 5, 2017
    Posts:
    115
    The idea of Screen.safeArea is to return a rectangle which is guaranteed to have non obscured display, so you just place your important/must see things within it and that's it.

    In your case, you want to intentionally place things outside safeArea around the notch, then it's up to you to decide where and how to place them, that includes calculating those positions and sizes yourself, because it's not enough just to know the offset from top, you also need to know where the notch is, it might be left/center/right/narrow/wide, it needs a custom solution which means custom math and using https://docs.unity3d.com/ScriptReference/Screen-cutouts.html
     
    nbzc likes this.
  17. LE-Peter

    LE-Peter

    Joined:
    Sep 15, 2020
    Posts:
    44
    Nope. I want to move UI down into the safe area, and expected the safeArea API to actually give me easy access to the top of the rect so I know how far to move it ...

    Screen.safeArea.y gives a value for offset from the bottom, for the 2 phones that need it.. why not have the same thing for the top? Where a lot more phones actually have something that would get in the way.

    Additionally, thanks for the docs link.. but it's void of any actual useful information. Needs updating with information and an example.
     
  18. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,734
    Can’t you do Screen.height - (Screen.safeArea.y + Screen.safeArea.height) ?
     
  19. LE-Peter

    LE-Peter

    Joined:
    Sep 15, 2020
    Posts:
    44
    Of coruse I can..

    My point is, that the safeArea API should include this already. Why wouldn't it? It's half an API as is atm..
     
  20. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,734
    The API returns a rect which has x, y, width, height. From this perspective it is complete.

    You might argue that returning a rect is a stupid idea, and I might agree, because rects kinda suck, but also... eh.

    Converting it to any other format is trivial.

    For example in our project we do this:

    Code (CSharp):
    1. float safex = Screen.safeArea.x / (float)Screen.width;
    2. safex = math.clamp(safex, 0f, 0.2f);
    3.  
    4. float safey = Screen.safeArea.y / (float)Screen.height;
    5. safey = math.clamp(safey, 0f, 0.2f);
    6.  
    7. float safez = (Screen.safeArea.x + Screen.safeArea.width)  / (float)Screen.width;
    8. safez = math.clamp(safez, 1f - 0.2f, 1f);
    9.  
    10. float safew = (Screen.safeArea.y + Screen.safeArea.height) / (float)Screen.height;
    11. safew = math.clamp(safew, 1f - 0.2f, 1f);
    12.  
    13. normalSafeArea = new float4(safex, safey, safez, safew);
    And we just use that.
     
  21. LE-Peter

    LE-Peter

    Joined:
    Sep 15, 2020
    Posts:
    44
    I think returning ONLY the rect is stupid.

    You've written that code for your project.. and so, every other dev using safeArea will need to do the same thing. I find it pretty poor that this kind of thing isn't just part of the API so that we're not all writing the same code over and over, in all our projects.

    If this was an asset on the store, I wouldn't buy it as is.
     
  22. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,734
    I wanted mine to be normalized because I wanted to use them with Camera.ViewportToWorldPoint. Maybe you want something different, maybe someone else wants something else. Maybe someone actually wants a Rect.

    Listen, I'm all for yelling at Unity for doing a poor job, I'm actually starting (?) to get notorious about it at this point, but if most of my Unity problems could be solved with 9 lines of code, I would be really happy with Unity.
     
    nbzc likes this.
  23. qtc_Dena

    qtc_Dena

    Joined:
    Aug 12, 2022
    Posts:
    5
    May I ask how can I get the safeArea in any orientation? The Screen.safeArea returns as full screen when the device is not landscape left. But that is not what I expected. I test in both real android phone and Unity Editor Simulator.
     
  24. kickasslin

    kickasslin

    Joined:
    May 31, 2023
    Posts:
    3
    upload_2023-10-8_15-15-32.png
    Why Screen.width is less than Screen.safeArea.width and Screen.height is less than Screen.safeArea.height?
    I expect with and height falls into Screen resolution
    and here is my code
    Code (CSharp):
    1. GUILayout.Label("Safe area :"+Screen.safeArea);
    2.  GUILayout.Label("ScreenWidth and Height :"+Screen.width+"   "+Screen.height);
     
  25. kickasslin

    kickasslin

    Joined:
    May 31, 2023
    Posts:
    3
    upload_2023-10-8_15-22-22.png
    and why safeArea.x,and y are both o ,You said the value starts from bottom-left,but even I rotate the device ,I got the values both zeros