Files
ichni_Official/Assets/Scripts/UI/Settings/GraphicsSettingsWindow.cs
TRADER_FOER 02617c1385 着重优化调度
Signed-off-by: TRADER_FOER <lhf190@outlook.com>
2026-07-21 09:58:21 +08:00

221 lines
8.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Ichni.UI;
using UnityEngine;
using UnityEngine.Serialization;
namespace Ichni.Menu
{
public class GraphicsSettingsWindow : SettingsWindow
{
private static readonly List<string> QualityPresetOptions = new List<string>
{
"Performant",
"Balanced",
"High Fidelity"
};
private static readonly List<string> DisplayModeOptions = new List<string>
{
"Fullscreen",
"Borderless Fullscreen",
"Windowed"
};
private static readonly List<string> BloomQualityOptions = new List<string>
{
"Off",
"Performance",
"Standard"
};
private static readonly List<string> VfxQualityOptions = new List<string>
{
"Low",
"Medium",
"High"
};
private readonly List<Vector2Int> _availableDisplayResolutions = new List<Vector2Int>();
private readonly List<string> _displayResolutionOptions = new List<string>();
public Dropdown qualityPresetDropdown;
[FormerlySerializedAs("resolutionLevelModifier")]
public ValueModifier renderScaleModifier;
public ValueModifier targetFrameModifier;
public Switch postProcessingSwitch;
public Dropdown bloomQualityDropdown;
public Dropdown vfxQualityDropdown;
public Switch vSyncSwitch;
public Dropdown displayModeDropdown;
public Dropdown displayResolutionDropdown;
public override void Initialize()
{
qualityPresetDropdown.SetUp((int)gameSettings.graphicsQualityPreset, QualityPresetOptions,
"Menu UI/Settings_Quality_Preset");
qualityPresetDropdown.updateValueAction = () =>
{
gameSettings.graphicsQualityPreset = (GraphicsQualityPreset)qualityPresetDropdown.selectedIndex;
SettingsManager.instance.ApplyGraphicSettings();
};
renderScaleModifier.SetUp(gameSettings.renderScaleLevel, 1, "Menu UI/Settings_Render_Scale");
renderScaleModifier.SetMinMax(0, 5);
renderScaleModifier.updateValueAction = () =>
{
gameSettings.renderScaleLevel = renderScaleModifier.GetValue();
SettingsManager.instance.ApplyGraphicSettings();
};
targetFrameModifier.SetUp(gameSettings.targetFrame, 30, "Menu UI/Settings_Target_Frame");
targetFrameModifier.SetMinMax(30, 120);
targetFrameModifier.updateValueAction = () =>
{
gameSettings.targetFrame = targetFrameModifier.GetValue();
SettingsManager.instance.ApplyGraphicSettings();
};
InitializePostProcessingSettings();
#if UNITY_STANDALONE || UNITY_EDITOR
InitializeDesktopDisplaySettings();
#else
vSyncSwitch.gameObject.SetActive(false);
displayModeDropdown.gameObject.SetActive(false);
displayResolutionDropdown.gameObject.SetActive(false);
#endif
}
public override void SetValuesFromSettings()
{
qualityPresetDropdown.SetValue((int)gameSettings.graphicsQualityPreset);
renderScaleModifier.SetValue(gameSettings.renderScaleLevel);
targetFrameModifier.SetValue(gameSettings.targetFrame);
if (postProcessingSwitch != null)
{
postProcessingSwitch.SetValue(gameSettings.enablePostProcessing);
bloomQualityDropdown.SetValue((int)gameSettings.bloomQuality);
vfxQualityDropdown.SetValue((int)gameSettings.vfxQuality);
}
#if UNITY_STANDALONE || UNITY_EDITOR
vSyncSwitch.SetValue(gameSettings.vSyncEnabled);
displayModeDropdown.SetValue((int)gameSettings.displayMode);
displayResolutionDropdown.SetValue(GetDisplayResolutionIndex());
#endif
}
/// <summary>
/// 初始化后处理、Bloom 与 VFX 档位。
/// 三个标题由 Prefab 上的 Unity Localization 组件管理,因此这里保留原有标题显示,不再由脚本写入本地化 Key。
/// 在旧 Prefab 尚未布置这些控件前保留兼容分支,避免更新脚本后立即破坏既有设置页。
/// </summary>
private void InitializePostProcessingSettings()
{
if (postProcessingSwitch == null)
{
return;
}
postProcessingSwitch.SetUp(gameSettings.enablePostProcessing, preservePrefabTitle: true);
postProcessingSwitch.updateValueAction = () =>
{
gameSettings.enablePostProcessing = postProcessingSwitch.GetValue();
SettingsManager.instance.ApplyPostProcessingSettings();
};
bloomQualityDropdown.SetUp((int)gameSettings.bloomQuality, BloomQualityOptions, preservePrefabTitle: true);
bloomQualityDropdown.updateValueAction = () =>
{
gameSettings.bloomQuality = (BloomQuality)bloomQualityDropdown.selectedIndex;
SettingsManager.instance.ApplyPostProcessingSettings();
};
vfxQualityDropdown.SetUp((int)gameSettings.vfxQuality, VfxQualityOptions, preservePrefabTitle: true);
vfxQualityDropdown.updateValueAction = () =>
{
gameSettings.vfxQuality = (VfxQuality)vfxQualityDropdown.selectedIndex;
};
}
#if UNITY_STANDALONE || UNITY_EDITOR
private void InitializeDesktopDisplaySettings()
{
BuildDisplayResolutionOptions();
vSyncSwitch.SetUp(gameSettings.vSyncEnabled, "Menu UI/Settings_VSync");
vSyncSwitch.updateValueAction = () =>
{
gameSettings.vSyncEnabled = vSyncSwitch.GetValue();
SettingsManager.instance.ApplyDisplaySettings();
};
displayModeDropdown.SetUp((int)gameSettings.displayMode, DisplayModeOptions,
"Menu UI/Settings_Display_Mode");
displayModeDropdown.updateValueAction = () =>
{
gameSettings.displayMode = (GraphicsDisplayMode)displayModeDropdown.selectedIndex;
SettingsManager.instance.ApplyDisplaySettings();
};
displayResolutionDropdown.SetUp(GetDisplayResolutionIndex(), _displayResolutionOptions,
"Menu UI/Settings_Display_Resolution");
displayResolutionDropdown.updateValueAction = () =>
{
Vector2Int resolution = _availableDisplayResolutions[displayResolutionDropdown.selectedIndex];
gameSettings.displayResolutionWidth = resolution.x;
gameSettings.displayResolutionHeight = resolution.y;
SettingsManager.instance.ApplyDisplaySettings();
};
}
private void BuildDisplayResolutionOptions()
{
_availableDisplayResolutions.Clear();
_displayResolutionOptions.Clear();
AddDisplayResolution(Screen.width, Screen.height);
foreach (Resolution resolution in Screen.resolutions)
{
AddDisplayResolution(resolution.width, resolution.height);
}
_availableDisplayResolutions.Sort((left, right) =>
{
int pixelCountComparison = (left.x * left.y).CompareTo(right.x * right.y);
return pixelCountComparison != 0 ? pixelCountComparison : left.x.CompareTo(right.x);
});
foreach (Vector2Int resolution in _availableDisplayResolutions)
{
_displayResolutionOptions.Add($"{resolution.x} x {resolution.y}");
}
}
private void AddDisplayResolution(int width, int height)
{
Vector2Int resolution = new Vector2Int(width, height);
if (!_availableDisplayResolutions.Contains(resolution))
{
_availableDisplayResolutions.Add(resolution);
}
}
private int GetDisplayResolutionIndex()
{
Vector2Int savedResolution = new Vector2Int(gameSettings.displayResolutionWidth,
gameSettings.displayResolutionHeight);
int savedResolutionIndex = _availableDisplayResolutions.IndexOf(savedResolution);
if (savedResolutionIndex >= 0)
{
return savedResolutionIndex;
}
return _availableDisplayResolutions.IndexOf(new Vector2Int(Screen.width, Screen.height));
}
#endif
}
}