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 QualityPresetOptions = new List { "Performant", "Balanced", "High Fidelity" }; private static readonly List DisplayModeOptions = new List { "Fullscreen", "Borderless Fullscreen", "Windowed" }; private static readonly List BloomQualityOptions = new List { "Off", "Performance", "Standard" }; private static readonly List VfxQualityOptions = new List { "Low", "Medium", "High" }; private readonly List _availableDisplayResolutions = new List(); private readonly List _displayResolutionOptions = new List(); 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 } /// /// 初始化后处理、Bloom 与 VFX 档位。 /// 三个标题由 Prefab 上的 Unity Localization 组件管理,因此这里保留原有标题显示,不再由脚本写入本地化 Key。 /// 在旧 Prefab 尚未布置这些控件前保留兼容分支,避免更新脚本后立即破坏既有设置页。 /// 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 } }