Canvas와 Fit Height, Fit Width의 적용 원리와 같은 기본 개념은 이전에 작성한 글에서 확인 가능하다.
위 글에서 정리한 기본적인 개념을 더 확장하고, 추가 개념을 입혀서
내가 만든 게임이 PC와 모든 모바일 기기 해상도에서 문제없이 잘 나오도록 하는 것이 목표다.
또한 UI를 PC용, 태블릿용, 모바일 가로용, 모바일 세로용으로 각각 만든다는 것은 작업의 효율이 떨어지기 때문에
최대한 적은 개수의 UI로 모든 해상도에 대응할 수 있어야 한다.
1. 해상도 대응하는 시점
cc.view.setResizeCallback(() => this.ResizeSolution());
프로젝트의 초기화 시점에서 ResizeCallback에 함수를 등록시켜 준다.
그러면 화면의 프레임 사이즈가 바뀔 때마다 실행된다. 이 함수 안에서 바뀐 해상도를 계산해서 대응하면 된다.
코코스 에디터에서는 해상도 프리셋을 바꿀 때, PC 빌드에서는 크롬 브라우저의 크기를 바꿀 때,
모바일에서는 핸드폰을 가로로 눕히거나 세로로 세울 때 실행된다.
2. 용어 설명
아래의 용어들은 내가 정리하기 위해서 만든 용어다.
- Design Size
const designSize: cc.Size = cc.view.getDesignResolutionSize();
씬에 있는 메인 Canvas의 크기와 동일. 가로, 세로 전환해도 width, height는 바뀌지 않고 항상 고정.
- Frame Size
const frameSize: cc.Size = cc.view.getFrameSize();
실제 Screen 화면의 크기와 동일. 언제나 유동적이고 가로, 세로 전환 시 width, height가 바뀜.
- Resolution Ratio
static ResolutionRatio(): number {
const designSize: cc.Size = cc.view.getDesignResolutionSize();
const frameSize: cc.Size = cc.view.getFrameSize();
if (frameSize.height/frameSize.width < designSize.height/designSize.width)
return frameSize.height/designSize.height;
else
return frameSize.width/designSize.width;
}
Frame Size가 Design Size와 얼마나 차이 나는지 비율이다.
씬에서 캔버스로 세팅한 기본 해상도와 실제 기기에서의 해상도가 얼마만큼 차이 나는지를 의미한다.
가로일 때의 Resolution Ratio는 frameSize.height / designSize.height = 418/720 = 0.58
세로일 때의 Resolution Ratio는 frameSize.width / designSize.width = 418/1280 = 0.326
Design Size에 맞게 제작된 UI 노드를 얼마만큼 늘릴 것인지, 그 수치를 계산할 때 이용한다.
- Aspect Ratio
static AspectRatio(): number {
const frameSize: cc.Size = cc.view.getFrameSize();
if (frameSize.width > frameSize.height)
return frameSize.width/frameSize.height;
else
return frameSize.height/frameSize.width;
}
Frame Size의 가로:세로 비율이다.
가로일 때의 Aspect Ratio는 frameSize.width / frameSize.height = 899/418 = 2.15
세로일 때의 Aspect Ratio는 frameSize.height / frameSize.width = 899/418 = 2.15
실제 기기가 정사각형에 가까울수록, 태블릿에 가까울 수록 비율이 낮아진다. (iPad Pro 11인치가 1.30과 1.64)
Safari 브라우저를 사용하는 아이폰과 아이패드는 가로일 때 비율과 세로일 때 비율이 다르게 나온다.
이유는 세로일 때 상단과 하단에 고정되는 UI가 실제 Frame Size를 더욱 작게 만들기 때문이다.
갤럭시폰의 삼성 인터넷이나 크롬은 전체화면을 제공하기 때문에 비율은 항상 같다.
이 해상도가 태블릿 해상도인지, 예외처리가 필요한 해상도인지 확인할 때 이용한다.
3. 노드 크기 조정
Resolution Ratio를 통해서 노드의 크기를 조정할 때
노드의 width, height 사이즈를 조정하는 방법이 있고 노드 자체의 scale을 조정하는 방법이 있다.
전자는 노드 안에 widget 컴포넌트들이 있을 때 적절하다.
대신에 widget에 의해서 이 해상도에서는 UI 간의 여백 간격이 크고, 어떤 해상도에서는 적은 차이가 발생할 수 있다.
후자는 모든 해상도에서 동일한 여백 간격을 유지할 수 있다.
(1) 노드의 width, height 조정
예시 : 공용 Window 프리팹
프리팹의 초기 사이즈가 가로 모드는 1280x720, 세로 모드는 1707x2276으로 설정돼 있지만
실제 화면 크기에 맞게 이 노드의 사이즈를 조정해줘야 한다.
가로 모드 프리팹은 width, height 모두 늘려주고, 세로 모드 프리팹은 width는 고정하고 height만 늘리는 규칙을 적용했다.
즉 가로는 Fit Width와 Fit Height를 모두 적용하고, 세로는 Fit Width를 적용했다.
가로 모드에서 targetSize
= (frameSize.width / Resolution Ratio, frameSize.height / Resolution Ratio)
= (899/0.58, 418/0.58)
= (1550, 720)
세로 모드에서 targetSize
= (windowNode.width, frameSize.height / Resolution Ratio)
= (1707, 899/0.326)
= (1707, 2757)
windowNode.setContentSize(targetSize.width, targetSize.height);
(2) 노드의 scale 조정
예시 : 백그라운드 프리팹
위 방법과 똑같이 새로 적용할 노드 사이즈 B를 먼저 계산한 뒤에
원래 프리팹의 사이즈 A에 나누면 얼마만큼 커졌는지 나오게 되고 이게 곧 targetScale이 된다.
가로에서는 Fit Width, 세로에서는 Fit Height를 적용했다.
새로 적용할 노드 사이즈 B와 원래 프리팹 사이즈 A의 크기 차이의 비율은 당연히 width와 height가 서로 다르다.
width 차이의 비율을 그대로 프리팹 scale에 적용하면 그대로 Fit Width 효과가 적용된다.
가로 모드에서 targetScale
= B (frameSize.width / Resolution Ratio) / A (backgroundNode.width)
= (899/0.58) / 1280
= 1.21
세로 모드에서 targetScale
= B (frameSize.height / Resolution Ratio) / A (backgroundNode.height)
= (899/0.326) / 2276
= 1.21
backgroundNode.scale = targetScale;
'Cocos Creator' 카테고리의 다른 글
노드 안에 노드가 들어있는지 확인하기 (0) | 2023.04.03 |
---|---|
간단한 미니 맵 (0) | 2023.04.03 |
Spine (2) | 2023.02.16 |
런타임 중에 노드의 뎁스(Depth) 정렬하기 (0) | 2023.01.19 |
스크롤 뷰(Scroll View)와 스크롤 바(Scroll Bar) (0) | 2022.12.13 |