-
유니티 화면 비율 고정 처리...10일지 2021. 10. 5. 18:43
화면 비율 고정 처리 동작 안 하는 경우 확인
비율 처리가 동작하지 않는 경우에 대한 처리를 확인하기 위해 코드를 조금 정리해서 상태에 따라 값을 출력하도록 했다.
ResolutionController.cs
using System; using System.Collections; using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.UI; public class ResolutionController : MonoBehaviour { public float AspectX { get; set; } = 16; public float AspectY { get; set; } = 9; public Text m_debugText; #region ENUMERATIONS private enum Cursors { IDC_ARROW = 32512, IDC_SIZENESW = 32643, IDC_SIZENS = 32645, IDC_SIZENWSE = 32642, IDC_SIZEWE = 32644, } private enum UpdateState { Waiting, Changing, Updating, } #endregion #region WINAPI_DLL [StructLayout(LayoutKind.Sequential)] public struct POINT { public Int32 x; public Int32 y; } private const int VK_LBUTTON = 0x01; private const ushort KEY_HOLD = 0x8000; [DllImport("user32.dll")] private static extern IntPtr GetCursor(); [DllImport("user32.dll")] private static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName); [DllImport("user32.dll")] private static extern ushort GetAsyncKeyState(ushort vKey); #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 UpdateState m_updateState; 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); m_updateState = UpdateState.Waiting; m_debugText.text = $"Update State : {m_updateState}"; } private void Update() { IntPtr hCursor = GetCursor(); if (m_updateState == UpdateState.Waiting && IsChanging(hCursor) && IsMouseButtonClicked()) { m_updateState = UpdateState.Changing; m_debugText.text = $"Update State : {m_updateState}"; } else if(m_updateState == UpdateState.Changing && !IsMouseButtonClicked()) { StartCoroutine(SetFixedResolution()); } } private IEnumerator SetFixedResolution() { m_updateState = UpdateState.Updating; m_debugText.text = $"Update State : {m_updateState}"; 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_updateState = UpdateState.Waiting; m_debugText.text = $"Update State : {m_updateState}"; } 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; } private bool IsMouseButtonClicked() { return (GetAsyncKeyState(VK_LBUTTON) & KEY_HOLD) != 0; } }
빌드 후 실행 결과는 다음과 같다.
상태 변경 테스트 아마 변경 과정에 SetResolution이 씹히고 있는 게 아닐까 한다.
생각해 볼 수 있는 처리 방법으로는 변경 후 대기 시간을 조금 늘려주거나 확실히 변경될 수 있도록 여러 번 과정을 반복시키는 방법이 있을 것 같다.