ui基本完毕,修了一大把的bug

This commit is contained in:
FloatGaming
2026-07-13 02:28:39 +08:00
parent 1e20d73e90
commit fd22501f71
958 changed files with 378289 additions and 41038 deletions
+183 -92
View File
@@ -8,6 +8,11 @@ using System.Runtime.InteropServices;
public class graphicSettings : MonoBehaviour
{
private const string PrefKeyScreenMode = "screenMode";
private const string PrefKeyResolutionIndex = "resolutionIndex";
private const string PrefKeyCustomResW = "customResW";
private const string PrefKeyCustomResH = "customResH";
public Dropdown screenMode_Dropdown;
public Dropdown resolution_Dropdown;
public Dropdown frameRate_Dropdown;
@@ -30,6 +35,22 @@ public class graphicSettings : MonoBehaviour
lastScreenSize = new Vector2Int(Screen.width, Screen.height);
}
public static void ApplySavedDisplaySettingsAtStartup(MonoBehaviour coroutineRunner)
{
int screenMode = PlayerPrefs.GetInt(PrefKeyScreenMode, 0);
screenMode = Mathf.Clamp(screenMode, 0, 2);
try
{
ApplyScreenModeStatic(screenMode, coroutineRunner);
ApplySavedResolutionStatic();
}
catch (Exception ex)
{
Debug.LogWarning($"[graphicSettings] Failed to apply saved display settings at startup: {ex}");
}
}
void OnDestroy()
{
if (screenMode_Dropdown != null)
@@ -99,7 +120,7 @@ public class graphicSettings : MonoBehaviour
int current = MapFullScreenModeToIndex(Screen.fullScreenMode);
if (PlayerPrefs.HasKey("screenMode"))
{
int saved = PlayerPrefs.GetInt("screenMode", current);
int saved = PlayerPrefs.GetInt(PrefKeyScreenMode, current);
saved = Mathf.Clamp(saved, 0, options.Count - 1);
current = saved;
ApplyScreenMode(current);
@@ -129,7 +150,7 @@ public class graphicSettings : MonoBehaviour
private void OnScreenModeChanged(int index)
{
ApplyScreenMode(index);
PlayerPrefs.SetInt("screenMode", index);
PlayerPrefs.SetInt(PrefKeyScreenMode, index);
PlayerPrefs.Save();
bool isWindowed = (index == 0);
@@ -141,96 +162,17 @@ public class graphicSettings : MonoBehaviour
private void ApplyScreenMode(int index)
{
try
{
if (index == 0)
{
Screen.fullScreenMode = FullScreenMode.Windowed;
Screen.fullScreen = false;
StopAllCoroutines();
StartCoroutine(ApplyWindowStyleNextFrame(true));
Screen.SetResolution(Screen.width, Screen.height, FullScreenMode.Windowed, Screen.currentResolution.refreshRateRatio);
}
else if (index == 1)
{
Screen.fullScreenMode = FullScreenMode.ExclusiveFullScreen;
Screen.fullScreen = true;
Resolution res = Screen.currentResolution;
Screen.SetResolution(res.width, res.height, FullScreenMode.ExclusiveFullScreen, res.refreshRateRatio);
}
else if (index == 2)
{
Screen.fullScreenMode = FullScreenMode.FullScreenWindow;
Screen.fullScreen = true;
Resolution res = Screen.currentResolution;
Screen.SetResolution(res.width, res.height, FullScreenMode.FullScreenWindow, res.refreshRateRatio);
StopAllCoroutines();
StartCoroutine(ApplyWindowStyleNextFrame(false));
}
}
catch (System.Exception ex)
{
Debug.LogWarning($"ApplyScreenMode failed: {ex}");
}
ApplyScreenModeStatic(index, this);
}
private System.Collections.IEnumerator ApplyWindowStyleNextFrame(bool enable)
{
yield return null;
yield return new WaitForSeconds(0.05f);
EnableWindowedModeResizable(enable);
yield return ApplyWindowStyleNextFrameStatic(enable);
}
private void EnableWindowedModeResizable(bool enable)
{
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
try
{
IntPtr hWnd = GetForegroundWindow();
if (hWnd == IntPtr.Zero) return;
const int GWL_STYLE = -16;
const int WS_OVERLAPPEDWINDOW = unchecked((int)0x00CF0000);
const int WS_POPUP = unchecked((int)0x80000000);
if (IntPtr.Size == 8)
{
long style = GetWindowLongPtr64(hWnd, GWL_STYLE);
if (enable)
{
style &= ~((long)WS_POPUP);
style |= WS_OVERLAPPEDWINDOW;
}
else
{
style &= ~((long)WS_OVERLAPPEDWINDOW);
style |= (long)WS_POPUP;
}
SetWindowLongPtr64(hWnd, GWL_STYLE, style);
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
else
{
int style = GetWindowLong32(hWnd, GWL_STYLE);
if (enable)
{
style &= ~WS_POPUP;
style |= WS_OVERLAPPEDWINDOW;
}
else
{
style &= ~((int)WS_OVERLAPPEDWINDOW);
style |= (int)WS_POPUP;
}
SetWindowLong32(hWnd, GWL_STYLE, style);
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
}
catch (Exception e)
{
Debug.LogWarning($"EnableWindowedModeResizable failed: {e}");
}
#endif
EnableWindowedModeResizableStatic(enable);
}
private void InitResolutionDropdown()
@@ -295,7 +237,7 @@ public class graphicSettings : MonoBehaviour
}
}
int savedResIndex = PlayerPrefs.GetInt("resolutionIndex", -2);
int savedResIndex = PlayerPrefs.GetInt(PrefKeyResolutionIndex, -2);
if (savedResIndex >= 0 && savedResIndex < availableResolutions.Count)
{
resolution_Dropdown.SetValueWithoutNotify(savedResIndex);
@@ -305,8 +247,8 @@ public class graphicSettings : MonoBehaviour
}
else if (savedResIndex == -1)
{
int cw = PlayerPrefs.GetInt("customResW", -1);
int ch = PlayerPrefs.GetInt("customResH", -1);
int cw = PlayerPrefs.GetInt(PrefKeyCustomResW, -1);
int ch = PlayerPrefs.GetInt(PrefKeyCustomResH, -1);
if (cw > 0 && ch > 0)
{
Screen.SetResolution(cw, ch, Screen.fullScreenMode, Screen.currentResolution.refreshRateRatio);
@@ -325,7 +267,7 @@ public class graphicSettings : MonoBehaviour
}
resolution_Dropdown.onValueChanged.AddListener(OnResolutionChanged);
int screenMode = PlayerPrefs.GetInt("screenMode", MapFullScreenModeToIndex(Screen.fullScreenMode));
int screenMode = PlayerPrefs.GetInt(PrefKeyScreenMode, MapFullScreenModeToIndex(Screen.fullScreenMode));
bool isWindowed = (screenMode == 0) || (Screen.fullScreenMode == FullScreenMode.Windowed);
if (resolutionLock_Image != null)
resolutionLock_Image.gameObject.SetActive(!isWindowed);
@@ -354,9 +296,9 @@ public class graphicSettings : MonoBehaviour
if (index < 0) return;
if (index >= availableResolutions.Count)
{
PlayerPrefs.SetInt("resolutionIndex", -1);
PlayerPrefs.SetInt("customResW", Screen.width);
PlayerPrefs.SetInt("customResH", Screen.height);
PlayerPrefs.SetInt(PrefKeyResolutionIndex, -1);
PlayerPrefs.SetInt(PrefKeyCustomResW, Screen.width);
PlayerPrefs.SetInt(PrefKeyCustomResH, Screen.height);
PlayerPrefs.Save();
return;
}
@@ -364,7 +306,7 @@ public class graphicSettings : MonoBehaviour
var r = availableResolutions[index];
FullScreenMode mode = Screen.fullScreenMode;
Screen.SetResolution(r.x, r.y, mode, Screen.currentResolution.refreshRateRatio);
PlayerPrefs.SetInt("resolutionIndex", index);
PlayerPrefs.SetInt(PrefKeyResolutionIndex, index);
PlayerPrefs.Save();
RemoveTempFreeOptionIfExists();
@@ -484,6 +426,155 @@ public class graphicSettings : MonoBehaviour
}
}
private static void ApplyScreenModeStatic(int index, MonoBehaviour coroutineRunner)
{
try
{
if (index == 0)
{
Screen.fullScreenMode = FullScreenMode.Windowed;
Screen.fullScreen = false;
Screen.SetResolution(Screen.width, Screen.height, FullScreenMode.Windowed, Screen.currentResolution.refreshRateRatio);
if (coroutineRunner != null)
{
coroutineRunner.StartCoroutine(ApplyWindowStyleNextFrameStatic(true));
}
}
else if (index == 1)
{
Screen.fullScreenMode = FullScreenMode.ExclusiveFullScreen;
Screen.fullScreen = true;
Resolution res = Screen.currentResolution;
Screen.SetResolution(res.width, res.height, FullScreenMode.ExclusiveFullScreen, res.refreshRateRatio);
}
else if (index == 2)
{
Screen.fullScreenMode = FullScreenMode.FullScreenWindow;
Screen.fullScreen = true;
Resolution res = Screen.currentResolution;
Screen.SetResolution(res.width, res.height, FullScreenMode.FullScreenWindow, res.refreshRateRatio);
if (coroutineRunner != null)
{
coroutineRunner.StartCoroutine(ApplyWindowStyleNextFrameStatic(false));
}
}
}
catch (Exception ex)
{
Debug.LogWarning($"ApplyScreenMode failed: {ex}");
}
}
private static void ApplySavedResolutionStatic()
{
int savedResIndex = PlayerPrefs.GetInt(PrefKeyResolutionIndex, -2);
if (savedResIndex == -1)
{
int customWidth = PlayerPrefs.GetInt(PrefKeyCustomResW, -1);
int customHeight = PlayerPrefs.GetInt(PrefKeyCustomResH, -1);
if (customWidth > 0 && customHeight > 0)
{
Screen.SetResolution(customWidth, customHeight, Screen.fullScreenMode, Screen.currentResolution.refreshRateRatio);
}
return;
}
if (savedResIndex < 0)
{
return;
}
Vector2Int[] candidates =
{
new Vector2Int(1024, 576),
new Vector2Int(1152, 648),
new Vector2Int(1280, 720),
new Vector2Int(1366, 768),
new Vector2Int(1600, 900),
new Vector2Int(1920, 1080),
new Vector2Int(2560, 1440),
new Vector2Int(3440, 1440),
new Vector2Int(3200, 1800),
new Vector2Int(3840, 2160),
new Vector2Int(5120, 2880),
new Vector2Int(7680, 4320),
new Vector2Int(15360, 8640)
};
if (savedResIndex >= candidates.Length)
{
return;
}
Vector2Int resolution = candidates[savedResIndex];
Resolution currentResolution = Screen.currentResolution;
if (resolution.x > currentResolution.width || resolution.y > currentResolution.height)
{
return;
}
Screen.SetResolution(resolution.x, resolution.y, Screen.fullScreenMode, currentResolution.refreshRateRatio);
}
private static System.Collections.IEnumerator ApplyWindowStyleNextFrameStatic(bool enable)
{
yield return null;
yield return new WaitForSeconds(0.05f);
EnableWindowedModeResizableStatic(enable);
}
private static void EnableWindowedModeResizableStatic(bool enable)
{
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
try
{
IntPtr hWnd = GetForegroundWindow();
if (hWnd == IntPtr.Zero) return;
const int GWL_STYLE = -16;
const int WS_OVERLAPPEDWINDOW = unchecked((int)0x00CF0000);
const int WS_POPUP = unchecked((int)0x80000000);
if (IntPtr.Size == 8)
{
long style = GetWindowLongPtr64(hWnd, GWL_STYLE);
if (enable)
{
style &= ~((long)WS_POPUP);
style |= WS_OVERLAPPEDWINDOW;
}
else
{
style &= ~((long)WS_OVERLAPPEDWINDOW);
style |= (long)WS_POPUP;
}
SetWindowLongPtr64(hWnd, GWL_STYLE, style);
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
else
{
int style = GetWindowLong32(hWnd, GWL_STYLE);
if (enable)
{
style &= ~WS_POPUP;
style |= WS_OVERLAPPEDWINDOW;
}
else
{
style &= ~((int)WS_OVERLAPPEDWINDOW);
style |= (int)WS_POPUP;
}
SetWindowLong32(hWnd, GWL_STYLE, style);
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
}
catch (Exception e)
{
Debug.LogWarning($"EnableWindowedModeResizable failed: {e}");
}
#endif
}
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();