- Home /
Mismatch refreshrate/hz between currentResolution and possible resolution?
Hi
I'm building a settings UI for my game and want a dropdown with possible resolutions and of cause want the current resolution be selected by default - pretty standard.
However, turns out it's super complicated in Unity or I'm doing something wrong - hope for the latter :)
My problem is that the current resolutions isn't selected and I also just now found out why. There is a mismatch between the refreshrate in the listed possible resolution and the currentResotution.
private void SetupResolutionDropDown()
{
ResolutionDropDown.ClearOptions();
var resolutionOptions = new List<TMP_Dropdown.OptionData>();
for (int i = 0; i < Screen.resolutions.Length; i++)
{
var resolutionAsText = $"{Screen.resolutions[i].width}x{Screen.resolutions[i].height} @ {Screen.resolutions[i].refreshRate}Hz";
resolutionOptions.Add(new TMP_Dropdown.OptionData(resolutionAsText));
Debug.Log($"Adding Resolution - '{resolutionAsText}'");
}
ResolutionDropDown.options = resolutionOptions;
ResolutionDropDown.onValueChanged.AddListener((index) =>
{
_selectedResolutionIndex = index;
});
RefreshResolutionDropdown();
}
private void RefreshResolutionDropdown()
{
var currentIndex = GetCurrentResolutionIndex();
ResolutionDropDown.value = currentIndex;
}
private int GetCurrentResolutionIndex()
{
for (int i = 0; i < Screen.resolutions.Length; i++)
{
if (Screen.resolutions[i].width == Screen.currentResolution.width &&
Screen.resolutions[i].height == Screen.currentResolution.height &&
Screen.resolutions[i].refreshRate == Screen.currentResolution.refreshRate)
return i;
}
Debug.LogError($"Unable to find CurrentResolutionIndex for resolution, '{Screen.currentResolution}'");
return -1;
}
This works fine in the Unity Editor, but in a build it doesn't. So I looked in the Player.log file to see the above Debug.Logs.
Here I see in the list of possible solutions:
Adding Resolution - '2560x1440 @ 143Hz'
However, the log for the Screen.currentResolution shows me:
Unable to find CurrentResolutionIndex for resolution, '2560 x 1440 @ 144Hz'
So, it's pretty obvious to see why it doesn't find a match, as one have 143Hz and the other have 144Hz.
So, why is that and how can I compensate or am I doing something wrong or?
I know I might be able to just skip the refreshrate from the find logic, however, it will reselect a wrong resolution and I don't want that.
Thanks in advance.
Answer by svgUnityAssets · May 11, 2020 at 08:21 AM
In all fullscreen modes other than "exclusive" the refresh rate will be that of whatever refresh rate your desktop runs. Because as the FullScreenMode enumeration's names imply, anything but "exclusive" is running in a window even if you can't see the window title and borders.
It's only exclusive fullscreen mode that allows setting the refresh rate manually (unless overridden by driver settings).
Hence: try again with FullScreenMode set to ExclusiveFullScreen in Player Settings.
Answer by ozonex · Sep 01, 2020 at 06:37 AM
@Laumania Did you found any solution? I have exactly same issue and Im unable to find how to deal with refresh rates. Everybody ends up with just using FullScreenWindow instead of ExclusiveFullScreen because you don't need to care about refresh rate. But exclusive mode gives more performance and more control so its strange that nobody found a solution.
I also think that it might not be the issue of only Unity itself, because when i enter to supported modes in Windows screen settings i also see this strange behavior.
In Windows for 2560x1440 i have supported refresh rates: 59hz, 60hz, 75hz, 100hz
Selecting 59 and 60 gives the same refresh rate 59hz. Selecting 75hz gives 74hz and 100hz is 99hz.
In unity for that resolution Screen.resolutions gives me 59hz, 74hz and 99hz. So somehow it finds out that all these options will end up and it seems correct apart from these strange values.
But then again when i use any of them in Screen.SetResolution() like that:
Screen.SetResolution(res.width, res.height, FullScreenMode.ExclusiveFullScreen, res.refreshRate);
Screen.currentResolution returns 60hz, 75hz and 100hz.
I can manually search for pairs like 59hz and 60hz and if not exactly the same is found then try to use other one, but this will be an ugly workaround.
Sadly no, I haven't found a solution. However, I must admit I haven't looked more into it since, as I have focused on other stuff in my game. It is something I'll get back to, as it annoys me :D
After whole day I think i managed to get it working using that workaround.
static bool CompareRefreshRates(int a, int b)
{
return GetRoundedRefreshRate(a) == GetRoundedRefreshRate(b);
}
static int GetRoundedRefreshRate(int refreshRate)
{
switch (refreshRate) // Hard coded pairs
{
case 23:
return 24;
case 29:
return 30;
case 47:
return 48;
case 59:
return 60;
case 75:
case 74:
return 75;
case 164:
case 165:
return 165;
}
if (refreshRate > 60) // 100, 120, 144 etc.
{
if (refreshRate % 2 > 0) // Always its rounded to smaller odd number
{
return refreshRate + 1;
}
}
return refreshRate;
}
This is used only when game is in ExclusiveFullScreen mode. I needed to replace "Fullscreen" toogle in the game with switch Window/Borderless/Exclusive.
In window resolution list is blocked and it displays Screen.width and Screen.height.
In Borderless i filter out and hide refreshRate so users can only select widht/height.
Only in Exclusive mode i display all refresh rates. When creating list I marge all similar refresh rates using CompareRefreshRates() and displays it on UI list as one converted by GetRoundedRefreshRate() so it looks correct for users.
To find what resolution is correctly selected i first try to find resolution with same refreshRate. If it fails then it search refreshRate using CompareRefreshRates(). When it also fails then use highest possible. I can imagine many issues with that solution, thats why by default our game starts in Borderless, but Exclusive mode works fine on all of our devices that we tested (PC, laptops, TVs)
Nice, I'll take a look at this once I get back to it in my game.
However, I know why you did it, but I really don't like this hardcoded adjustment of the refreshrate - but it's also really odd that we get these wierd numbers :S
Answer by nypehb · Apr 06, 2021 at 11:25 AM
You can add condition like: resolutions[i].refreshRate == Screen.currentResolution.refreshRate || resolutions[i].refreshRate + 1 == Screen.currentResolution.refreshRate).
So, if you compares 59Hz and 60Hz or any numbers with difference of only 1 number - they will be equal to each other and a condition will work.
It's not very convenient, but It works and doesn't take much space.
It should work too. Code is complex because i used it to debug different devices and drivers.
Answer by PortgateStudios · Apr 24, 2021 at 07:43 PM
Holy... I've been searching for the cause of the issue for hours... And it turns out this was the problem.
Your answer
Follow this Question
Related Questions
Can i set my work to be played at a single screen resolution only to prevent scaling issues? 0 Answers
Camera Fit Issues on 10 inch tablet 0 Answers
Putting object at the edge of the screen irrespective of resolution 2 Answers
How do I negate the zoom caused by changing resolution and screen orientation? 1 Answer