Pull to refresh

Краткий обзор нового Unity UI с примерами организации интерфейса

Game development *Unity3D *
Sandbox


Пожалуй, для многих новость о выходе новой системы Unity UI (далее просто UI) не показалась чем-то значимым. Как минимум — по причине её сырости, как максимум — из-за существования NGUI. Я поначалу не стал исключением, но открытие исходного кода UI системы (1) под либеральной лицензией MIT/X11, а так же энтузиазм разработчиков Unity Technologies заставили меня изменить мнение.

На мой взгляд, новый UI принесет нам довольно много плюсов:

  • Вполне достойный инструмент из коробки;
  • Возможность более глубоко понимать работу UI благодаря наличию исходников;
  • Общепринятый механизм внесения изменений в исходный код UI — fork/pull request;
  • Здоровая конкуренция между разными системами UI в конечном итоге принесет свои плоды в виде более качественных и удобных инструментов для Unity, а возможно и демпинг цен;
  • Тесное взаимодействие команды разработки UI и ядра Unity уже сейчас приносят плоды в виде оптимизаций производительности, да и в будущем надеюсь они будут идти нога в ногу.


Руководствуясь этими мыслями было решено разрабатывать интерфейс игры, используя новый UI. Как показало время, решение было оправдано, игра увидела свет и благополучно функционирует на Android девайсах. К слову сказать, финальное решение было после анонса патча Unity 4.6.1 (2), который включал тонну фиксов и импрувов UI.

Давайте перейдем к конкретике. Начну с общего представления, сформировавшегося после раскуривания скудной документации, просмотра видео-уроков и раскопки исходного кода.

Концепция UI


Подход к организации интерфейса переработан впринципе. То есть если вы ранее работали с GUI, в новом UI вы почти не найдете ничего похожего. И наоборот — если вы работали с NGUI, то найдете очень много общего. В целом ее можно назвать типичной для сред с инструментами визуальной разработки.

В основе понимания новой концепции лежат три компонента: Canvas, Rect Transform и Event Trigger.

Canvas — является контейнером для всех элементов UI и определяет режим рендера. Таких контейнеров на сцене может быть более одного (3).

Rect Transform — этот компонент позволяет задать положение и размер игрового объекта, используя удобные визуальные контролы. Он вводит понятия ширины и высоты, а не только масштаб (4).

Unity Event — доработанная система событий, а конкретно компонент Event -> Event Trigger который включает компоненты визуального управления вызовом событий (5).

По мере знакомства с UI я создавал для себя возможные варианты использования. Давайте на них и разберем эту всю кухню. В конце статьи вы можете найти демо-проект, на который я буду ссылаться в тексте. К сожалению, этим примерам далеко до готовых рецептов, так как они не достаточно проработаны, плюс заточены под 2D игры, хотя местами вполне подойдут и для 3D.

Пример #1


Цели:
1. Тайловый фон;
2. Фиксированное положение контролов в независимости от разрешения и соотнешения сторон экрана;
3. Контролы должны быть пропорциональны размеру экрана.

Вариант решения:
1. Добавляем на сцену Canvas и выбираем режим рендера Screen space — Overlay, этот режим будет автоматически подстраивать его размер под размер камеры;
2. Добавим тайловый фон, для этого нам всего-то и нужно, что добавить нашему Canvas новый UI компонент — Image, выбрать нужный спрайт и изменить поле Image Type в значение Tiled;
3. Выбираем в окне Game удобное нам разрешение, например, 480x800 и добавляем на наш Canvas — контейнер необходимые контролы, выставляем им нужные позиции;
4. Далее идет новая магия UI, под названием якоря! Название говорит само за себя, они позволяют закреплять ряд характеристик игрового объекта, используя компонент Rect Transform. Изменить их можно в окне редактирования сцены, включив новый режим, либо в инспекторе. Обратите внимание, что иконка в инспекторе компонента Rect Transform — кликабельна и открывает окно выбора предустановленных положений и вариантов поведения, а если зажать кнопку Shift, то еще и положение точки опоры;
5. Довершает картину один из компонентов Canvas, который добавляется к нему по умолчанию Layout -> Canvas Scaler, а именно один из его режимов — Scale With Screen Size. Этот режим позволяет задать Reference Resolution, в нашем случае это будет 480x800.



Пример #2


Цели:
1. Ориентация строго портретная;
2. Универсальный для всех соотношений сторон фон, который всегда отображается на весь экран, а если необходимо обрезается только снизу;
3. Фиксированное положение контролов в независимости от разрешения и соотнешения сторон экрана;
4. Контролы должны быть пропорциональны размеру экрана.



Вариант решения:
1. Добавляем на наш Canvas — контейнер объект UI -> Image, выбираем нужный спрайт и тип изображения Simple;
2. Вся магия сводится к расположению якорей и точки опоры таким образом, что бы они лежили по центру верхнего ребра Canvas;
3. В компонент Canvas Scaler нужно выставить значение Match равное 0.

Пример #3


Цели:
1. Ориентация строго портретная;
2. Тайловый фон, который не скейлится;
3. Фиксированное по размеру игровое поле, например 400x400;
4. Фиксированное положение контролов в независимости от разрешения и соотнешения сторон экрана;
5. Контролы должны быть пропорциональны размеру экрана.



Вариант решения:
1. Можно, конечно, реализовать фон как Sky Box или игровым объектом типа Quad с затайленой текстурой и размерами заведомо больше экрана. Но мы пойдем UI-ным путем и создадим Canvas, аналогичный примеру #1, только выставим тип рендера Screen Space — Camera и пропишем нашу главную камеру в поле Render Camera;
2. Теперь создадим еще один Canvas с типом рендера World Space, пропишем камеру и поставим значение Order in Layer равное 1, что бы этот слой рисовался поверх предыдущего Canvas у которого это значение равно 0;
3. Советую вам при рендере World Space _заранее_ ставить значение масштаба Canvas таким образом, что бы у вас не было проблем с размером шрифтов;
4. Контролы раставляем уже известным нам способом.

Пример #4


Цели:
1. Создать скроллер;
2. Контент не должен быть виден за пределаеми скролера;
3. Он должен скейлиться вместе с экраном и липнуть к нижнему краю.



Вариант решения:
1. Нам необходим игровой объект которому мы добавим компонент UI -> Scroll Rect, самое важное поле которого — Content, задав которое мы указываем контейнер содержащий игровые объекты (например надцать изображений игровых уровней размером 100х100, которые заведомо не влезают в размер экрана);
2. Так же нам будет полезен компонент UI -> Mask (обратите внимание, что также необходимо вставлять пустой компонент Image), который клипнет контент выходящий за пределы игрового объекта, на который он добавлен;
3. Можно так же создать объект UI -> Scrollbar и привязать его к нашему Scroll Rect

Пример #5


Несколько мелкий приятностей:
1. Как расширить список обрабатываемых событий, например обрабатывать события StartDrag, EndDrag и т.д. используя компонент Event Trigger;
2. Применение элемента UI -> Toggle для реализации наград в виде Звезд с удобным скриптингом вида isOn = true;
3. Простейший вариант Попап окошек с использованием компонента Canvas Group и старого доброго аниматора без единой строчки кода.

Конечно, эти примеры покрывают лишь малую часть возможных задач и реализаций, но я надеюсь, они помогут вам выбрать удобное направление для поисков решения или, как минимум, песочницу, в которой можно попробовать разные варианты.

Файл проекта с примерами


www.dropbox.com/s/0d48cf04lekpfoe/DemoProjectUIv4_6_1.unitypackage?dl=0

Сноски


1. bitbucket.org/Unity-Technologies/ui/overview
2. unity3d.com/unity/whats-new/unity-4.6.1
3. docs.unity3d.com/Manual/class-Canvas.html
4. docs.unity3d.com/Manual/class-RectTransform.html
5. docs.unity3d.com/Manual/SupportedEvents.html
Tags: unity3duigamedevexamples
Hubs: Game development Unity3D
Total votes 19: ↑17 and ↓2 +15
Comments 25
Comments Comments 25

Popular right now

Top of the last 24 hours