ui基本完毕,修了一大把的bug
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user