일지

유니티 화면 비율 고정 처리...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;
	}
}

 

실행 결과는 예상과 다르게 커서를 움직이고 뗀 뒤에 유니티 창 내부로 이동해야 마우스 커서를 받아와 처리를 진행했다.

 

커서 상태가 바뀐 상태에서 마우스 버튼을 눌렀을 때 상태를 저장하고 이후 마우스를 떼면 그때 크기 변경 처리를 진행하도록 해 봐야 할 것 같다.