---
title: "UI Toolkit 은 화면에 오브젝트를 놓지 않는다"
description: "유니티에는 UI 를 만드는 체계가 둘 있고, 이 시리즈가 열여섯 편 동안 다룬 것은 그중 하나입니다. 다른 하나는 어디에 무엇을 놓는지부터 다릅니다. 무엇이 되고 무엇이 안 되는지, 유니티가 어느 쪽을 권하는지, 그리고 시안을 넘기는 쪽에서 무엇이 달라지는지를 봅니다."
author: "유니얼"
pubDate: 2026-09-17
category: "game-dev/unity/ui"
tags: ["Unity", "UI", "uGUI", "UI Toolkit"]
canonical: https://blog.unialgames.com/posts/unity-ui-toolkit-vs-ugui/
---
지금까지 열여섯 편은 전부 한 가지 체계 이야기였습니다.

유니티에는 게임 화면 UI 를 만드는 방법이 둘 있습니다. 이름이 **uGUI** 와 **UI Toolkit** 입니다. 둘은 같은 것의 옛 버전과 새 버전이 아니라, 서로 다른 방식으로 만들어진 별개의 체계입니다.

그래서 시안을 넘기기 전에 물어봐야 할 것이 하나 늘어납니다. **이 화면은 어느 쪽으로 만드나요.**

## 지금까지 본 것은 uGUI 입니다

Canvas, RectTransform, 앵커와 피벗, Image, Text, Button, Layout Group. 이 시리즈가 다룬 이름은 전부 uGUI 쪽입니다. 정식 이름은 Unity UI 고, 보통 uGUI 라고 부릅니다.

핵심은 한 줄입니다. **요소 하나가 하이어라키의 오브젝트 하나**입니다.

버튼 하나가 배경 그림 오브젝트와 글자 오브젝트를 자식으로 가진 오브젝트 묶음이라는 이야기를 [입력창은 컴포넌트 하나가 아니라 오브젝트 묶음이다](/posts/unity-ui-input-field/)와 [원본을 고치면 전부 따라오는데, 손댄 것만 안 따라온다](/posts/unity-ui-prefab-handoff/)에서 했습니다. 그게 uGUI 의 전제입니다.

그 전제에서 많은 것이 따라 나옵니다. 오브젝트라서 프리팹이 되고, 오브젝트라서 애니메이션 클립이 붙고, 오브젝트라서 씬에서 눈으로 끌어다 놓을 수 있습니다.

## UI Toolkit 은 화면에 오브젝트를 놓지 않습니다

UI Toolkit 은 그 전제를 버립니다. 버튼도 글자도 배경도 **하이어라키에 없습니다.**

<x-tabs>
<figure class="diagram" data-tab="uGUI: 하이어라키에 오브젝트">
<svg viewBox="0 0 680 262" role="img" aria-label="uGUI 에서는 버튼 하나가 하이어라키의 오브젝트 묶음이다">
<text x="40" y="30" font-size="13" fill="var(--text)">버튼 하나를 만들면</text>
<text x="50" y="58" font-size="11.5" fill="var(--accent2)">Hierarchy</text>
<rect x="40" y="66" width="290" height="132" rx="8" fill="var(--bg-subtle)" stroke="var(--border)"></rect>
<text x="56" y="90" font-size="11.5" fill="var(--text)" font-family="var(--font-mono)">Canvas</text>
<text x="72" y="114" font-size="11.5" fill="var(--text)" font-family="var(--font-mono)">Popup_Reward</text>
<text x="88" y="138" font-size="11.5" fill="var(--text)" font-family="var(--font-mono)">Btn_Confirm</text>
<text x="104" y="162" font-size="11.5" fill="var(--text)" font-family="var(--font-mono)">Img_BG</text>
<text x="104" y="186" font-size="11.5" fill="var(--text)" font-family="var(--font-mono)">Txt_Label</text>
<text x="370" y="58" font-size="11.5" fill="var(--accent)">Scene 뷰</text>
<rect x="360" y="66" width="280" height="132" rx="8" fill="var(--bg-subtle)" stroke="var(--border)"></rect>
<rect x="440" y="115" width="120" height="34" rx="7" fill="var(--accent)" fill-opacity="0.2" stroke="var(--accent)"></rect>
<text x="500" y="137" font-size="12" fill="var(--text)" text-anchor="middle">확인</text>
<text x="40" y="226" font-size="12" fill="var(--text)">요소 하나가 오브젝트 하나입니다. 그래서 프리팹이 되고, 애니메이션 클립이 붙고,</text>
<text x="40" y="248" font-size="12" fill="var(--text)">인스펙터에서 버튼에 함수를 끌어다 연결할 수 있습니다.</text>
</svg>
<figcaption>눈에 보이는 모든 조각이 하이어라키에 있습니다.</figcaption>
</figure>
<figure class="diagram" data-tab="UI Toolkit: 파일 두 개">
<svg viewBox="0 0 680 262" role="img" aria-label="UI Toolkit 에서는 구조와 스타일이 파일로 있고 하이어라키에는 문서를 붙인 오브젝트 하나뿐이다">
<text x="40" y="30" font-size="13" fill="var(--text)">같은 버튼을 만들면</text>
<text x="50" y="58" font-size="11.5" fill="var(--accent2)">Project 창 (파일)</text>
<rect x="40" y="66" width="290" height="132" rx="8" fill="var(--bg-subtle)" stroke="var(--border)"></rect>
<rect x="56" y="82" width="258" height="46" rx="6" fill="var(--accent2)" fill-opacity="0.14" stroke="var(--accent2)"></rect>
<text x="70" y="102" font-size="11.5" fill="var(--text)" font-family="var(--font-mono)">Popup.uxml</text>
<text x="70" y="119" font-size="10.5" fill="var(--text-muted)">무엇이 어떤 순서로 있는지</text>
<rect x="56" y="140" width="258" height="46" rx="6" fill="var(--accent2)" fill-opacity="0.14" stroke="var(--accent2)"></rect>
<text x="70" y="160" font-size="11.5" fill="var(--text)" font-family="var(--font-mono)">Popup.uss</text>
<text x="70" y="177" font-size="10.5" fill="var(--text-muted)">어떤 모양으로 보일지</text>
<text x="370" y="58" font-size="11.5" fill="var(--accent)">UI Builder 창</text>
<rect x="360" y="66" width="280" height="132" rx="8" fill="var(--bg-subtle)" stroke="var(--border)"></rect>
<rect x="440" y="115" width="120" height="34" rx="7" fill="var(--accent)" fill-opacity="0.2" stroke="var(--accent)"></rect>
<text x="500" y="137" font-size="12" fill="var(--text)" text-anchor="middle">확인</text>
<text x="40" y="226" font-size="12" fill="var(--text)">하이어라키에는 그 문서를 붙인 오브젝트 하나뿐입니다(UI Document).</text>
<text x="40" y="248" font-size="12" fill="var(--warn)">버튼도 글자도 배경도 하이어라키에 안 보입니다. 파일 안에 있습니다.</text>
</svg>
<figcaption>씬이 아니라 파일에 씁니다. 웹의 HTML 과 CSS 가 있는 자리입니다.</figcaption>
</figure>
</x-tabs>

대신 파일 두 종류에 씁니다.

- **`.uxml`**: 무엇이 어떤 순서로 들어 있는지. 웹의 HTML 자리입니다
- **`.uss`**: 그것들이 어떤 모양으로 보일지. 웹의 CSS 자리입니다

만드는 도구는 **UI Builder** 입니다. 유니티 문서 표현으로 "a visual authoring tool to create and edit UI Toolkit assets such as UXML and USS files" 입니다. 창 안에서 끌어다 놓으면 그게 `.uxml` 과 `.uss` 로 저장됩니다.

화면에 띄울 때는 오브젝트 하나에 **UI Document** 컴포넌트를 붙이고 거기에 `.uxml` 파일을 물립니다. 하이어라키에 남는 것은 그 오브젝트 하나뿐입니다.

이 차이 하나에서 나머지가 거의 다 나옵니다. 씬에 오브젝트가 없으니 **씬에서 눈으로 배치할 수 없고**, 오브젝트가 없으니 **프리팹으로 만들 수 없고**, 오브젝트가 없으니 **애니메이션 클립을 붙일 수 없습니다.**

## 줄 세우는 방식도 다릅니다

uGUI 에서 자리를 정하는 것은 앵커와 피벗이었습니다([앵커는 화면이 늘어날 때 어디에 붙어 있을지 정한다](/posts/unity-ui-rect-transform-anchor/)). 줄을 세우는 것은 Layout Group 이었고요([Layout Group 은 칸을 먼저 나누고 그 안에 자식을 놓는다](/posts/unity-ui-layout-group/)).

UI Toolkit 은 웹과 같은 계열을 씁니다. 유니티 문서가 "implements a subset of Flexbox, a HTML/CSS layout system" 이라고 적어 둔 그것입니다. 요소를 한 줄에 쌓고, 남는 자리를 나눠 갖고, 넘치면 접는 방식입니다.

다만 기본값 하나가 반대입니다.

<figure class="diagram">
<svg viewBox="0 0 680 236" role="img" aria-label="웹 CSS 의 기본 방향은 가로이고 UI Toolkit 의 기본 방향은 세로다">
<text x="160" y="34" font-size="12.5" fill="var(--text-muted)" text-anchor="middle">웹 CSS 의 기본</text>
<text x="500" y="34" font-size="12.5" fill="var(--accent)" text-anchor="middle">UI Toolkit 의 기본</text>
<rect x="40" y="48" width="240" height="120" rx="8" fill="var(--bg-subtle)" stroke="var(--border)"></rect>
<rect x="58" y="70" width="64" height="76" rx="5" fill="var(--border)" fill-opacity="0.35" stroke="var(--border)"></rect>
<text x="90" y="112" font-size="12" fill="var(--text)" text-anchor="middle">1</text>
<rect x="130" y="70" width="64" height="76" rx="5" fill="var(--border)" fill-opacity="0.35" stroke="var(--border)"></rect>
<text x="162" y="112" font-size="12" fill="var(--text)" text-anchor="middle">2</text>
<rect x="202" y="70" width="64" height="76" rx="5" fill="var(--border)" fill-opacity="0.35" stroke="var(--border)"></rect>
<text x="234" y="112" font-size="12" fill="var(--text)" text-anchor="middle">3</text>
<text x="160" y="188" font-size="11.5" fill="var(--text-muted)" text-anchor="middle" font-family="var(--font-mono)">row (가로로 쌓임)</text>
<rect x="380" y="48" width="240" height="120" rx="8" fill="var(--bg-subtle)" stroke="var(--accent)"></rect>
<rect x="400" y="60" width="200" height="28" rx="5" fill="var(--accent)" fill-opacity="0.2" stroke="var(--accent)"></rect>
<text x="500" y="79" font-size="12" fill="var(--text)" text-anchor="middle">1</text>
<rect x="400" y="96" width="200" height="28" rx="5" fill="var(--accent)" fill-opacity="0.2" stroke="var(--accent)"></rect>
<text x="500" y="115" font-size="12" fill="var(--text)" text-anchor="middle">2</text>
<rect x="400" y="132" width="200" height="28" rx="5" fill="var(--accent)" fill-opacity="0.2" stroke="var(--accent)"></rect>
<text x="500" y="151" font-size="12" fill="var(--text)" text-anchor="middle">3</text>
<text x="500" y="188" font-size="11.5" fill="var(--accent)" text-anchor="middle" font-family="var(--font-mono)">column (세로로 쌓임)</text>
<text x="40" y="218" font-size="12" fill="var(--text)">같은 규칙을 쓰는데 기본값이 반대입니다. 웹을 하다 온 사람이 가장 자주 걸리는 자리입니다.</text>
</svg>
<figcaption>레이아웃 규칙은 웹과 같은 계열이지만 쌓이는 기본 방향이 다릅니다.</figcaption>
</figure>

문서가 붙여 둔 단서도 하나 있습니다. 자리를 좌표로 직접 찍는 Absolute 모드에 대해 **"Avoid to use Absolute position mode because it bypasses the built-in layout engine"** 이라고 적혀 있습니다. 유니티 쪽에서도 쌓는 방식으로 짜기를 권한다는 뜻입니다.

시안 쪽에서 보면 이건 나쁜 소식이 아닙니다. **오토 레이아웃으로 짜 둔 시안이 그대로 맞아떨어지는 쪽**이 UI Toolkit 입니다. 좌표로 절대 배치한 시안은 오히려 옮기기가 번거로워집니다.

## 무엇이 되고 무엇이 안 되는가

유니티가 공식 비교표를 내놓고 있습니다. 시안을 넘기는 쪽에 영향을 주는 줄만 뽑았습니다.

| | uGUI | UI Toolkit |
| --- | --- | --- |
| 씬에서 눈으로 배치 | 됩니다 | 안 됩니다 |
| 애니메이션 클립과 타임라인 | 됩니다 | 안 됩니다 |
| 인스펙터에서 버튼에 동작 연결 | 됩니다 | 안 됩니다 |
| 벡터(SVG) | 안 됩니다 | 됩니다 |
| 스타일로 거는 전환 애니메이션 | 안 됩니다 | 됩니다 |
| 데이터 바인딩 | 안 됩니다 | 됩니다 |
| 월드 공간(3D 안에 붙는 UI) | 됩니다 | 됩니다 |
| 커스텀 셰이더와 머티리얼 | 됩니다 | 됩니다 |

읽을 때 주의할 것이 하나 있습니다. 이 표는 **지금 이 시점의 표**입니다. 유니티 문서가 이렇게 적어 뒀습니다.

> UI Toolkit is in active development and releases new features frequently. uGUI and IMGUI are established and production-proven UI systems that are updated infrequently.

한쪽은 계속 늘어나는 중이고 한쪽은 자리를 잡은 상태입니다. 그래서 "안 됩니다" 칸은 시간이 지나면 바뀔 수 있고, 반대로 "됩니다" 쪽은 오래 그대로일 가능성이 높습니다.

## 유니티가 권하는 쪽

같은 문서가 권장을 적어 두고 있습니다. 새로 나온 쪽이 자동으로 기본이 되는 것은 아닙니다.

- **게임 화면(런타임)**: uGUI 를 권하고, UI Toolkit 을 대안으로 둡니다
- **에디터 도구 화면**: UI Toolkit 을 권하고, IMGUI 를 대안으로 둡니다

에디터 도구는 개발자가 쓰는 창이라 이 시리즈와는 상관이 없습니다. 게임 화면 쪽만 보면 **아직은 uGUI 가 기본**입니다.

문서가 UI Toolkit 쪽이 낫다고 드는 자리는 이렇습니다.

- **해상도가 많이 갈리는 메뉴와 HUD**, 그리고 UI 가 많은 프로젝트
- **월드 공간 UI 와 VR**
- 커스텀 셰이더와 머티리얼을 많이 쓰는 경우

반대로 uGUI 쪽이 낫다고 드는 자리는 **키프레임으로 찍은 애니메이션**입니다. 연출을 클립으로 만들어 두는 작업 방식이면 그쪽입니다.

실무 판단은 대체로 단순합니다.

- 이미 uGUI 로 절반쯤 만들어 둔 프로젝트에 굳이 섞지 않습니다. 두 체계를 한 화면에서 겹치게 쓰면 어느 쪽이 위인지 정하는 일부터 번거로워집니다
- 새로 시작하고, 화면이 많고, 연출이 적고, 해상도가 많이 갈린다면 UI Toolkit 도 후보가 됩니다
- 연출이 많고 3D 와 UI 가 섞여 있으면 uGUI 쪽이 안전합니다

## 시안을 넘기는 쪽에서 달라지는 것

어느 쪽이냐에 따라 넘기는 것이 달라집니다.

- **그림 파일.** uGUI 는 벡터를 그대로 못 받아서 PNG 로 뽑아야 합니다. UI Toolkit 은 SVG 를 받습니다. 배수와 9-slice 경계를 적는 규칙은 어느 쪽이든 같습니다
- **이름.** uGUI 에서는 레이어 이름이 하이어라키의 오브젝트 이름이 됐습니다. UI Toolkit 에서는 **스타일을 걸 이름**이 됩니다. 웹에서 클래스 이름을 붙이는 것과 같은 자리라, 같은 모양이 여러 군데 나오면 그 묶음에 이름 하나를 주는 편이 좋습니다
- **연출.** 클립이 없으니 "이 팝업 인트로를 프레임으로 찍어 뒀습니다" 가 안 통합니다. 대신 "이 상태에서 저 상태로 0.2초, Ease Out" 처럼 **시작과 끝과 시간**으로 적어 주시면 그대로 됩니다([Animator 는 붙어 있는 동안 계속 일한다](/posts/unity-ui-animation/)에서 적은 방식 그대로입니다)
- **배치.** 좌표로 절대 배치한 시안보다 **오토 레이아웃으로 짠 시안**이 그대로 옮겨집니다

그래서 시안 파일 맨 앞에 한 줄이면 됩니다. **이 화면은 어느 쪽으로 만드나요.** 그 한 줄이 위의 네 가지를 한꺼번에 정합니다.

## 시안을 넘길 때 적어 주면 좋은 것

| 항목 | 적어 줄 것 |
| --- | --- |
| 어느 쪽 | 이 화면을 uGUI 로 만드는지 UI Toolkit 으로 만드는지 |
| 그림 | uGUI 면 PNG, UI Toolkit 이면 SVG 도 가능. 배수와 9-slice 는 어느 쪽이든 |
| 이름 | 같은 모양이 여러 군데 나오면 그 묶음에 이름 하나 |
| 배치 | 좌표로 찍었는지, 오토 레이아웃으로 쌓았는지 |
| 연출 | 프레임으로 찍은 것인지, 시작·끝·시간으로 적을 수 있는 것인지 |
| 섞임 | 한 화면에 두 체계가 겹치는 자리가 있는지 |

## 정리

- 유니티에는 게임 화면 UI 체계가 둘 있습니다. **uGUI** 와 **UI Toolkit** 이고, 이 시리즈가 다룬 것은 uGUI 입니다
- uGUI 는 **요소 하나가 오브젝트 하나**입니다. 그래서 프리팹이 되고 클립이 붙고 씬에서 눈으로 배치합니다
- UI Toolkit 은 구조를 `.uxml`, 스타일을 `.uss` 파일에 씁니다. 하이어라키에는 문서를 붙인 오브젝트 하나뿐입니다
- 그 차이에서 나머지가 나옵니다. 씬 배치·프리팹·애니메이션 클립이 안 되고, 벡터와 스타일 전환과 데이터 바인딩이 됩니다
- 줄 세우는 방식은 웹과 같은 계열인데 **쌓이는 기본 방향이 세로**입니다
- 유니티는 지금도 **게임 화면에는 uGUI 를, 에디터 도구에는 UI Toolkit 을** 권합니다
- 시안 쪽에서는 그림 형식, 이름의 성격, 연출을 적는 방법, 배치 방식이 달라집니다. 그래서 **어느 쪽으로 만드는지** 한 줄이 먼저입니다