
게임을 만들다보면 생각해야할 부분이 상당히 많은데,
UI와 화면구성, 화면비같은 시각적인 부분도 상당히 중요한 요소들이다.
요즘 스마트폰들의 화면비를 보면 다들 화려한 개성들을 뽐내기 때문에 그 부분도 신경써야하는데..
노치, 펀치홀 디자인과 같은 요소들이 생겨 이 또한 신경을 써야한다.
개인적으로 느끼기에 요즘 나온 게임인데도 불구하고, 화면의 양옆에 광활한 레터박스를 만들어놓은 게임들은 조금 옛날 느낌이 난다고 해야하나? 나는 그렇게 느껴진다.
특히나 내 폰은 z플립3 이기 때문에 세로폭이 길어서 레터박스가 엄청나게 커지는데
그러면 유저들이 조금 답답함을 느낄 수 있다고 생각한다.
아무튼 노치와 펀치홀을 가지고있는 핸드폰에 대응하기 위해서 우린 두가지 선택을 할 수 있다.
1. 레터박스 없이 전체 화면을 사용하지만, ui들을 조금 안쪽으로 당긴다.
2. 노치와 펀치홀쪽 부분만 레터박스를 사용한다.
최근에 조금씩 하고있는 모바일게임 <픽셀 판타지아> 를 플레이해보면
위 스크린샷과 같이 펀치홀 부분만 살짝 레터박스가 생긴것을 볼 수있다.
Safe Area Helper | GUI Tools | Unity Asset Store
Safe Area Helper | GUI 도구 | Unity Asset Store
Use the Safe Area Helper from Crystal Pug on your next project. Find this GUI tool & more on the Unity Asset Store.
assetstore.unity.com
위 처럼 구현하기 위해서는 간편하게 에셋을 사용해도 된다.
하지만 내가 직접 만들 수 없는 기능을 에셋으로 사용한다면 뭔가 찝찝한 부분이 있어서 공부를 해봤다.
Safe Area?
유니티의 게임씬에서 Game부분을 눌러보면 Simulator가 있다.
현재 제작하고 있는 게임화면이 핸드폰에서 어떻게 나오는지를 미리 확인할 수 있는 기능이다.
현재 내가 사용하는 버전 21.3.18f1 버전에서는 내 폰까지 지원을 해주고 있어서 상당히 놀랐다.
아무튼 테스트가 필요한 기종으로 바꿔보면 해당 핸드폰에서 어떻게 화면을 표시해주는지를 보여준다.
오른쪽 옆에 'Safe Afea'를 눌러보면,
이런식으로 펀치홀을 제외한 부분이 노란색으로 표시된다.
위에 기종들을 바꿔보면 알아서 Safe Area가 설정되는것을 볼 수 있을것이다.
이름부터 직관적으로 느껴지기에도 안전 구역이라는 뜻은 UI를 보여주기에 알맞은 구역이라는 느낌이 강하게 든다.
이제 우리는 이 Safe Area를 가져와서 설정을 해주어야한다.
기본 세팅
이런식으로 캔버스를 만들어주고, 그 밑에 바로 parent라는 빈 오브젝트를 만들어주었다.
글리고 이 Parent라는 오브젝트의 앵커 프리셋을 alt를 눌러 가로 세로 스트레치로 쫙 늘려주었다.
그리고 안에는 하얀색 배경 이미지를 똑같이 쫙 펴주고, 간단한 이미지 하나를 중앙에 배치시켰다.
앵커
가로세로를 스트레치로 쫙 늘려준 하얀색 배경의 앵커를 건드려보자.
현재는 가로세로로 쭉 늘려주었으니, 각 위치에 맞게 앵커가 자리가 잡혀있다.
(X값은 맨왼쪽 0, 오른쪽 1)
(Y값은 맨 아래 0, 맨 위가 1)
이 상태에서 Y값의 맥스치를 0.8정도로 변경해보면?
실제 인게임 화면의 변화는 없지만 앵커 프리셋의 모양이 바뀌고, Top의 값이 수정된다.
이상태에서 Top을 0으로 바꿔보자
앵커의 최대 Y값이 내려오면서 하얀색 배경은 0.8 부분까지만 보이게 된다.
우리는 이걸 이용해서 Safe Area만큼의 화면을 맞춰줄것이다.
Rect 와 RectTransform
아마 대다수의 분들이 RectTrasfrom은 상당히 많이 써보셨을테지만,
RectTrasfrom 안에있는 Rect 구조체는 잘 모르실수도 있다고 생각한다.
나도 RectTrasfrom만 썼지, 그 안에 Rect 까지는 써본적이 없었다.
설명을 보면 트랜스폼의 로컬 공간에서 계산된 사각형이라고 뜨는데,
RectTrasfrom은 인스펙터에 있는 값들을 그대로 가져오는거라면
Rect는 그 트랜스폼의 사각형에 대한 로컬값을 가져온다.
실험을 위해 내가 아까 만든 아이콘을 쭉 늘려보았다.
void Start()
{
RectTransform rectTransform = GetComponent<RectTransform>();
Debug.Log(rectTransform.rect.size);
Debug.Log(rectTransform.sizeDelta);
}
실험을 통해 스타트 함수에 rect.size와 RectTransfrom.sizeDelta를 비교해보면
렉트 트렌스폼은 인스펙트의 값을 그대로 들고왔지만, rect.size는 실제 사이즈를 알려주었다.
오늘의 주제는 이 두개가 아니기 때문에, 나머지 프로퍼티들도 실험을 해보시면 차이를 아실수있다.
Screen.safeArea
그래서 우리가 safeArea를 이용해 필요한 비율을 조절하기 위해서는 Screen.SafeArea를 통해 그 값을 가져올 수 있는데,
Screen 클래스안에있는 safeArea를 보면 Rect 형식이다.
여기서 우리가 필요한 프로퍼티는 Rect.min 과 max이다.
Rect.min & max
Rect.min은 Pivot에서 좌측하단까지 가기위한 좌표를 반환하고,
Rect.max는 Pivot에서 우측 상단까지의 좌표를 반환한다.
가로세로가 100인 정사각형, Pivot은 (0.5,0.5) 인 Rect에서 min과 max를 받아온다면
min : (-50,-50)
max : (50,50)
이 나올것이다.
기준이 Pivot이기 때문에, 피벗을 바꾸면 값도 달라진다.
Safe Area의 min,max
아이폰 12 프로는 SafeArea가 하단과 상단 모두 떨어져있어서 테스트를 하기 용이했다.
이 상태에서 Safearea의 min,max를 찍어보았다.
아까 말했듯이 min과 max는 pivot으로 부터 좌측하단, 우측 상단의 거리인데..
min의 y값이 102라는 뜻은 pivot이 Safearea의 좌측 하단이 아닌 실제 스크린의 좌측하단 이라는것을 알 수 있다.
실제 코드로 적용해보기
아까 앵커설명 부분에서 적용했듯이 우리는 실제 스크린과 이 SafeArea의 비율을 이용해서 화면을 맞춰줄것이다.
빨간색 네모는 실제 스크린의 크기이고, 노란색 부분은 Safearea이다.
현재 가로는 실제 스크린과 SafeArea 의 갭이 없기때문에,
앵커의 최소,최대 y값만 수정해주어도 상관이없다. (하늘색 부분)
하지만 여러 핸드폰에 대응을 해야하기 때문에 아래와 같이 코드를 작성했다.
Vector2 minAnchor;
Vector2 maxAnchor;
private void Start()
{
var Myrect = this.GetComponent<RectTransform>();
minAnchor = Screen.safeArea.min;
maxAnchor = Screen.safeArea.max;
minAnchor.x /= Screen.width;
minAnchor.y /= Screen.height;
maxAnchor.x /= Screen.width;
maxAnchor.y /= Screen.height;
Myrect.anchorMin = minAnchor;
Myrect.anchorMax = maxAnchor;
}
현재 스크린의 너비와 높이에 대한 safeArea의 비율을 계산해주어 앵커에 적용을 시켜주었다.
완성 화면
SafeArea의 비율만큼 앵커가 수정되어 적용이 된것을 볼 수있다.
빈공간의 파란색이 보기 싫다면 카메라의 BackGround 색상을 수정시키면 된다.
내 핸드폰인 z플립3로 설정해도 잘 적용이 된다.
늘 느끼는 거지만 에셋을 쓰면 편하긴하다.
끝
'게임 엔진 > Unity' 카테고리의 다른 글
Dotween tmp.pro DoText 함수 직접 구현하기 (0) | 2023.04.16 |
---|---|
유니티 로컬라이제이션 기능 사용해보기 (6) | 2023.02.26 |
유니티로 구글 애드몹(AdMob) 테스트 해보기 (0) | 2023.01.29 |
유니티 에셋공부 <Feel> - (1) (0) | 2023.01.18 |
유니티 에셋공부 <DOTween Pro> - (3) (0) | 2023.01.18 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!