
유니티 UI 를 여러 해상도에 맞추려면 Canvas 에 붙은 Canvas Scaler 의 UI Scale Mode 를 Scale With Screen Size 로 바꾸고, UI 를 그린 기준 해상도(Reference Resolution)를 넣습니다. 비율이 다른 화면에서 너비와 높이 중 어디에 맞출지는 Screen Match Mode 와 Match 값으로 정합니다.
canvas_scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvas_scaler.referenceResolution = new Vector2(1080f, 1920f); // UI 를 그린 기준 화면
canvas_scaler.matchWidthOrHeight = 0.5f; // 0 너비 · 1 높이
에디터의 Game 창에서는 버튼이 딱 맞았는데 폰에서 켜 보면 글자가 깨알처럼 작거나, 화면 양옆이 잘리거나, 태블릿에서 위아래 버튼이 화면 밖으로 나가는 일이 있습니다. Canvas Scaler 를 기본값(Constant Pixel Size)으로 두었거나, 맞추는 기준이 화면 비율과 맞지 않을 때 생기는 일입니다. 이번 글에서는 Canvas Scaler 를 코드로 맞추고 지금 화면의 배율과 UI 크기를 글자로 띄워 보는 CanvasScaleInfo 를 만들고, 폰 · 태블릿 해상도마다 Match 값에 따라 UI 가 어떤 크기가 되는지 계산해 비교했습니다.
C# (UNITY 3D)
CanvasScaleInfo 를 Canvas 에 붙이면 시작할 때 Canvas Scaler 가 Scale With Screen Size · 기준 1080 x 1920 · Match 0.5 로 맞춰집니다. text_info 를 넣어 두면 화면 크기가 바뀔 때마다 「화면 1080 x 2400 · 배율 · UI 크기」 가 글자로 바뀌어, 기기마다 UI 가 몇 단위 크기로 잡히는지 바로 볼 수 있습니다.
1. 준비 — Canvas Scaler 가 하는 일
using TMPro;
using UnityEngine.UI;
CanvasScaler 는 UnityEngine.UI, 정보 글자 TMP_Text 는 TMPro 에 있습니다.
Hierarchy 에서 UI 를 하나 만들면 Canvas 에 Canvas Scaler 가 함께 붙습니다. 기본인 Constant Pixel Size 는 UI 를 화면 픽셀 그대로 그려서, 해상도가 높은 폰일수록 UI 가 작아 보입니다. Scale With Screen Size 로 바꾸면 UI 는 늘 기준 해상도 단위로 놓이고, 실제 화면에 맞게 통째로 키우거나 줄입니다. 세로 게임이면 기준을 1080 x 1920 처럼 세로로 넣고, Game 창도 같은 해상도로 두고 배치하면 편합니다.
2. Canvas Scaler 를 맞추고 값을 띄우는 코드
using TMPro;
using UnityEngine;
using UnityEngine.UI;
//CodeFinder 코드파인더
//From https://codefinder.janndk.com/
[RequireComponent(typeof(CanvasScaler))]
public class CanvasScaleInfo : MonoBehaviour
{
public Vector2 reference_resolution = new Vector2(1080f, 1920f); // UI 를 그린 기준 화면(세로 게임)
[Range(0f, 1f)] public float match = 0.5f; // 0 이면 너비, 1 이면 높이에 맞춤
public TMP_Text text_info; // 지금 값을 띄울 글자(없어도 됨)
CanvasScaler canvas_scaler;
Canvas canvas;
int last_width;
int last_height;
void Awake()
{
canvas_scaler = GetComponent<CanvasScaler>();
canvas = GetComponent<Canvas>();
canvas_scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvas_scaler.referenceResolution = reference_resolution;
canvas_scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
canvas_scaler.matchWidthOrHeight = match;
}
void LateUpdate()
{
if (Screen.width == last_width && Screen.height == last_height)
return;
last_width = Screen.width; // 회전하거나 창 크기가 바뀌었을 때만
last_height = Screen.height;
Show_Info();
}
public void Show_Info()
{
if (text_info == null || canvas == null)
return;
Vector2 size = ((RectTransform)canvas.transform).rect.size; // UI 단위로 본 화면 크기
text_info.text = "화면 " + Screen.width + " x " + Screen.height
+ "\n배율 " + canvas.scaleFactor.ToString("F3")
+ "\nUI 크기 " + size.x.ToString("F0") + " x " + size.y.ToString("F0");
}
public static float Calc_Scale(Vector2 screen, Vector2 reference, float match)
{
float log_width = Mathf.Log(screen.x / reference.x, 2f); // 너비 비율(로그)
float log_height = Mathf.Log(screen.y / reference.y, 2f); // 높이 비율(로그)
return Mathf.Pow(2f, Mathf.Lerp(log_width, log_height, match));
}
}
Awake 에서 Canvas Scaler 의 네 값을 코드로 넣습니다. 인스펙터에서 같은 값을 골라도 되지만, 씬이 여러 개일 때 Canvas 마다 손으로 맞추다 하나를 빠뜨리는 일을 줄여 줍니다. LateUpdate 는 화면 크기가 바뀐 프레임에만 Show_Info 를 불러, Canvas Scaler 가 그 프레임의 배율을 넣은 뒤의 scaleFactor(실제 픽셀 ÷ UI 단위)와 Canvas 자신의 크기(UI 단위로 본 화면 크기)를 보여 줍니다. Update 에 두면 Canvas Scaler 보다 먼저 돌 수 있어 바뀌기 전 값이 남습니다.
Calc_Scale 은 Match Width or Height 모드에서 배율이 정해지는 식입니다. 너비 비율과 높이 비율을 로그로 바꿔 Match 값만큼 섞은 뒤 되돌립니다. Match 0 이면 「화면 너비 ÷ 기준 너비」, 1 이면 「화면 높이 ÷ 기준 높이」 가 그대로 배율이 됩니다. 이 식으로 낸 값이 Unity 가 실제로 넣은 scaleFactor 와 같은지 확인했습니다(3절).
이 스크립트는 Unity 6000.6.3f1 에서 컴파일 오류 없이 들어갔고, 배치 모드에서 Awake · LateUpdate 를 불러도 예외가 없었습니다. 배치 모드는 화면이 640 x 480 하나뿐이라 실제 폰에서 띄워 보지는 못했고, 다른 기기 해상도는 Calc_Scale 로 계산했습니다.
변수(variable)
reference_resolution(Vector2) : UI 를 그린 기준 해상도
match(float) : 너비(0)와 높이(1) 중 어디에 맞출지
text_info(TMP_Text) : 지금 값을 띄울 글자
canvas_scaler(CanvasScaler) : 같은 오브젝트의 Canvas Scaler
canvas(Canvas) : 같은 오브젝트의 Canvas
last_width · last_height(int) : 지난번에 본 화면 크기
함수(function)
Awake : Canvas Scaler 를 Scale With Screen Size · 기준 해상도 · Match 로 맞춥니다.
LateUpdate : 화면 크기가 바뀐 때만 Show_Info 를 부릅니다.
Show_Info : 화면 크기 · 배율 · UI 크기를 글자로 띄웁니다.
Calc_Scale : 화면 · 기준 해상도 · Match 로 배율을 계산합니다.
3. 기기마다 UI 가 잡히는 크기

먼저 배치 모드 화면(640 x 480)에서 Unity 가 넣은 scaleFactor 를 읽어 보니 Match 0 은 0.5926, 0.5 는 0.3849, 1 은 0.2500 이었고, Calc_Scale 로 낸 값과 소수 넷째 자리까지 같았습니다. Expand 는 너비 · 높이 비율 중 작은 쪽(0.25), Shrink 는 큰 쪽(0.5926)과 같았습니다.
그 식으로 기준 1080 x 1920 을 여러 기기에 넣어 보면, 1080 x 1920 · 720 x 1280 처럼 비율이 같은 화면은 Match 와 상관없이 UI 크기가 1080 x 1920 그대로입니다. 차이는 비율이 다를 때 납니다. 요즘 폰처럼 더 길쭉한 1080 x 2400 에서 Match 1(높이)이면 UI 너비가 864 로 줄어, 1080 폭으로 그린 UI 의 양옆이 잘립니다. Match 0(너비)이면 1080 x 2400 이 되어 너비는 그대로이고 위아래로 공간이 늘어납니다. 반대로 더 넓적한 태블릿 2048 x 2732 에서 Match 0 이면 UI 높이가 1441 로 줄어 1920 높이로 그린 UI 의 위아래가 잘리고, Match 1 이면 1439 x 1920 으로 옆이 남습니다.
4. 어느 화면이든 기준이 다 들어가게 — Expand
canvas_scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.Expand; // 기준보다 작아지지 않음
canvas_scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.Shrink; // 기준보다 커지지 않음
Match 값 하나로는 길쭉한 폰과 넓적한 태블릿을 둘 다 잘리지 않게 맞출 수 없습니다. Screen Match Mode 를 Expand 로 두면 Unity 문서대로 Canvas 크기가 기준보다 작아지지 않게 너비나 높이 중 한쪽을 늘립니다. 계산해 보면 1080 x 2400 폰은 1080 x 2400(너비에 맞춤), 2048 x 2732 태블릿은 1439 x 1920(높이에 맞춤)이 되어, 1080 x 1920 으로 그린 UI 가 어느 쪽에서도 잘리지 않습니다. 늘어난 공간은 버튼들을 화면 가장자리 앵커에 붙여 두면 자연스럽게 벌어집니다. Shrink 는 반대로 기준보다 커지지 않게 한쪽을 잘라 냅니다.
5. 안 될 때 — 자주 하는 실수
폰에서 UI 가 깨알처럼 작다
UI Scale Mode 가 기본값 Constant Pixel Size 로 남아 있으면 UI 를 화면 픽셀 그대로 그립니다. 에디터 Game 창이 작은 해상도였다면 해상도가 높은 폰에서는 같은 UI 가 훨씬 작게 보입니다. Scale With Screen Size 로 바꿉니다.
폰에서 양옆이 잘린다
세로 게임인데 Match 를 1(높이)로 두면 기준보다 길쭉한 폰에서 UI 너비가 줄어듭니다(1080 x 2400 에서 864). 세로 게임에서 길쭉한 폰만 본다면 Match 0, 태블릿까지 함께 맞추려면 Expand 를 씁니다.
태블릿에서 위아래가 잘린다
Match 0 으로 맞춘 세로 게임을 태블릿에서 켜면 UI 높이가 기준보다 짧아집니다(2048 x 2732 에서 1441). 화면 위 · 아래 끝에 붙은 버튼이 사라지면 Expand 로 바꾸거나 태블릿 화면도 Game 창에 추가해 확인합니다.
배율은 맞는데 노치에 버튼이 가린다
Canvas Scaler 는 크기만 맞출 뿐, 노치나 둥근 모서리는 피하지 않습니다. 그 부분은 Screen.safeArea 로 따로 줄여야 합니다.
함께 보기: 노치 · 둥근 모서리를 피하는 법은 유니티 노치 화면 대응 · 안전 영역 (Screen.safeArea) 에 있습니다.
Canvas Scaler 동작은 Unity 공식 문서 Canvas Scaler 와 Unity 6000.6.3f1 에디터(Windows)에서 값을 넣어 본 결과를 기준으로 적었습니다.
'Unity3D > C#' 카테고리의 다른 글
| 유니티 Scroll View 맨 아래로 자동 스크롤 (ScrollRect verticalNormalizedPosition) (0) | 2026.11.04 |
|---|---|
| 유니티 코루틴으로 몇 초 뒤 실행 (WaitForSeconds, StopCoroutine) (0) | 2026.11.03 |
| 유니티 씬 전환 · 로딩 바 (SceneManager.LoadScene, LoadSceneAsync) (0) | 2026.11.02 |
| 유니티 노치 화면 대응 · 안전 영역 (Screen.safeArea) (0) | 2026.10.31 |
| 유니티 안드로이드 뒤로가기 · 앱 종료 (KeyCode.Escape) (0) | 2026.10.30 |