如何通过生成的下拉选项列表从Unity中的下拉UI元素中获得选定的分辨率



我正在为Unity的TextMeshPro屏幕分辨率下拉菜单编写功能,该菜单使用void Start()处的for循环来获取Unity的可用分辨率,并用分辨率选项填充自身。虽然我可以填充下拉列表,但每个菜单选项都是不可选择的,并且会假设我只是选择了已经启用的默认选项(例如,在我的情况下,它将是1920x1080,这是大多数用户的默认选项。(

我正试图弄清楚如何使生成的项目可选择,尤其是如果这不是正确的方法。虽然生成的项目在Unity的编辑器中是可选择的,但它们在构建时并不对齐。(例如,选择1920x1080将在实际构建中返回800x600。(

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()是我目前使用的公共函数,作为DropDown的动态int功能集的OnValueChanged(Int32)。这种方法适用于我正在使用的另一个下拉菜单,它处理语言选项,但不适用于此菜单。我认为这与生成的列表有关,因为语言菜单已经为不需要生成的语言提供了预设选项。

您确定此代码在其他地方有效吗?您的问题是在函数调用SetAndApplyResolution之前没有设置变量currentResolutionIndex,或者传入了错误的变量。

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);
}
}

除了上述修复程序外,当从onValueChange的侦听器设置此值时,还可能存在另一个问题。确保从以Dynamic Int而非Static Parameters为首的列表中的ApplyChanges列表中选择回调函数。

事实证明,我没有意识到Unity也列出了所述分辨率选项的刷新率,最初显示的是重复的。

为了解决这个问题,我添加了显示的刷新率作为生成选项的一部分,以便在void Start()中的for循环生成所述选项时对最终用户更有意义,并删除了LINQ.Distinct()方法,因为它不再需要。

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

最新更新