Black bars and wrong aspect ratio on resolution over 1080p

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.


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.

1 Like

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.

public void PrepareResolutions()
    {
        resolutions = Screen.resolutions;
        resolutionDropdown.ClearOptions();

        List<string> options = new List<string>();

        int currentResolutionIndex = 0;

        for (int i = 0; i < resolutions.Length; i++)
        {
            string option = resolutions[i].width + " x " + resolutions[i].height;

            if (Screen.width == resolutions[i].width && Screen.height == resolutions[i].height)
                currentRes = i;
            if (resolutions[i].width == 1680 && resolutions[i].height == 1050 && variableManager.GetComponent<VariableManager>().screenHeight == 0)
            {
                variableManager.GetComponent<VariableManager>().screenWidth = 1680;
                variableManager.GetComponent<VariableManager>().screenHeight = 1050;
            }

            if (!options.Contains(option))
                options.Add(option);

            if(i == resolutions.Length - 1)
            {
                currentResolutionIndex = i;
            }
        }

        resolutionDropdown.AddOptions(options);
        if(variableManager.GetComponent<VariableManager>().screenHeight == 0)
            resolutionDropdown.value = currentResolutionIndex;
        else
        {
            int desiredWidth = variableManager.GetComponent<VariableManager>().screenWidth;
            int desiredHeight = variableManager.GetComponent<VariableManager>().screenHeight;

            for (int i = 0; i < resolutionDropdown.options.Count; i++)
            {
                string optionText = resolutionDropdown.options[i].text;

                // Split the option text into width and height strings
                string[] parts = optionText.Split('x');
                if (parts.Length == 2)
                {
                    // Parse width and height from the split parts
                    if (int.TryParse(parts[0], out int width) && int.TryParse(parts[1], out int height))
                    {
                        Resolution optionResolution = new Resolution();
                        optionResolution.width = width;
                        optionResolution.height = height;

                        // Check if the option resolution matches the desired width and height
                        if (optionResolution.width == desiredWidth && optionResolution.height == desiredHeight)
                        {
                            resolutionDropdown.value = i;
                            break;
                        }
                    }
                }
            }
        }
        resolutionDropdown.RefreshShownValue();

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:

var resolutions = Screen.resolutions
    .GroupBy(r => new { r.width, r.height }) // Sort by resolution
    .Select(g => g.OrderByDescending(r => r.refreshRate).First()) // Keep the highest refresh rate
    .ToArray();
2 Likes

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.