창 올라타기
This commit is contained in:
@@ -14,9 +14,24 @@
|
||||
[RequireComponent(typeof(Camera))]
|
||||
public class TransparentWindow : MonoBehaviour
|
||||
{
|
||||
public enum CoverageMode
|
||||
{
|
||||
/// <summary>플레이어 설정의 기본 해상도를 그대로 쓴다. 디버깅용.</summary>
|
||||
FixedSize,
|
||||
|
||||
/// <summary>주 모니터를 꽉 채운다. 해상도가 달라도 자동으로 맞춘다.</summary>
|
||||
PrimaryMonitor,
|
||||
|
||||
/// <summary>모든 모니터를 합친 가상 데스크톱 전체를 덮는다.</summary>
|
||||
VirtualDesktop,
|
||||
}
|
||||
|
||||
[Header("창 동작")]
|
||||
[Tooltip("창을 가상 데스크톱 전체로 확장. 클릭 통과가 동작하는 것을 확인한 뒤 켤 것")]
|
||||
[SerializeField] bool spanVirtualDesktop = false;
|
||||
[Tooltip("창이 덮을 범위. 해상도가 바뀌면 자동으로 다시 맞춘다")]
|
||||
[SerializeField] CoverageMode coverage = CoverageMode.PrimaryMonitor;
|
||||
|
||||
[Tooltip("해상도/모니터 변경을 확인하는 주기(초). 0 이면 확인하지 않는다")]
|
||||
[SerializeField] float boundsCheckInterval = 2f;
|
||||
|
||||
[Tooltip("작업표시줄 / Alt+Tab 에서 숨김 (WS_EX_TOOLWINDOW)")]
|
||||
[SerializeField] bool hideFromTaskbar = true;
|
||||
@@ -70,19 +85,74 @@ void Update()
|
||||
var kb = Keyboard.current;
|
||||
if (kb != null && kb.escapeKey.wasPressedThisFrame) Application.Quit();
|
||||
}
|
||||
|
||||
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
|
||||
CheckBoundsChanged();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
|
||||
/// <summary>설정한 범위에 해당하는 화면 사각형을 구한다.</summary>
|
||||
void GetTargetBounds(out int x, out int y, out int w, out int h)
|
||||
{
|
||||
switch (coverage)
|
||||
{
|
||||
case CoverageMode.PrimaryMonitor:
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = Win32.GetSystemMetrics(Win32.SM_CXSCREEN);
|
||||
h = Win32.GetSystemMetrics(Win32.SM_CYSCREEN);
|
||||
break;
|
||||
|
||||
case CoverageMode.VirtualDesktop:
|
||||
x = Win32.GetSystemMetrics(Win32.SM_XVIRTUALSCREEN);
|
||||
y = Win32.GetSystemMetrics(Win32.SM_YVIRTUALSCREEN);
|
||||
w = Win32.GetSystemMetrics(Win32.SM_CXVIRTUALSCREEN);
|
||||
h = Win32.GetSystemMetrics(Win32.SM_CYVIRTUALSCREEN);
|
||||
break;
|
||||
|
||||
default:
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = Screen.width;
|
||||
h = Screen.height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool applying;
|
||||
Vector4 appliedBounds = new Vector4(-1f, -1f, -1f, -1f);
|
||||
float nextBoundsCheck;
|
||||
|
||||
/// <summary>
|
||||
/// 해상도 변경, 모니터 연결/해제, 배율 변경에 대응한다.
|
||||
/// 이걸 안 하면 모니터를 바꿔 꽂았을 때 창이 예전 크기로 남아 화면 일부만 덮는다.
|
||||
/// </summary>
|
||||
void CheckBoundsChanged()
|
||||
{
|
||||
if (!IsReady || applying) return;
|
||||
if (boundsCheckInterval <= 0f) return;
|
||||
if (Time.unscaledTime < nextBoundsCheck) return;
|
||||
|
||||
nextBoundsCheck = Time.unscaledTime + boundsCheckInterval;
|
||||
|
||||
GetTargetBounds(out int x, out int y, out int w, out int h);
|
||||
var now = new Vector4(x, y, w, h);
|
||||
if (now == appliedBounds) return;
|
||||
|
||||
Debug.Log($"[TransparentWindow] 화면 구성 변경 감지: {appliedBounds} -> {now}. 다시 적용합니다.");
|
||||
StartCoroutine(ApplyWindowStyle());
|
||||
}
|
||||
|
||||
IEnumerator ApplyWindowStyle()
|
||||
{
|
||||
int x = 0, y = 0, w = Screen.width, h = Screen.height;
|
||||
applying = true;
|
||||
|
||||
if (spanVirtualDesktop)
|
||||
GetTargetBounds(out int x, out int y, out int w, out int h);
|
||||
appliedBounds = new Vector4(x, y, w, h);
|
||||
|
||||
if (coverage != CoverageMode.FixedSize && (w != Screen.width || h != Screen.height))
|
||||
{
|
||||
x = Win32.GetSystemMetrics(Win32.SM_XVIRTUALSCREEN);
|
||||
y = Win32.GetSystemMetrics(Win32.SM_YVIRTUALSCREEN);
|
||||
w = Win32.GetSystemMetrics(Win32.SM_CXVIRTUALSCREEN);
|
||||
h = Win32.GetSystemMetrics(Win32.SM_CYVIRTUALSCREEN);
|
||||
Screen.SetResolution(w, h, FullScreenMode.Windowed);
|
||||
}
|
||||
|
||||
@@ -123,7 +193,8 @@ IEnumerator ApplyWindowStyle()
|
||||
|
||||
Hwnd = hwnd;
|
||||
IsReady = true;
|
||||
Debug.Log($"[TransparentWindow] 적용 완료: {x},{y} {w}x{h}");
|
||||
applying = false;
|
||||
Debug.Log($"[TransparentWindow] 적용 완료: {coverage} {x},{y} {w}x{h}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user