무더운 여름입니다. 이게 날씨인가 싶지만 개발은 계속됩니다.

최근에 UI디자이너분의 요청에 따라 기존에 사용하던 SafeArea를 개량했는데
의외로 쓸만하다는 생각이 들어서 이렇게 기록해 놓습니다.
제 블로그에서도 소개드렸던 에셋스토어에서 무료로 배포하는 SafeArea 에셋의 스크립트를 개조한 것 입니다.
기존에 사용하던 SafeArea는 X축, Y축만 대응이 가능했다고 한다면, 이번에 개량하게된 버전은
Topn Bottom, Left, Right 4방향을 조절할 수 있게 되었습니다.
using UnityEngine;
public class SafeArea : MonoBehaviour
{
    public enum SimDevice
    {
        None,
        iPhoneX,
        iPhoneXsMax,
        Pixel3XL_LSL,
        Pixel3XL_LSR
    }
    public static SimDevice Sim = SimDevice.None;
    Rect[] NSA_iPhoneX = new Rect[]
    {
        new Rect (0f, 102f / 2436f, 1f, 2202f / 2436f),  // Portrait
        new Rect (132f / 2436f, 63f / 1125f, 2172f / 2436f, 1062f / 1125f)  // Landscape
    };
    Rect[] NSA_iPhoneXsMax = new Rect[]
    {
        new Rect (0f, 102f / 2688f, 1f, 2454f / 2688f),  // Portrait
        new Rect (132f / 2688f, 63f / 1242f, 2424f / 2688f, 1179f / 1242f)  // Landscape
    };
    Rect[] NSA_Pixel3XL_LSL = new Rect[]
    {
        new Rect (0f, 0f, 1f, 2789f / 2960f),  // Portrait
        new Rect (0f, 0f, 2789f / 2960f, 1f)  // Landscape
    };
    Rect[] NSA_Pixel3XL_LSR = new Rect[]
    {
        new Rect (0f, 0f, 1f, 2789f / 2960f),  // Portrait
        new Rect (171f / 2960f, 0f, 2789f / 2960f, 1f)  // Landscape
    };
    RectTransform Panel;
    Rect LastSafeArea = new Rect (0, 0, 0, 0);
    Vector2Int LastScreenSize = new Vector2Int (0, 0);
    ScreenOrientation LastOrientation = ScreenOrientation.AutoRotation;
    // 해상도 좌우 대응
    [SerializeField] bool ConformLeft = true;
    [SerializeField] bool ConformRight = true;
    // 해상도 상하 대응
    [SerializeField] bool ConformTop = true;
    [SerializeField] bool ConformBottom = true;
    [SerializeField] bool Logging = false;
    void Awake ()
    {
        Panel = GetComponent<RectTransform> ();
        if (Panel == null)
        {
            Debug.LogError ("Cannot apply safe area - no RectTransform found on " + name);
            Destroy (gameObject);
        }
        Refresh ();
    }
    void Update ()
    {
        Refresh ();
    }
    void Refresh ()
    {
        Rect safeArea = GetSafeArea ();
        if (safeArea != LastSafeArea
            || Screen.width != LastScreenSize.x
            || Screen.height != LastScreenSize.y
            || Screen.orientation != LastOrientation)
        {
            // Fix for having auto-rotate off and manually forcing a screen orientation.
            // See https://forum.unity.com/threads/569236/#post-4473253 and https://forum.unity.com/threads/569236/page-2#post-5166467
            LastScreenSize.x = Screen.width;
            LastScreenSize.y = Screen.height;
            LastOrientation = Screen.orientation;
            ApplySafeArea (safeArea);
        }
    }
    Rect GetSafeArea ()
    {
        Rect safeArea = Screen.safeArea;
        if (Application.isEditor && Sim != SimDevice.None)
        {
            Rect nsa = new Rect (0, 0, Screen.width, Screen.height);
            switch (Sim)
            {
                case SimDevice.iPhoneX:
                    if (Screen.height > Screen.width)  // Portrait
                        nsa = NSA_iPhoneX[0];
                    else  // Landscape
                        nsa = NSA_iPhoneX[1];
                    break;
                case SimDevice.iPhoneXsMax:
                    if (Screen.height > Screen.width)  // Portrait
                        nsa = NSA_iPhoneXsMax[0];
                    else  // Landscape
                        nsa = NSA_iPhoneXsMax[1];
                    break;
                case SimDevice.Pixel3XL_LSL:
                    if (Screen.height > Screen.width)  // Portrait
                        nsa = NSA_Pixel3XL_LSL[0];
                    else  // Landscape
                        nsa = NSA_Pixel3XL_LSL[1];
                    break;
                case SimDevice.Pixel3XL_LSR:
                    if (Screen.height > Screen.width)  // Portrait
                        nsa = NSA_Pixel3XL_LSR[0];
                    else  // Landscape
                        nsa = NSA_Pixel3XL_LSR[1];
                    break;
                default:
                    break;
            }
            safeArea = new Rect (Screen.width * nsa.x, Screen.height * nsa.y, Screen.width * nsa.width, Screen.height * nsa.height);
        }
        return safeArea;
    }
    void ApplySafeArea (Rect r)
    {
        LastSafeArea = r;
        // Check for invalid screen startup state on some Samsung devices (see below)
        if (Screen.width > 0 && Screen.height > 0)
        {
            // Convert safe area rectangle from absolute pixels to normalised anchor coordinates
            Vector2 anchorMin = r.position;
            Vector2 anchorMax = r.position + r.size;
            if (!ConformRight) anchorMax.x = Screen.width;
            if (!ConformLeft) anchorMin.x = 0;
            if (!ConformTop) anchorMax.y = Screen.height;
            if (!ConformBottom) anchorMin.y = 0;
            anchorMin.x /= Screen.width;
            anchorMin.y /= Screen.height;
            anchorMax.x /= Screen.width;
            anchorMax.y /= Screen.height;
            // Fix for some Samsung devices (e.g. Note 10+, A71, S20) where Refresh gets called twice and the first time returns NaN anchor coordinates
            // See https://forum.unity.com/threads/569236/page-2#post-6199352
            if (anchorMin.x >= 0 && anchorMin.y >= 0 && anchorMax.x >= 0 && anchorMax.y >= 0)
            {
                Panel.anchorMin = anchorMin;
                Panel.anchorMax = anchorMax;
            }
        }
        if (Logging)
        {
            Debug.LogFormat ("New safe area applied to {0}: x={1}, y={2}, w={3}, h={4} on full extents w={5}, h={6}",
            name, r.x, r.y, r.width, r.height, Screen.width, Screen.height);
        }
    }
}
반응형
    
    
    
  '게임 개발 > Unity' 카테고리의 다른 글
| [유니티 C#] 특정 텍스트 눌러서 팝업 띄우기 (2) | 2022.08.29 | 
|---|---|
| [유니티 C#] MonoBehaviour를 상속 받아야하는 Singleton, 모노 싱글톤 (0) | 2021.08.29 | 
| [유니티 C#] UI Animation State 이름 중복 사용 (0) | 2021.07.11 | 
| [유니티 C#] PhotonNetwork 기본 콜백함수 찍먹하기 (1) | 2021.06.09 | 
| 유니티 Admob mediation adapter 적용시 빌드에러 (0) | 2021.02.14 |