일지
유니티 화면 비율 고정 처리...7
niamdank
2021. 9. 27. 20:20
커서를 이용한 사이즈 조절 처리
커서를 받아오고 사이즈 변경에 관련된 커서가 아닐 때 사이즈를 변경하도록 수정했다.
ResolutionController.cs
using System;
using System.Collections;
using System.Runtime.InteropServices;
using UnityEngine;
public class ResolutionController : MonoBehaviour
{
public float AspectX { get; set; } = 16;
public float AspectY { get; set; } = 9;
#region ENUMERATIONS
private enum Cursors
{
IDC_ARROW = 32512,
IDC_SIZENESW = 32643,
IDC_SIZENS = 32645,
IDC_SIZENWSE = 32642,
IDC_SIZEWE = 32644,
}
#endregion
#region WINAPI_DLL
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public Int32 x;
public Int32 y;
}
[DllImport("user32.dll")]
public static extern IntPtr GetCursor();
[DllImport("user32.dll")]
public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
#endregion
#region WINAPI_VARIABLES
private IntPtr CursorNESW { get; set; }
private IntPtr CursorNS { get; set; }
private IntPtr CursorNWSE { get; set; }
private IntPtr CursorWE { get; set; }
#endregion
private float m_aspectRatio;
private int m_screenSizeX;
private int m_screenSizeY;
private bool m_isChanging;
private bool m_isUpdating;
private void Start()
{
m_aspectRatio = AspectX / AspectY;
m_screenSizeX = Screen.width;
m_screenSizeY = Screen.height;
Initialize();
}
private void Initialize()
{
CursorNESW = LoadCursor(IntPtr.Zero, (int)Cursors.IDC_SIZENESW);
CursorNS = LoadCursor(IntPtr.Zero, (int)Cursors.IDC_SIZENS);
CursorNWSE = LoadCursor(IntPtr.Zero, (int)Cursors.IDC_SIZENWSE);
CursorWE = LoadCursor(IntPtr.Zero, (int)Cursors.IDC_SIZEWE);
}
private void Update()
{
if (m_isUpdating)
{
return;
}
IntPtr hCursor = GetCursor();
if (IsStartChaning(hCursor))
{
}
else if(IsEndChanging(hCursor))
{
StartCoroutine(SetFixedResolution());
}
}
private IEnumerator SetFixedResolution()
{
m_isUpdating = true;
int newScreenSizeX = Screen.width;
int newScreenSizeY = Screen.height;
if (newScreenSizeX != m_screenSizeX && newScreenSizeY != m_screenSizeY)
{
if (Mathf.Abs(newScreenSizeX - m_screenSizeX) > Mathf.Abs(newScreenSizeY - m_screenSizeY))
{
newScreenSizeY = Mathf.FloorToInt(newScreenSizeX / m_aspectRatio);
}
else
{
newScreenSizeX = Mathf.FloorToInt(newScreenSizeY * m_aspectRatio);
}
}
else if (newScreenSizeX != m_screenSizeX)
{
newScreenSizeY = Mathf.FloorToInt(newScreenSizeX / m_aspectRatio);
}
else
{
newScreenSizeX = Mathf.FloorToInt(newScreenSizeY * m_aspectRatio);
}
m_screenSizeX = newScreenSizeX;
m_screenSizeY = newScreenSizeY;
Screen.SetResolution(m_screenSizeX, m_screenSizeY, false);
yield return null;
m_isUpdating = false;
}
private bool IsStartChaning(IntPtr hCursor)
{
if (m_isChanging) return false;
if (!IsChanging(hCursor)) return false;
m_isChanging = true;
return true;
}
private bool IsEndChanging(IntPtr hCursor)
{
if (!m_isChanging) return false;
if (IsChanging(hCursor)) return false;
m_isChanging = false;
return true;
}
private bool IsChanging(IntPtr hCursor)
{
if (hCursor == CursorNESW) return true;
if (hCursor == CursorNS) return true;
if (hCursor == CursorNWSE) return true;
if (hCursor == CursorWE) return true;
return false;
}
}
실행 결과는 예상과 다르게 커서를 움직이고 뗀 뒤에 유니티 창 내부로 이동해야 마우스 커서를 받아와 처리를 진행했다.
커서 상태가 바뀐 상태에서 마우스 버튼을 눌렀을 때 상태를 저장하고 이후 마우스를 떼면 그때 크기 변경 처리를 진행하도록 해 봐야 할 것 같다.