1
\$\begingroup\$

I've been receiving complaints from users that my game doesn't support the 16:10 aspect ratio.

Currently I list everything in Screen.resolutions in a dropdown and allow the user to pick from that. I have since come to the understanding that the first element is not necessarily the native resolution of the monitor.

I've found the Display class but this appears to only give the native resolution, not all scaled resolutions. E.g. if the monitor is 1920x1080 then I need a list of 1600x900, 1280x720, 640x360 etc.

I thought about just multiplying by some scale factor but then I'm afraid I'll get something obscure like 885x497.8. And if I have a pre determined list of resolutions for a specific aspect ratio, how do I support obscure aspect ratios like widescreen for example.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ From your Display class link, this is a Unity question. I've added the Unity tag to more easily help other people, including prospective answerers, find and/or filter it. Please feel free to roll back this edit if if misrepresents your intention. \$\endgroup\$ Sep 13, 2020 at 9:03
  • \$\begingroup\$ What platforms do you aim to support? \$\endgroup\$
    – wondra
    Sep 13, 2020 at 15:20
  • \$\begingroup\$ Standalone windows Pc \$\endgroup\$
    – mr-matt
    Sep 13, 2020 at 19:23

1 Answer 1

1
+50
\$\begingroup\$

I've been receiving complaints from users that my game doesn't support the 16:10 aspect ratio.

You should get a more specific description of the problem. It could be that the game allows the player to select such resolutions, but the game does not look right. And that would be a different problem. You should check if your game is not stretching elements on wide screen, and that it is positioning UI elements correctly. Notice also that the perspective camera field of view is vertical, thus you may see more or less to the sides depending on the resolution.

You can try by going to the game tab on the Unity editor, on the top you will see a drop down (it says Free Aspect by default), you can change it to test your game in different aspect ratios, at the end of the list there's is a plus option to add your own. You can add an aspect ratio (select aspect ratio instead of fixed resolution) such as 16:10, or a fixed resolution such as 1680:1050.


I've found the Display class but this appears to only give the native resolution

It should give you both the "native"※ (Display.systemWidth, Display.systemHeight) and the current resolution (Display.renderingWidth , Display.renderingHeight). Screen.currentResolution is the resolution of the screen even when windowed, while (Display.renderingWidth , Display.renderingHeight) is the resolution of the game, which may not match the screen resolution when windowed.

※: I believe Unity falls back to the configured resolution on Windows when native resolution information is not available. This means that the monitor could support a higher resolutions than Unity says.

not all scaled resolutions

Screen.resolutions should give you all supported resolutions (according to Unity). You can filter that list to those that have the same aspect ratio as the native resolution (if that is what you want). To do that, iterate over Screen.resolutions, compute the aspect ratio, and compare it to the aspect ratio of the native resolution.

By the way, if all you want is the native resolution first, you can start the list with the native resolution taken from Display, followed by all the resolutions from Screen.resolutions. You compare each one with the native resolution so you can skip adding that one twice.


I thought about just multiplying by some scale factor but then I'm afraid I'll get something obscure like 885x497.8

You can ignore all not integer resolutions. In fact, if you want to use divisors of the native resolution, you want to only use common divisors of the horizontal an vertical resolutions. To find the common divisors, get the gcd (greatest common divisor) with Euclid's algorithm, get get the divisors of the gcd iterating from 1 to sqrt(gcd) and doing a simple divisibility test (eg. if (n % i == 0){/*...*/}).


Since you only intent on supporting Windows platforms, you could sidestep Unity, and use the Windows API. You can also filter by aspect ratio if that is what you want.

First you need to get the device name. To do that, call EnumDisplayDevices, to which you pass a pointer to a DISPLAY_DEVICEA structure to be populated.

Once you have your device name, you can call EnumDisplaySettings or EnumDisplaySettingsEx. You will do multiple calls, each time with a different value of iModeNum starting at 0 and incrementing, until the call fails. Each call gives you the information of a supported mode of the monitor in a DEVMODEA structure. Your resolution are the fields dmPelsWidth and dmPelsHeight.

You can change the resolution with ChangeDisplaySettings.

You can get the P/Invoke declaration from PInvoke.net. There is also a complete example on Stackoverflow: How to list available video modes using C#?. See also the article Dynamic Screen Resolution by sreejith ss nair at Code Project.

If you are going to be doing a lot of P/Invoke, you might be interested in a library that makes that easier, such as dahall/Vanara.


Perhaps the solution to your problem is simply to allow the player to type the desired resolution, and then change to that. You can write a coroutine that reads the resolution waiting for a change. If the resolution not changed after a while (say 5 seconds), we can assume it failed.

If the change succeeded, then wait for user input to confirm or revert (ESC). In particular, if you use ChangeDisplaySettings to change the resolution you may end up with a black screen, in which case the player would want to revert (traditionally by pressing ESC) to get back to a supported resolution.


One more thing, you may want to figure out the minimum playable resolution for your game and not offer anything below that (in particular if you are going with the divisors of the native resolution).

Anecdotally I can tell you that I can change the resolution of my monitor to 320:240, even though that is not listed anywhere. The minimum listed by both Windows API and Unity is 640:480. The minimum on Windows configuration is 800:600 (there are ways to modify that list, but that is another tale).

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .