창 올라타기
This commit is contained in:
@@ -12,6 +12,52 @@
|
||||
/// </summary>
|
||||
public static class DesktopCursor
|
||||
{
|
||||
/// <summary>
|
||||
/// 데스크톱 물리 좌표(Y 아래로) <-> Unity 화면 좌표(Y 위로) 변환에 필요한 정보.
|
||||
/// 창 사각형을 매번 다시 묻지 않도록 한 번 만들어 재사용한다.
|
||||
/// </summary>
|
||||
public struct Mapping
|
||||
{
|
||||
public int Left, Top, Width, Height;
|
||||
public float ScaleX, ScaleY;
|
||||
|
||||
public float ToScreenX(float desktopX) => (desktopX - Left) * ScaleX;
|
||||
public float ToScreenY(float desktopY) => (Height - (desktopY - Top)) * ScaleY;
|
||||
public Vector2 ToScreen(float desktopX, float desktopY)
|
||||
=> new Vector2(ToScreenX(desktopX), ToScreenY(desktopY));
|
||||
}
|
||||
|
||||
/// <summary>우리 창을 기준으로 한 좌표 변환 정보를 구한다.</summary>
|
||||
public static bool TryGetMapping(System.IntPtr hwnd, out Mapping mapping)
|
||||
{
|
||||
mapping = default;
|
||||
|
||||
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
|
||||
if (hwnd == System.IntPtr.Zero) return false;
|
||||
if (!Win32.GetWindowRect(hwnd, out var rc)) return false;
|
||||
if (rc.Width <= 0 || rc.Height <= 0) return false;
|
||||
|
||||
mapping = new Mapping
|
||||
{
|
||||
Left = rc.left,
|
||||
Top = rc.top,
|
||||
Width = rc.Width,
|
||||
Height = rc.Height,
|
||||
// 창 크기와 백버퍼 크기가 어긋날 경우를 대비해 비율로 환산한다.
|
||||
ScaleX = Screen.width / (float)rc.Width,
|
||||
ScaleY = Screen.height / (float)rc.Height,
|
||||
};
|
||||
return true;
|
||||
#else
|
||||
mapping = new Mapping
|
||||
{
|
||||
Left = 0, Top = 0, Width = Screen.width, Height = Screen.height,
|
||||
ScaleX = 1f, ScaleY = 1f,
|
||||
};
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 커서의 Unity 화면 좌표(좌하단 원점)를 구한다. 커서가 창 밖이면 false.
|
||||
/// </summary>
|
||||
@@ -20,22 +66,14 @@ public static bool TryGetScreenPosition(System.IntPtr hwnd, out Vector2 screenPo
|
||||
screenPos = default;
|
||||
|
||||
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
|
||||
if (hwnd == System.IntPtr.Zero) return false;
|
||||
if (!Win32.GetCursorPos(out var pt)) return false;
|
||||
if (!Win32.GetWindowRect(hwnd, out var rc)) return false;
|
||||
if (!TryGetMapping(hwnd, out Mapping map)) return false;
|
||||
|
||||
int w = rc.Width, h = rc.Height;
|
||||
if (w <= 0 || h <= 0) return false;
|
||||
// 창 밖이면 무효로 본다.
|
||||
if (pt.x < map.Left || pt.y < map.Top ||
|
||||
pt.x >= map.Left + map.Width || pt.y >= map.Top + map.Height) return false;
|
||||
|
||||
// 창 기준 좌표 (좌상단 원점, Y 아래로)
|
||||
int localX = pt.x - rc.left;
|
||||
int localY = pt.y - rc.top;
|
||||
if (localX < 0 || localY < 0 || localX >= w || localY >= h) return false;
|
||||
|
||||
// Unity 화면 좌표로. 창 크기와 백버퍼 크기가 어긋날 경우를 대비해 비율 환산.
|
||||
screenPos = new Vector2(
|
||||
localX * (Screen.width / (float)w),
|
||||
(h - localY) * (Screen.height / (float)h));
|
||||
screenPos = map.ToScreen(pt.x, pt.y);
|
||||
return true;
|
||||
#else
|
||||
// 에디터에서는 일반 마우스 입력으로 대체해 미리보기가 가능하게 한다.
|
||||
|
||||
Reference in New Issue
Block a user