Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Ask Question
I'm writing functionality for a TextMeshPro screen-resolution dropdown menu for Unity that uses a
for
loop at
void Start()
to get Unity's available resolutions and populates itself with resolution options. While I can get the dropdown list to populate, each menu option is not selectable and will assume I'm just selecting the default option that is already enabled (which for example in my case would be 1920x1080, the default for most users.)
I am trying to figure out how to make the generated items selectable, especially if this isn't the correct way to do it. While the generated items are selectable in Unity's editor, they are not in aligntment upon build. (For example, selecting 1920x1080 will return 800x600 in an actual build.)
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using TMPro;
public class WindowSettings : MonoBehaviour
#region Attributes
#endregion
#region Player Pref Key Constants
private const string RESOLUTION_PREF_KEY = "resolution";
#endregion
#region Resolution
[SerializeField]
private TextMeshProUGUI resolutionText;
private Resolution[] resolutions;
private int currentResolutionIndex = 0;
public TMP_Dropdown resolutionDropdown;
private bool clickable = true;
#endregion
private void Start()
clickable = true;
resolutions = Screen.resolutions;
resolutionDropdown.ClearOptions();
int endResolutionIndex = resolutions.Length - 1;
//Makes a list of resolution options.
List<string> options = new List<string>();
for (int i = 0; i < resolutions.Length; i++)
string option = resolutions[i].width + " x " + resolutions[i].height;
options.Add(option);
Debug.Log(option + "added.");
//Ensures those resolutions options are not made with duplicates.
IEnumerable<string> distinctOptions = options.Distinct();
//Adds options to the list.
resolutionDropdown.AddOptions(distinctOptions.ToList());
currentResolutionIndex = endResolutionIndex;
resolutionDropdown.value = currentResolutionIndex;
resolutionDropdown.RefreshShownValue();
currentResolutionIndex = PlayerPrefs.GetInt(RESOLUTION_PREF_KEY, 0);
SetResolutionText(resolutions[currentResolutionIndex]);
#region Apply Resolution
private void SetAndApplyResolution(int newResolutionIndex)
currentResolutionIndex = newResolutionIndex;
ApplyCurrentResolution();
StartCoroutine(WaittoClick(1));
//To prevent click spamming.
IEnumerator WaittoClick(int seconds)
yield return new WaitForSeconds(seconds);
clickable = true;
private void ApplyCurrentResolution()
ApplyResolution(resolutions[currentResolutionIndex]);
Debug.Log("Applying " + currentResolutionIndex);
private void ApplyResolution(Resolution resolution)
SetResolutionText(resolution);
Screen.SetResolution(resolution.width, resolution.height, Screen.fullScreen);
PlayerPrefs.SetInt(RESOLUTION_PREF_KEY, currentResolutionIndex);
#endregion
#region Resolution Cycling
private void SetResolutionText(Resolution resolution) => resolutionText.text = resolution.width + " x " + resolution.height;
#endregion
//This needs to be able to find what part of the list is selected.
public void ApplyChanges(int x)
//Experimenting with bools to prevent click spamming.
if (clickable)
clickable = false;
resolutionDropdown.value = x;
resolutionDropdown.RefreshShownValue();
SetAndApplyResolution(currentResolutionIndex);
public void ToggleFullScreen(bool option)
Screen.fullScreen = option;
Debug.Log("FullScreen is " + option);
ApplyChanges() is the public function I'm currently using as the OnValueChanged(Int32) for the DropDown's functionality set with a dynamic int. This approach works for another dropdown menu I'm using which handles the language options, but not this menu. I would assume that this has something to do with the generated list since the language menu already has preset options for languages that do not need to be generated.
Are you sure this code works elsewhere? Your issue is you are not setting the variable currentResolutionIndex before the function call to SetAndApplyResolution, or you are passing in the wrong variable.
public void ApplyChanges(int x)
//Experimenting with bools to prevent click spamming.
if (clickable)
clickable = false;
resolutionDropdown.value = x;
resolutionDropdown.RefreshShownValue();
// this line is your issue so either...
// SetAndApplyResolution(currentResolutionIndex);
// solution 1 to fix above line
currentResolutionIndex = x;
SetAndApplyResolution(currentResolutionIndex);
// OR
// solution 2 to fix above line (what I believe you intended)
SetAndApplyResolution(x);
In addition to the above fix, there could potentially be another issue when setting this value from the listener of the onValueChange. Assure to select the callback function from the list of ApplyChanges from the list headed by Dynamic Int, not Static Parameters.
As it turns out I didn't realize that Unity was also listing the refresh rate of said resolution options, initially appearing to show duplicates instead.
To fix this, I added the displayed refresh rate as part of the generated options so that it makes more sense for the end user when the for loop in void Start() generated said options, as well as removed the LINQ .Distinct() method since it was no longer needed.
for (int i = 0; i < resolutions.Length; i++)
string option = resolutions[i].width + " x " + resolutions[i].height + " " + resolutions[i].refreshRate + "hz";
options.Add(option);
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.