UI
31편
클릭은 콜라이더가 받고 UI 는 월드에 놓여 있다
NGUI 의 버튼에는 콜라이더가 붙어 있고, UICamera 가 물리 레이캐스트로 그걸 맞힙니다. 가까운 것이 아니라 앞에 있는 것이 이기는 이유, SendMessage 로 오는 알림, UIRoot 가 루트를 2/화면높이로 축소해 두는 좌표계까지 소스에서 확인했습니다.
그리는 순서는 하이어라키가 아니라 숫자가 정한다
NGUI 는 위젯마다 depth 정수를 들고 그 숫자로 앞뒤를 정합니다. 오브젝트를 옮겨도 순서가 안 바뀌는 대신 숫자를 관리해야 합니다. 판과 위젯의 두 단계 정렬, 같은 숫자를 줬을 때의 재질 묶기, 그 숫자 배치가 드로우 콜을 가르는 과정까지 소스에서 확인했습니다.
uGUI 는 NGUI 에서 시작했다
유니티에 런타임 UI 가 없던 시절에 그 자리를 채운 것이 NGUI 입니다. 2025년 10월에 MIT 로 풀린 저장소를 열어 보면서, 무엇이 한 상자에 들어 있었는지와 유니티 UI 와 크게 갈리는 지점을 정리했습니다.
목록은 보이는 만큼만 만든다
ListView 는 항목이 천 개여도 요소를 열몇 개만 만들고 돌려 씁니다. makeItem 과 bindItem 이 갈려 있는 이유, 높이를 아느냐가 가르는 두 가지 가상화 방식, Rebuild 와 RefreshItems 의 차이, 그리고 안 되는 것까지 정리했습니다.
판을 화면이 아니라 씬에 놓는다
Panel Settings 의 render mode 를 World Space 로 바꾸면 UI 판이 씬 안의 오브젝트가 됩니다. Pixels Per Unit 으로 크기를 정하고, 기준점을 아홉 자리 중에 고르고, 카메라와의 거리로 순서가 정해지고, 입력은 물리 레이로 갑니다.
한 배치에 텍스처 여덟 장까지다
UI Toolkit 의 우버 셰이더는 한 배치에 텍스처 여덟 장을 받습니다. 그 한도와 배치가 깨지는 조건, Vertex Budget, 사각 마스크와 스텐실 마스크가 갈리는 지점, 오버드로와 메모리까지 공식 문서에서 확인해 정리했습니다.
무엇이 다시 계산되는지가 네 가지로 나뉜다
uGUI 는 한 칸이 바뀌면 캔버스가 통째로 다시 계산됐습니다. UI Toolkit 은 스타일 해석·레이아웃·정점 버퍼·렌더 상태 넷으로 갈립니다. 바꾼 값마다 어디까지 번지는지, 숨기는 방법 셋의 비용, UsageHints, 바인딩의 리플렉션 비용까지 정리했습니다.
내가 만든 요소도 UXML 에 태그로 들어간다
같은 묶음이 화면마다 반복되면 묶습니다. uxml 템플릿으로 다시 쓰는 방법과 C# 으로 요소를 만드는 방법, UxmlElement 와 UxmlAttribute, 옛 UxmlFactory 방식과의 차이, 에디터 창까지 정리했습니다.
움직임은 클립이 아니라 두 값 사이에서 만들어진다
UI Toolkit 에는 Animator 도 클립도 안 붙습니다. uss 에 한 줄 적어 두면 값이 바뀔 때 이어서 갑니다. 전환을 어디에 걸어야 배치가 안 다시 잡히는지, 전환 이벤트, 그리고 값이 바뀌면 화면이 따라오게 하는 데이터 바인딩까지 정리했습니다.
이벤트는 루트에서 내려갔다가 다시 올라온다
UI Toolkit 에는 인스펙터의 On Click 칸이 없습니다. 콜백을 코드로만 거는 대신 이벤트가 트리를 두 번 지나갑니다. 내려가는 길과 올라오는 길, 막는 방법, pickingMode, 포커스까지 정리했습니다.
해상도 대응은 씬이 아니라 에셋 한 장에 적힌다
UI Toolkit 의 Panel Settings 는 Canvas Scaler 와 하는 일이 거의 같은데 있는 자리가 다릅니다. 배율 방식 세 가지, Match 값, Sort Order 로 정하는 패널 순서, Render Texture, Safe Area 가 없다는 것까지 정리했습니다.
칸은 남는 자리를 나눠 갖는 방식으로 정해진다
UI Toolkit 에는 앵커도 피벗도 없습니다. 자리는 부모가 정하고 자식은 쌓입니다. 기본 방향이 column 인 것, flex-grow 로 남는 자리를 나누는 것, 주축과 교차축, absolute 를 언제만 쓰는지, 숨기는 방법 두 가지를 정리했습니다.
이름을 붙여야 스타일을 걸 수 있다
UI Toolkit 에서 모양은 요소에 붙지 않고 선택자에 붙습니다. 타입, 이름, 클래스, 전체 네 가지로 부르는 방법과
화면 하나가 파일 두 개와 오브젝트 하나가 된다
UI Toolkit 으로 화면을 만들면 무엇이 어디에 생기는지부터 봅니다. uxml 과 uss 가 각각 무엇을 적는 파일인지, VisualElement 가 uGUI 의 무엇 자리인지, UI Document 와 Panel Settings 가 왜 따로 있는지를 정리했습니다.
UI Toolkit 은 화면에 오브젝트를 놓지 않는다
유니티에는 UI 를 만드는 체계가 둘 있고, 이 시리즈가 열여섯 편 동안 다룬 것은 그중 하나입니다. 다른 하나는 어디에 무엇을 놓는지부터 다릅니다. 무엇이 되고 무엇이 안 되는지, 유니티가 어느 쪽을 권하는지, 그리고 시안을 넘기는 쪽에서 무엇이 달라지는지를 봅니다.
원본을 고치면 전부 따라오는데, 손댄 것만 안 따라온다
프리팹이 무엇이고 무엇을 어떻게 프리팹으로 만드는지부터 봅니다. 한 번 손댄 값이 왜 원본 수정을 빗나가는지, 시안의 Variant 와 무엇이 다른지, 레이어 이름과 그림 파일을 어떻게 넘겨야 하는지를 정리했습니다.
짧은 글자일수록 번역에서 더 길어진다
언어가 바뀌면 글자 길이가 바뀌고 한국어에 맞춰 잡은 칸이 깨집니다. 얼마나 늘어나는지, 폰트에 없는 글자는 어떻게 되는지, 오른쪽에서 왼쪽으로 읽는 언어에서 화면이 어떻게 뒤집히는지를 봅니다.
한 칸이 바뀌면 그 캔버스는 통째로 다시 계산된다
UI 가 무거워지는 자리는 그림의 퀄리티가 아니라 쌓아 둔 구조입니다. 캔버스 경계가 무엇까지 막아 주는지, 겹침이 어디서 묶음을 끊는지, 그리고 중첩 레이아웃 그룹과 오버드로우를 봅니다.
Animator 는 붙어 있는 동안 계속 일한다
UI 를 움직이는 방법은 애니메이션 클립과 코드 두 갈래입니다. Animator 가 매 프레임 하는 일, 무엇을 움직이면 무엇이 다시 도는지, 시안에서 시간과 이징을 어떻게 넘기는지를 그림으로 봅니다.
눌리는 것은 전부 같은 상태 다섯 개를 쓴다
시안의 버튼은 보통 기본과 눌림 두 장이지만 Unity 는 다섯 상태를 요구합니다. 상태와 전환 방식, 무엇이 클릭을 먹는지, 그룹 전체를 못 누르게 막는 법, 최소 터치 크기를 그림으로 봅니다.
반투명이 시안보다 밝게 나오면 색 공간 문제다
같은 색과 같은 알파인데 Unity 화면에서 다르게 보이는 이유는 색을 섞는 자리가 다르기 때문입니다. 색 공간, 그라데이션 중간 색, 없는 블렌드 모드, 정점을 복제하는 외곽선까지 그림으로 봅니다.
동적으로 채우는 글자는 본 만큼 램에 쌓인다
채팅이나 유저 이름처럼 나올 글자를 미리 알 수 없는 화면은 글자를 실행 중에 굽습니다. 한글과 중국어에서 그 텍스처가 얼마나 커지는지, 왜 채팅만 Text 기반 컴포넌트로 만드는지를 그림으로 봅니다.
입력창은 컴포넌트 하나가 아니라 오브젝트 묶음이다
시안의 입력창은 사각형 하나지만 Unity 에서는 배경, 안내 문구, 입력 글자, 커서가 각각 따로입니다. 구조와 인스펙터 값, Content Type, 글자 수 제한, 모바일 키보드까지 그림으로 봅니다.
크기가 고정이고 꾸밈이 없으면 일반 Text 로 충분하다
Unity 의 글자 컴포넌트는 둘입니다. 일반 Text 가 하는 일과 없는 기능, 폰트를 준비하는 방식의 차이, 그리고 어느 화면을 일반 Text 로 두고 어느 화면을 TextMeshPro 로 가져갈지를 그림으로 봅니다.
TextMeshPro 는 글자를 미리 그림으로 구워 둔다
한글은 영문과 글자 수부터 다릅니다. 폰트 에셋이 구워지는 방식, 외곽선과 그림자가 머티리얼인 이유, 자간과 행간의 기준 차이, 상자에 글이 안 들어갈 때 일어나는 일을 그림으로 봅니다.
버튼 이미지를 통째로 늘리면 모서리가 같이 늘어난다
버튼 배경 한 장을 여러 크기로 쓰려면 이미지를 아홉 조각으로 나눠야 합니다. Image Type 넷이 늘어나는 방식, 9-slice 경계, Pixels Per Unit, 색 곱하기, 투명 여백을 그림으로 봅니다.
스크롤 목록은 창문 뒤에서 긴 종이를 움직이는 것이다
인벤토리 같은 스크롤 목록을 칸(Grid Layout Group), 종이와 창(Scroll View), 가림막(Mask, RectMask2D) 세 부품으로 나눠, 칸이 꺾이는 규칙과 끝에서 튕기는 동작을 그림으로 봅니다.
Layout Group 은 칸을 먼저 나누고 그 안에 자식을 놓는다
Figma Auto Layout 과 닮았지만 규칙이 다릅니다. Control Child Size 와 Child Force Expand 가 버튼 모양을 어떻게 네 가지로 바꾸는지, 글에 맞춰 커지는 말풍선이 어떻게 만들어지는지 그림으로 봅니다.
Canvas Scaler 는 가로와 세로 중 한쪽만 지킨다
시안과 비율이 다른 화면에서는 가로와 세로를 동시에 맞출 수 없습니다. Match 값이 무엇을 지키고 무엇을 남기는지, 노치를 피하는 Safe Area 까지 봅니다.
앵커는 화면이 늘어날 때 어디에 붙어 있을지 정한다
같은 Pos X 60 이 앵커에 따라 왼쪽에서 60 이 되기도, 가운데에서 60 이 되기도 합니다. RectTransform 의 앵커와 피벗을 Figma 컨스트레인트와 나란히 놓고 봅니다.
하이어라키 맨 아래가 화면 맨 앞이다
Figma 레이어 패널과 Unity 하이어라키는 앞뒤를 반대 방향으로 셉니다. 캔버스가 무엇이고, 무엇이 앞에 그려지는지 정하는 규칙을 봅니다.