Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Black bars and wrong aspect ratio on resolution over 1080p

Discussion in 'Editor & General Support' started by prophet, Apr 11, 2024.

  1. prophet

    prophet

    Joined:
    Sep 8, 2009
    Posts:
    211
    I have failed at searching, so I am asking. What can cause black bars to show up when I try and set a resolution over 1080p when in fullscreen mode. When in windowed mode, anything over 1080p appears to be doing a 4:3 aspect ratio, or something. Just speculation. I have adjusted all canvas scaler's to 4k and also tried at 1080p before, but the behavior hasn't changed. To date my searches haven't seem to called out a specific issue where it was a resolution specific issue that caused the issue.
     

    Attached Files:

  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,528
    Maybe if your monitor only supports 1920x1080p at most?

    How do you set the resolution? Perhaps the 2560x1440 choice is simply not applying the resolution that the menu says it would. Try logging the actual dimensions you intend to apply and afterwards log what the Screen width/height values are.
     
    prophet likes this.
  3. prophet

    prophet

    Joined:
    Sep 8, 2009
    Posts:
    211
    Just to answer, the display is 4k and I run at 2560x1440 cause 4k desktop just sucks to me lol.

    But your questions led me down a path and I found the issue.

    In the editor, I would set a resolution from a dropdown and the index of my selection would output what I expected.

    What I learned and don't understand is when in the editor resolutions = Screen.resolutions; will return 26 options. When the game is built, it returned 50. But the code I am using would always only show the original 26. So all options were going to be off because the index no longer directly related to what the game thought was there. This is my code that prepares the res options. Can't remember where it came from or what I have changed over time, but here it is now. I now use the actual screen dimensions in the dropdown for setting the res.

    Code (CSharp):
    1. public void PrepareResolutions()
    2.     {
    3.         resolutions = Screen.resolutions;
    4.         resolutionDropdown.ClearOptions();
    5.  
    6.         List<string> options = new List<string>();
    7.  
    8.         int currentResolutionIndex = 0;
    9.  
    10.         for (int i = 0; i < resolutions.Length; i++)
    11.         {
    12.             string option = resolutions[i].width + " x " + resolutions[i].height;
    13.  
    14.             if (Screen.width == resolutions[i].width && Screen.height == resolutions[i].height)
    15.                 currentRes = i;
    16.             if (resolutions[i].width == 1680 && resolutions[i].height == 1050 && variableManager.GetComponent<VariableManager>().screenHeight == 0)
    17.             {
    18.                 variableManager.GetComponent<VariableManager>().screenWidth = 1680;
    19.                 variableManager.GetComponent<VariableManager>().screenHeight = 1050;
    20.             }
    21.  
    22.             if (!options.Contains(option))
    23.                 options.Add(option);
    24.  
    25.             if(i == resolutions.Length - 1)
    26.             {
    27.                 currentResolutionIndex = i;
    28.             }
    29.         }
    30.  
    31.         resolutionDropdown.AddOptions(options);
    32.         if(variableManager.GetComponent<VariableManager>().screenHeight == 0)
    33.             resolutionDropdown.value = currentResolutionIndex;
    34.         else
    35.         {
    36.             int desiredWidth = variableManager.GetComponent<VariableManager>().screenWidth;
    37.             int desiredHeight = variableManager.GetComponent<VariableManager>().screenHeight;
    38.  
    39.             for (int i = 0; i < resolutionDropdown.options.Count; i++)
    40.             {
    41.                 string optionText = resolutionDropdown.options[i].text;
    42.  
    43.                 // Split the option text into width and height strings
    44.                 string[] parts = optionText.Split('x');
    45.                 if (parts.Length == 2)
    46.                 {
    47.                     // Parse width and height from the split parts
    48.                     if (int.TryParse(parts[0], out int width) && int.TryParse(parts[1], out int height))
    49.                     {
    50.                         Resolution optionResolution = new Resolution();
    51.                         optionResolution.width = width;
    52.                         optionResolution.height = height;
    53.  
    54.                         // Check if the option resolution matches the desired width and height
    55.                         if (optionResolution.width == desiredWidth && optionResolution.height == desiredHeight)
    56.                         {
    57.                             resolutionDropdown.value = i;
    58.                             break;
    59.                         }
    60.                     }
    61.                 }
    62.             }
    63.         }
    64.         resolutionDropdown.RefreshShownValue();
     
  4. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,494
    It's the additional refresh rates available. Unity's editor isn't running in fullscreen so it's showing you the refresh rate of the desktop, but in fullscreen there are other refresh rates available which is why the number balloons. My code shows 60Hz in editor but in fullscreen builds it's 180, 170, 165, 144, 120, 60, etc. Over 200 in build vs 33 in editor.

    To eliminate the "duplicates" I use LINQ:
    Code (csharp):
    1. var resolutions = Screen.resolutions
    2.     .GroupBy(r => new { r.width, r.height }) // Sort by resolution
    3.     .Select(g => g.OrderByDescending(r => r.refreshRate).First()) // Keep the highest refresh rate
    4.     .ToArray();
     
    Last edited: Apr 12, 2024
    prophet and CodeSmile like this.
  5. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,528
    Exactly! Don‘t just filter by resolution or you may force the user into some awkward refresh rate of 30 Hz or 59 Hz.

    Stop repeating yourself all over the place! DRY principle. You are making the code unreadable (more verbose) and you force the computer to do the same thing multiple times all over again.

    Get that component once, assign it to a variable, results in more readable and more efficient code.