Files
ichni_Official/Assets/Scripts/UI/Settings/GraphicsSettingsWindow.cs
SoulliesOfficial 923fc5359f 发包版本
2026-07-26 09:32:51 -04:00

248 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
using Ichni.UI;
using UnityEngine;
using UnityEngine.Serialization;
namespace Ichni.Menu
{
public class GraphicsSettingsWindow : SettingsWindow
{
private const string UiTable = "UI";
private static readonly string[] QualityPresetKeys =
{
"ui_settings_quality_performance",
"ui_settings_quality_balanced",
"ui_settings_quality_high_fidelity"
};
private static readonly string[] BloomQualityKeys =
{
"ui_settings_bloom_off",
"ui_settings_bloom_performance",
"ui_settings_bloom_standard"
};
private static readonly string[] VfxQualityKeys =
{
"ui_settings_vfx_low",
"ui_settings_vfx_medium",
"ui_settings_vfx_high"
};
private static readonly string[] DisplayModeKeys =
{
"ui_settings_display_fullscreen",
"ui_settings_display_borderless_fullscreen",
"ui_settings_display_windowed"
};
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 uiEffectsSwitch;
public Switch vSyncSwitch;
public Dropdown displayModeDropdown;
public Dropdown displayResolutionDropdown;
public override void Initialize()
{
qualityPresetDropdown.SetUpLocalized((int)gameSettings.graphicsQualityPreset, UiTable, QualityPresetKeys);
qualityPresetDropdown.updateValueAction = () =>
{
gameSettings.graphicsQualityPreset = (GraphicsQualityPreset)qualityPresetDropdown.selectedIndex;
SettingsManager.instance.ApplyGraphicSettings();
};
renderScaleModifier.SetUp(gameSettings.renderScaleLevel, 1);
renderScaleModifier.SetMinMax(0, 5);
renderScaleModifier.updateValueAction = () =>
{
gameSettings.renderScaleLevel = renderScaleModifier.GetValue();
SettingsManager.instance.ApplyGraphicSettings();
};
targetFrameModifier.SetUp(gameSettings.targetFrame, 30);
targetFrameModifier.SetMinMax(30, 120);
targetFrameModifier.updateValueAction = () =>
{
gameSettings.targetFrame = targetFrameModifier.GetValue();
SettingsManager.instance.ApplyGraphicSettings();
};
InitializePostProcessingSettings();
InitializeUiEffectsSettings();
#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 (uiEffectsSwitch != null)
{
uiEffectsSwitch.SetValue(gameSettings.enableUiEffects);
}
#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);
postProcessingSwitch.updateValueAction = () =>
{
gameSettings.enablePostProcessing = postProcessingSwitch.GetValue();
SettingsManager.instance.ApplyPostProcessingSettings();
};
bloomQualityDropdown.SetUpLocalized((int)gameSettings.bloomQuality, UiTable, BloomQualityKeys);
bloomQualityDropdown.updateValueAction = () =>
{
gameSettings.bloomQuality = (BloomQuality)bloomQualityDropdown.selectedIndex;
SettingsManager.instance.ApplyPostProcessingSettings();
};
vfxQualityDropdown.SetUpLocalized((int)gameSettings.vfxQuality, UiTable, VfxQualityKeys);
vfxQualityDropdown.updateValueAction = () =>
{
gameSettings.vfxQuality = (VfxQuality)vfxQualityDropdown.selectedIndex;
};
}
/// <summary>
/// 初始化 UI 特效开关。
/// 它独立于后处理和 VFX 质量:关闭后只停止标记为 UiExpandingContoursEffect 的 UI Image 绘制,
/// 不会影响游戏内 Note 特效、相机后处理或普通 UI。
/// </summary>
private void InitializeUiEffectsSettings()
{
// 兼容尚未补齐新控件的旧 Settings Prefab完成界面布置后必须在 Inspector 绑定该引用。
if (uiEffectsSwitch == null)
{
return;
}
uiEffectsSwitch.SetUp(gameSettings.enableUiEffects);
uiEffectsSwitch.updateValueAction = () =>
{
gameSettings.enableUiEffects = uiEffectsSwitch.GetValue();
SettingsManager.instance.ApplyUiEffectsSettings();
};
}
#if UNITY_STANDALONE || UNITY_EDITOR
private void InitializeDesktopDisplaySettings()
{
BuildDisplayResolutionOptions();
vSyncSwitch.SetUp(gameSettings.vSyncEnabled);
vSyncSwitch.updateValueAction = () =>
{
gameSettings.vSyncEnabled = vSyncSwitch.GetValue();
SettingsManager.instance.ApplyDisplaySettings();
};
displayModeDropdown.SetUpLocalized((int)gameSettings.displayMode, UiTable, DisplayModeKeys);
displayModeDropdown.updateValueAction = () =>
{
gameSettings.displayMode = (GraphicsDisplayMode)displayModeDropdown.selectedIndex;
SettingsManager.instance.ApplyDisplaySettings();
};
displayResolutionDropdown.SetUpRuntime(GetDisplayResolutionIndex(), _displayResolutionOptions);
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
}
}