问题描述
我正在为 Unity 的 TextMeshPro 屏幕分辨率下拉菜单编写功能,该菜单使用 for
处的 void Start()
循环来获取 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()
是我目前使用的公共函数,用作带有动态 int 的 DropDown 功能集的 OnValueChanged(Int32)
。这种方法适用于我正在使用的另一个处理语言选项的下拉菜单,但不适用于此菜单。我认为这与生成的列表有关,因为语言菜单已经为不需要生成的语言提供了预设选项。
解决方法
您确定此代码在其他地方有效吗?您的问题是您没有在函数调用 currentResolutionIndex
之前设置变量 SetAndApplyResolution
,或者您传入了错误的变量。
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
的侦听器设置此值时可能存在另一个问题。确保从以ApplyChanges
为首的列表中的Dynamic Int
列表中选择回调函数,而不是Static Parameters
。
事实证明,我没有意识到 Unity 还列出了上述分辨率选项的刷新率,最初似乎显示的是重复项。
为了解决这个问题,我添加了显示的刷新率作为生成选项的一部分,这样当 for
中的 void Start()
循环生成所述选项时,它对最终用户更有意义,以及删除了 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);
}