UI Toolkit 프라이머: 프로그래머처럼 UI 구축하기
요약
본 영상은 Unity의 UI Toolkit 프라이머리를 활용하여 프로그래밍 방식으로 사용자 인터페이스를 구축하는 방법을 소개합니다. 내장 그래픽 API, 트위닝/애니메이션 라이브러리 등을 사용하여 복잡한 시각화와 부드러운 애니메이션을 쉽게 구현할 수 있습니다. 또한 USS 스타일시트를 통해 전역적인 강조 색상 변경이나 호버 효과 추가가 매우 간편하며, 모든 작업이 실시간으로 이루어지는 점을 보여줍니다.
핵심 포인트
- UI Toolkit은 내장 그래픽 API와 트위닝/애니메이션 라이브러리를 제공합니다.
- USS 스타일시트를 사용해 CSS처럼 전역적인 스타일링 및 호버 효과를 쉽게 구현할 수 있습니다.
- 강조 변수(accent variable) 변경 등 전체 애플리케이션의 색상을 한 번에 수정 가능합니다.
- 모든 작업이 실시간으로 이루어져 재컴파일 과정 없이 즉각적인 피드백을 얻을 수 있습니다.
영상: UI Toolkit 프라이머 - 프로그래머처럼 UI 구축하기
채널: Tarodev
길이: 27분 54초
출처: 자막 (자동, 영어)
스크립트:
필드를 만들고 약 2.5초 동안 보여주는 것이 좋겠네요. 아니, 1.5초로 하겠습니다. 어, 로컬 부동 소수점 스케일링입니다. 안녕하세요. 원래 이 프로젝트는 이것이 무엇인지, 그리고 어떻게 만드는지를 보여주려는 의도로 시작했지만, 제가 너무 과하게 만들어서 이제 튜토리얼에서 보여주기에는 너무 커졌습니다. 그래서 이 프로젝트가 사용하는 UI Toolkit의 몇 가지 강력한 기능들을 보여드리고, 그 다음에는 좀 더 쉽고 기본적인 것들부터 가르쳐 드리면서 살펴보겠습니다.
첫 번째 멋진 기능은 통계용 레이더 차트를 시각화하는 데 제가 사용하는 내장 그래픽 API가 있다는 것입니다. 이 차트는 분포에 반응합니다. 본질적으로 베지어 선(Bezier lines)과 스케일, 그리고 채우기 모양을 그릴 수 있게 해줍니다. 화면에 표시하고 싶은 모든 데이터나 셀 수 없이 많은 퍼즐 게임에 완벽합니다. 이것이 내장되어 있다는 것이 놀랍습니다. 다음으로 UI Toolkit에는 트위닝/애니메이션을 위한 내장 라이브러리가 있습니다. 만약 prime twin이나 do tween, lane tween 같은 것을 사용해 본 적이 있다면, 객체를 가져와서 예를 들어 '움직여라'라고 말하고, 일정 시간 동안 부드러운 곡선으로 새로운 위치로 이동시킬 수 있다는 것을 아실 겁니다.
UI Toolkit에는 실제로 이것이 내장되어 있습니다. 예를 들어, 이 화면들 사이를 부드럽게 페이드 인/아웃 애니메이션하는 데 사용합니다. UI Toolkit은 스타일 시트(style sheets)를 사용하여 스타일링됩니다. 웹 개발을 해본 적이 있다면 CSS에 익숙하실 겁니다. Unity는 이것과 유사한 USS라는 것을 사용합니다. 그리고 또한 전체 범위의 전환 옵션을 제공합니다. 마우스를 올릴 때 색상이 페이드 인되는 이 미묘한 효과를 볼 수 있습니다. 여기에 좀 더 생동감을 추가하고 싶다면, 버튼 호버 스타일로 가서 '와, 줌 1.2' 같은 것을 말하는 것만큼 간단할 것입니다.
이렇게 간단한 효과를 얻었습니다. 단 한 줄의 코드로 이 호버(hover) 효과를 추가할 수 있었고, 정말 멋져 보입니다. 이전 시스템에서는 스크립트를 작성하거나 애니메이션을 만들어서 매번 호버할 때마다 실행해야 했습니다. 하지만 보시다시피 새 시스템에서는 훨씬 쉽습니다. 그리고 여러분이 알아차리셨을 수도 있는 점은, 돌아가서 스타일을 변경하고 다시 돌아와도 재컴파일(recompilation)이 필요 없다는 것입니다. 모든 것이 실시간으로 이루어집니다. 스타일 시트(style sheets)를 사용하면 또 다른 놀라운 기능이 있는데, 예를 들어 이 모든 컨트롤의 강조 색상(accent color)을 변경하고 싶다고 가정해 봅시다.
스타일 시트로 들어가서 우리의 강조 변수(accent variable)를 찾습니다. 아, 이건 제가 임의로 정한 변수 이름입니다. 원하는 어떤 것이든 선택할 수 있습니다. 음, 예쁜 분홍색으로 해보겠습니다. 그리고 여기 있습니다. 애플리케이션 전체에서 변경됩니다. 우리가 변수를 사용하는 모든 곳에서요. 이전에는 모든 프리팹(prefabs)에 들어가서 색상을 바꿔야 했을 수도 있습니다. 어쨌든, 잡담은 충분합니다. 실제로 무언가를 만들어 봅시다. 좋습니다. 제가 방금 보여드린 다른 앱만큼 흥미롭지는 않다는 것을 이해하지만, 인터페이스 도구 생성의 기본을 가르쳐 줄 것입니다.
그 후에 여러분은 단순히 자신만의 인터페이스를 만들기 시작할 수 있습니다. 그래서 화면 중앙에 실제 큐브(cube)가 있을 겁니다. 이런 뷰포트(viewport) 같은 것이 있고, 아래쪽에는 버튼과 슬라이더가 있는 또 다른 컨트롤 패널이 있을 것입니다. 이것으로 몇 가지 작은 기술들을 배우고 마지막에 애니메이션을 추가할 예정입니다. 만들기를 시작하려면 인터페이스 도구 상자에서 마우스 오른쪽 버튼을 클릭하고 인터페이스 문서(interface document)를 생성하기만 하면 됩니다. 인터페이스 문서는 이전 시스템의 캔버스(canvas)와 같은 역할을 합니다.
좋습니다. 인터페이스 툴킷을 사용하려면 Unity는 몇 가지 방법을 제공합니다. 제가 생각하기에 Unity가 실제로 권장하는 첫 번째 방법은 인터페이스 빌더(interface builder)입니다. 따라서 요소를 화면에 그냥 던지듯이 배치하면 됩니다. 시그니처와 버튼이 있습니다. 이것을 유지할 수 있습니다. 메인 메뉴라고 부르겠습니다. 그리고 우리의 인터페이스 문서에 메인 메뉴를 추가할 수 있습니다. 보시다시피 여기에 표시됩니다. 레이블이 약간 어둡습니다. 따라서 요소를 스타일링하는 방법은 여러 가지가 있습니다.
먼저, 레이블을 클릭하고 여기 텍스트로 가서 색상을 흰색으로 변경할 수 있습니다. 웹 개발을 해본 적이 있다면, 여기에 스타일을 지정하는 것은 인라인 스타일(inline styles)과 동일합니다. 급하게는 괜찮지만, 재사용성이 높지는 않습니다. 예를 들어, 여기에 다른 레이블을 추가하면, 그것도 인라인으로 스타일링해야 합니다. 따라서 이에 해당하는 방법은 여기 작은 선택자(selector)를 추가하는 것입니다. 이것이 제 버튼일 수 있습니다. 그리고 이것이 스타일시트(stylesheet)를 저장합니다. 이제 우리의 스타일시트에 작은 스타일이 생겼으니, 이 스타일을 클릭하여 빨간색으로 변경할 수 있습니다.
그런 다음 이 스타일을 레이블로 드래그할 수 있습니다. 그런데 작동하지 않았습니다. 왜냐하면 인라인 스타일은 또 다른 문제입니다. 기본 내장 스타일(Built-in styles)이 실제로 여러분의 스타일시트를 덮어쓰기 때문입니다. 그래서 저는 텍스트를 마우스 오른쪽 버튼으로 클릭하고 모든 설정 초기화(reset all settings)를 합니다. 이제 제 레이블이 빨간색인 것을 볼 수 있습니다. 따라서 여기에 다른 레이블을 가져와서, 제가 재사용할 스타일을 쉽게 드래그할 수 있습니다. 인터페이스를 만드는 또 다른 방법은 UMX를 직접 편집하는 것입니다. UMX는 사실 인터페이스 디자이너에 의해 생성되는 마크업 언어(markup language)와 같습니다. 그래서 이것을 열고 싶다면, 여기에 새 버튼을 추가하고, 제 새 버튼의 텍스트를 작성하면 여기에 나타날 것입니다.
이렇게도 할 수 있습니다. 전통적으로 저는 이 방식으로 인터페이스를 만들어 왔습니다. 만약 네이티브 개발을 하게 된다면, 보통은 인터페이스 빌더를 사용하지 않고 마크업(markup)을 직접 작성합니다. 왜냐하면 그것들이 조금 투박하다고 느끼기 때문입니다. 이 두 가지 방법에는 명확한 문제가 하나 있습니다. 사실 몇 가지가 있지만, 제 생각에 가장 큰 문제는 만약 제가 예를 들어 이 버튼에 어떤 로직을 연결하고 싶다면, 여기에 ID를 부여해야 한다는 것입니다. 그냥 '버튼 ID'라고 부르겠습니다. 저는 스크립트, 즉 메뉴 스크립트를 작성하고, 여기 인터페이스 문서를 직렬화(serialize)한다고 가정해 봅시다.
그러면 제 버튼을 이렇게 쿼리해야 합니다. 예를 들어 button = document ee와 같이 하고, 루트 비주얼 노드(root visual node)를 가져옵니다. 그리고 네, 이미 제가 무엇을 하려고 하는지 알고 있습니다. 하지만 제가 ID를 뭐라고 불렀죠? 이런 식으로요. 그래서 이제 여기 링크가 생겼지만, 이건 문자열(string) 링크입니다. 그래서 변경하기가 매우 쉽습니다. 그리고 이것이 존재하는지 아닌지를 알려주는 IntelliSense 기능도 없습니다. 벌써 꽤 무섭습니다. 이렇게 하면 프로그램이 상당히 취약해집니다. 누군가가 메뉴의 깊은 곳에 있는 스크립트를 수정하다가 실수로 단위(unit)를 넣거나 뭔가 할 수도 있습니다.
누가 알겠습니까? 하지만 이제 인터페이스가 깨져버립니다. 바라건대 이것이 실제로 깨졌다고 알려주는 일종의 단위 테스트(unit test)가 있겠지만, 그래도 조금은 부서지기 쉽습니다(brittle). 그리고 UI 툴킷의 공식 샘플 프로젝트를 열어보면, 그들이 검색에 너무 많은 문자열을 사용한다는 것을 알 수 있습니다. 단지 한 화면일 뿐이죠? 약 20개의 화면이 있습니다. 모두가 문자열 검색을 사용합니다. 정말 매우 취약합니다. 그래서 프로그래머처럼 인터페이스를 만드는 방법을 보여드리겠습니다. 좋습니다. 실제 UI 문서 파일은 사용하지 않기 때문에 삭제했습니다.
그리고 스크립트를 만들겠습니다. '메인 메뉴 화면(main menu screen)'이라고 부르죠. 그리고 이 스크립트를 제가 UI 문서와 같은 오브젝트에 붙일 겁니다. 그리고 이것은 삭제하겠습니다. '생성 및 직렬화된 .Document'이라는 함수를 만들고, Start에서 generate()를 호출할 것입니다. 좋습니다. 그러니까 Document는 트리가 같은 거예요—요소들의 계층적 트리죠. 본질적으로 루트 노드가 있습니다. 그래서 이 루트 노드를 이렇게 가져갈 수 있어요: "document.rootVisual". 그리고 이것은 기본적으로 캔버스에 비유할 수 있는 것과 같아요. 무언가를 배치하기 시작할 수 있는 캔버스 오브젝트 같은 거죠.
좋아요, 그럼 제목 태그를 만드는 것부터 시작하겠습니다. 이렇게요. 그리고 여기에 'hello'라고 적을 것이고, "root.addTitleTag()"라고 말함으로써 인터페이스에 쉽게 추가할 수 있습니다. 이제 Unity에서 이 인터페이스 문서를 스크립트에 할당하고 플레이 버튼을 누르기만 하면 됩니다. 실제로 여기서 'hello'가 재현되는 것을 볼 수 있지만, 매우 보기 어렵습니다. 그래서 인터페이스 디자이너에 내장 스타일이 있었던 것처럼, 여기에서도 내장 스타일을 사용할 수 있습니다. 이렇게 할 수 있어요: titleLabelStyle = new ColorStyle(Color.white).
그리고 플레이를 누르면 정말 스타일링된 것을 말할 수 있겠죠. 하지만 말씀드렸듯이 인라인 스타일은 이런 작업을 수행하는 재사용성이 낮은 방법입니다. 그래서 여기에서 스타일시트를 만들겠습니다. '인터페이스 도구 스타일시트(interface tools stylesheet)'로 이동하겠습니다. 그리고 이것이 '메인 메뉴 스타일시트(main menu stylesheet)'가 될 겁니다. 그런 다음 스크립트에서 스타일시트를 직렬화하겠습니다. 그리고 루트 노드에서, 만약 이 영상 끝날 때까지 co-pilot에 의해 검증되지 않는다면 뭔가 잘못된 것이기 때문입니다. 솔직히 말해서 이건 제 머릿속의 co-pilot 같아요. 자, 이 스타일시트를 직렬화하고 열어봅시다.
만약 CSS를 사용해 본 적이 없다면 걱정하지 마세요. 세상에서 가장 간단한 것입니다. 예를 들어, 모든 라벨을 커스터마이징하고 싶다고 가정해 봅시다. 그러면 라벨을 선택자로 지정하고, 여기 색상을 빨간색으로 설정할 수 있습니다. 만약 빨간색이 아니라면요? 그건 여기에 기본 스타일이 있기 때문입니다. 그리고 아까 기억나시겠지만, 인라인 스타일(inline styles)은 표준 스타일보다 우선권을 갖는다고 말씀드렸습니다. 그러니 더 이상 인라인 스타일을 사용하고 싶지 않으니 그걸 제거해 봅시다. 재생 버튼을 누르면 빨간색이 나타납니다. 원한다면 다시 흰색으로 바꿀 수도 있습니다.
이게 다입니다. 좋습니다. 좀 더 해봅시다. 어, 빨간 사각형을 하나 만들겠습니다. 자, 빨간 사각형(red boy). 그리고 이걸 시각적 요소(visual element)로 만들어 봅시다. 시각적 요소는 일종의 컨테이너와 같습니다. 무엇이든 될 수 있습니다. 유니티(Unity)에서 빈 오브젝트 같은 것이죠? 그리고 루트에 빨간 사각형을 추가해 봅시다. 이제 스타일에서는 우리의 시각적 요소를 선택하고, 너비는 50, 높이는 50으로 지정하고 배경색을 빨간색으로 만들자고 말할 수 있습니다. 재생 버튼을 누릅니다. 자, 이렇게 됐습니다. 작은 시각적 요소가 생겼네요. 이제 파란 사각형을 만들어 봅시다.
파란 사각형(Blue boy). 그리고 이걸 대신 추가해 봅시다. 여기서 문제가 발생하는 건, 저는 이게 파란색이 되길 원하지만, 제가 타겟팅하는 것은 모든 것에 영향을 미치기 때문입니다. 그렇죠? 어떻게 해야 두 가지를 구별할 수 있을까요? 이건 클래스(classes)를 사용해서 처리됩니다. 자, 갑시다. 빨간 사각형에 클래스를 추가하겠습니다. 빨간 사각형(Red boy). 그리고 제 파란 사각형은 blue-boy라는 클래스를 가질 수 있습니다. 좋습니다. 좋습니다. 그래서 우리의 클래스 선택 스타일에는 여기에 점 표기법(dot notation)을 넣으면 됩니다. blue-boy. 배경색을 파란색으로 만들자고 합시다. 빨간 사각형을 하나 더 만듭니다. 그리고 얘는 제가 뭘 원하는지 이미 알고 있어요.
그리고 이 두 요소 모두 너비와 높이를 갖기를 원합니다. 그리고 둘 다 시각적 요소입니다. 그러니 그대로 둡시다. 그리고 삭제할 수 있습니다. 끝났습니다. 그리고 그 사이에 약간의 들여쓰기가 필요하다고 합시다. 제가 파란색 상자(blue-boy)를 가져와서 위쪽 들여쓰기(top indent)를 10픽셀로 만들겠습니다. 끝났습니다. 좋습니다. 그래서 여러분이 알아차렸을 수 있는 한 가지 단점은 시각적 변경 사항을 보려면 플레이 버튼을 계속 눌러야 한다는 것이고, 실제로 플레이 버튼을 누르지 않으면 화면에 아무것도 없다는 것입니다. 그리고 그건 끔찍합니다.
그래서 이를 해결하는 방법은 validate 함수를 사용하는 것입니다. 여기서는 generate도 호출할 것입니다. 하지만 만약 검증(validate)하고 싶지 않을 때, 즉 플레이 중일 때는 검증을 하고 싶지 않다면, 원래의 방식을 사용할 것입니다. 그리고 이제 실제로 화면에 나타났습니다. 이 문제를 해결했지만, 새로운 문제를 만들었습니다. 예를 들어, 여기에 떠다니는 요소가 있다고 합시다. 왜냐하면 이것이 검증(validation) 중에 발생하기 때문입니다. Validate는 스크립트나 객체에서 무언가 변경될 때마다 호출됩니다. 그래서 우리가 이것을 여기저기 움직이기 시작하면, UI를 끊임없이 업데이트하고 루트 요소에 더 많은 요소를 추가하는 것을 볼 수 있습니다.
이를 수정하는 방법은 generate할 때마다 단순히 지우는 것입니다. 그러면 이제 객체를 수정할 수 있고, 이런 일이 발생하지 않습니다. 그리고 이것이 비효율적으로 보일 수도 있지만, 여러 번 업데이트되는 것처럼 보일 수 있지만, 이전의 IMUI 시스템을 생각해 보면 기본적으로 발생하는 것이고, 실제로 게임에 있을 때는 그렇게 하지 않습니다. 단지 한 번 그릴 뿐이며, 실제로 무언가 변경될 때만 변경됩니다. 이제 만약 대상 요소가 우리가 여기서 가져오는 루트 요소(root element) 자체가 되기를 원한다면, root라는 특별한 선택자(selector)를 사용합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 YouTube Tarodev (Unity 팁)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기