2025-08-11 14:04:06 -04:00
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using Ichni.UI;
|
|
|
|
|
using UnityEngine;
|
2026-07-19 16:44:58 -04:00
|
|
|
using UnityEngine.Serialization;
|
2025-08-11 14:04:06 -04:00
|
|
|
|
|
|
|
|
namespace Ichni.Menu
|
|
|
|
|
{
|
|
|
|
|
public class GraphicsSettingsWindow : SettingsWindow
|
|
|
|
|
{
|
2026-07-25 13:27:53 -04:00
|
|
|
private const string UiTable = "UI";
|
|
|
|
|
|
|
|
|
|
private static readonly string[] QualityPresetKeys =
|
2026-07-19 16:44:58 -04:00
|
|
|
{
|
2026-07-25 13:27:53 -04:00
|
|
|
"ui_settings_quality_performance",
|
|
|
|
|
"ui_settings_quality_balanced",
|
|
|
|
|
"ui_settings_quality_high_fidelity"
|
2026-07-19 16:44:58 -04:00
|
|
|
};
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
private static readonly string[] BloomQualityKeys =
|
2026-07-19 16:44:58 -04:00
|
|
|
{
|
2026-07-25 13:27:53 -04:00
|
|
|
"ui_settings_bloom_off",
|
|
|
|
|
"ui_settings_bloom_performance",
|
|
|
|
|
"ui_settings_bloom_standard"
|
2026-07-19 16:44:58 -04:00
|
|
|
};
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
private static readonly string[] VfxQualityKeys =
|
2026-07-19 16:44:58 -04:00
|
|
|
{
|
2026-07-25 13:27:53 -04:00
|
|
|
"ui_settings_vfx_low",
|
|
|
|
|
"ui_settings_vfx_medium",
|
|
|
|
|
"ui_settings_vfx_high"
|
2026-07-19 16:44:58 -04:00
|
|
|
};
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
private static readonly string[] DisplayModeKeys =
|
2026-07-19 16:44:58 -04:00
|
|
|
{
|
2026-07-25 13:27:53 -04:00
|
|
|
"ui_settings_display_fullscreen",
|
|
|
|
|
"ui_settings_display_borderless_fullscreen",
|
|
|
|
|
"ui_settings_display_windowed"
|
2026-07-19 16:44:58 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private readonly List<Vector2Int> _availableDisplayResolutions = new List<Vector2Int>();
|
|
|
|
|
private readonly List<string> _displayResolutionOptions = new List<string>();
|
|
|
|
|
|
|
|
|
|
public Dropdown qualityPresetDropdown;
|
|
|
|
|
[FormerlySerializedAs("resolutionLevelModifier")]
|
|
|
|
|
public ValueModifier renderScaleModifier;
|
2025-08-11 14:04:06 -04:00
|
|
|
public ValueModifier targetFrameModifier;
|
2026-07-19 16:44:58 -04:00
|
|
|
public Switch postProcessingSwitch;
|
|
|
|
|
public Dropdown bloomQualityDropdown;
|
|
|
|
|
public Dropdown vfxQualityDropdown;
|
|
|
|
|
public Switch vSyncSwitch;
|
|
|
|
|
public Dropdown displayModeDropdown;
|
|
|
|
|
public Dropdown displayResolutionDropdown;
|
2026-07-21 09:58:21 +08:00
|
|
|
|
2025-08-11 14:04:06 -04:00
|
|
|
public override void Initialize()
|
|
|
|
|
{
|
2026-07-25 13:27:53 -04:00
|
|
|
qualityPresetDropdown.SetUpLocalized((int)gameSettings.graphicsQualityPreset, UiTable, QualityPresetKeys);
|
2026-07-19 16:44:58 -04:00
|
|
|
qualityPresetDropdown.updateValueAction = () =>
|
|
|
|
|
{
|
|
|
|
|
gameSettings.graphicsQualityPreset = (GraphicsQualityPreset)qualityPresetDropdown.selectedIndex;
|
|
|
|
|
SettingsManager.instance.ApplyGraphicSettings();
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
renderScaleModifier.SetUp(gameSettings.renderScaleLevel, 1);
|
2026-07-19 16:44:58 -04:00
|
|
|
renderScaleModifier.SetMinMax(0, 5);
|
|
|
|
|
renderScaleModifier.updateValueAction = () =>
|
2025-08-11 14:04:06 -04:00
|
|
|
{
|
2026-07-19 16:44:58 -04:00
|
|
|
gameSettings.renderScaleLevel = renderScaleModifier.GetValue();
|
|
|
|
|
SettingsManager.instance.ApplyGraphicSettings();
|
2025-08-11 14:04:06 -04:00
|
|
|
};
|
2026-07-21 09:58:21 +08:00
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
targetFrameModifier.SetUp(gameSettings.targetFrame, 30);
|
2025-08-11 14:04:06 -04:00
|
|
|
targetFrameModifier.SetMinMax(30, 120);
|
|
|
|
|
targetFrameModifier.updateValueAction = () =>
|
|
|
|
|
{
|
|
|
|
|
gameSettings.targetFrame = targetFrameModifier.GetValue();
|
2026-07-19 16:44:58 -04:00
|
|
|
SettingsManager.instance.ApplyGraphicSettings();
|
2025-08-11 14:04:06 -04:00
|
|
|
};
|
2026-07-19 16:44:58 -04:00
|
|
|
|
|
|
|
|
InitializePostProcessingSettings();
|
|
|
|
|
|
|
|
|
|
#if UNITY_STANDALONE || UNITY_EDITOR
|
|
|
|
|
InitializeDesktopDisplaySettings();
|
|
|
|
|
#else
|
|
|
|
|
vSyncSwitch.gameObject.SetActive(false);
|
|
|
|
|
displayModeDropdown.gameObject.SetActive(false);
|
|
|
|
|
displayResolutionDropdown.gameObject.SetActive(false);
|
|
|
|
|
#endif
|
2025-08-11 14:04:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void SetValuesFromSettings()
|
|
|
|
|
{
|
2026-07-19 16:44:58 -04:00
|
|
|
qualityPresetDropdown.SetValue((int)gameSettings.graphicsQualityPreset);
|
|
|
|
|
renderScaleModifier.SetValue(gameSettings.renderScaleLevel);
|
2025-08-11 14:04:06 -04:00
|
|
|
targetFrameModifier.SetValue(gameSettings.targetFrame);
|
2026-07-19 16:44:58 -04:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
postProcessingSwitch.SetUp(gameSettings.enablePostProcessing);
|
2026-07-19 16:44:58 -04:00
|
|
|
postProcessingSwitch.updateValueAction = () =>
|
|
|
|
|
{
|
|
|
|
|
gameSettings.enablePostProcessing = postProcessingSwitch.GetValue();
|
|
|
|
|
SettingsManager.instance.ApplyPostProcessingSettings();
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
bloomQualityDropdown.SetUpLocalized((int)gameSettings.bloomQuality, UiTable, BloomQualityKeys);
|
2026-07-19 16:44:58 -04:00
|
|
|
bloomQualityDropdown.updateValueAction = () =>
|
|
|
|
|
{
|
|
|
|
|
gameSettings.bloomQuality = (BloomQuality)bloomQualityDropdown.selectedIndex;
|
|
|
|
|
SettingsManager.instance.ApplyPostProcessingSettings();
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
vfxQualityDropdown.SetUpLocalized((int)gameSettings.vfxQuality, UiTable, VfxQualityKeys);
|
2026-07-19 16:44:58 -04:00
|
|
|
vfxQualityDropdown.updateValueAction = () =>
|
|
|
|
|
{
|
|
|
|
|
gameSettings.vfxQuality = (VfxQuality)vfxQualityDropdown.selectedIndex;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if UNITY_STANDALONE || UNITY_EDITOR
|
|
|
|
|
private void InitializeDesktopDisplaySettings()
|
|
|
|
|
{
|
|
|
|
|
BuildDisplayResolutionOptions();
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
vSyncSwitch.SetUp(gameSettings.vSyncEnabled);
|
2026-07-19 16:44:58 -04:00
|
|
|
vSyncSwitch.updateValueAction = () =>
|
|
|
|
|
{
|
|
|
|
|
gameSettings.vSyncEnabled = vSyncSwitch.GetValue();
|
|
|
|
|
SettingsManager.instance.ApplyDisplaySettings();
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
displayModeDropdown.SetUpLocalized((int)gameSettings.displayMode, UiTable, DisplayModeKeys);
|
2026-07-19 16:44:58 -04:00
|
|
|
displayModeDropdown.updateValueAction = () =>
|
|
|
|
|
{
|
|
|
|
|
gameSettings.displayMode = (GraphicsDisplayMode)displayModeDropdown.selectedIndex;
|
|
|
|
|
SettingsManager.instance.ApplyDisplaySettings();
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-25 13:27:53 -04:00
|
|
|
displayResolutionDropdown.SetUpRuntime(GetDisplayResolutionIndex(), _displayResolutionOptions);
|
2026-07-19 16:44:58 -04:00
|
|
|
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));
|
2025-08-11 14:04:06 -04:00
|
|
|
}
|
2026-07-19 16:44:58 -04:00
|
|
|
#endif
|
2025-08-11 14:04:06 -04:00
|
|
|
}
|
2026-07-19 16:44:58 -04:00
|
|
|
}
|