Создание архитектуры UI на Unity

Для мобильных игр и не только. Разработчик Янко Оливейра (Yanko Oliveira) поделился в блоге на Gamasutra своим опытом и советами по выстраиванию архитектуры пользовательского интерфейса для мобильных игр на Unity. При разработке мобильного проекта, особенно F2P, не обойтись без метаигры, которая чаще всего гораздо сложнее основной геймплейной петли. А это значит много работы над пользовательским интерфейсом. UI мало кто любит заниматься, поэтому разработчики часто выбирают уже существующие архитектуры и упрямо защищают их в жарких спорах. На деле нет какой-то идеальной архитектуры, подходящей для всех. В этом материале я изложу один способ разработки интерфейса, который хорошо работает при создании систем средней и высокой сложности, и был проверен на нескольких выпущенных играх. Если вкратце, эта архитектура — нечто вроде менеджера окон с историей и управлением потоком данных. Её легко адаптировать под конкретный проект. Многие необходимые вещи уже встроены в Unity, поэтому разработка интерфейса в нём — довольно простая задача, если понимаешь, как что работает. Однако некоторые сомнительные решения и небольшие детали могут вызывать фрустрацию. Иногда придётся создавать свои компоненты интерфейса. При этом нужно помнить о целесообразности этих действий — возможно, то, что вам нужно, уже есть на движке. Расширить базовые классы UI и добавить дополнительные функции существующим компонентам — лёгкий путь, но опасный. Есть большая вероятность, что в результате придётся делать больше работы, чем если бы вы создали новые компоненты и классы. Когда вы что-то меняете в иерархии, весь меш обновляется. То есть, если весь интерфейс — это один холст (canvas), и в одном маленьком текстовом поле каждый кадр меняется число, то весь холст будет заново отстраиваться каждый кадр. В идеале нужно иметь все статичные элементы на одном холсте, а динамические — на другом, но чаще всего это невозможно. Нужно искать баланс между оптимизацией и временем, затраченным на работу. Отзывчивый интерфейс легче адаптировать для разных разрешений. Также не забудьте выставить референсное разрешение в CanvasScaler, иначе потом придётся всё перестраивать. Я использую 1920*1080. Это распространённая ошибка. Её симптом — элементы выглядят нормально, когда вы передвигаете их в редакторе, но меняют положение при рендеринге. Экран (screen) — отдельная замкнутая часть интерфейса. Они бывают двух видов: панели (panels) и диалоги (dialogs). Одновременно могут быть открыты несколько панелей и диалогов, но только один диалог может быть интерактивным в единицу времени. Панели могут быть только открыты или закрыты, а диалоги обладают историей. Виджет (widget) — часть экрана, которую можно использовать несколько раз. Слой (layer) — то, в чём находится и чем контролируется экран. Вот приблизительное устройство иерархии элементов интерфейса (в скобках перечислено, что в них обычно содержится). UI [код UI Manager, основной холст] — Камера — Слой диалога (код слоя диалога) — — Диалог А (контроллер диалога А) — — Диалог B (контроллер диалога B) — Слой панелей (код слоя панелей) — — Панель A (контроллер панели A) — — Панель B (контроллер панели B) Unity отрисовывает элементы строго по иерархии, то есть, нижние элементы рендерятся в последнюю очередь. В этом примере панели всегда будут расположены поверх диалогов. Во время настройки основного холста используйте Screenspace — Camera, а не Screenspace — Overlay. Она работает точно так же, и можно добавлять вещи вроде трёхмерных моделей, систем частиц и даже эффектов постобработки. Префабы (prefab) очень помогают. Я обычно делаю по одному префабу для экранов и по несколько для виджетов. Что бы вы ни делали, старайтесь разделять элементы на как можно большее количество префабов. В идеале ваш художник интерфейса должен работать в Unity. Так вы сможете сосредоточиться на программировании, вместо того, чтобы пытаться перенести творения художника в игру. Если он не знает движка, постарайтесь его научить. Также можно сделать редактор для художника, но это нужно делать вместе с ним, потому что это ему работать в программе. Спрайты лучше всегда переводить в атласы (atlas). Я пользуюсь встроенным Sprite Packer и складываю все спрайты для одного атласа в отдельную папку, чтобы все они попадали в Asset Bundle. Также рекомендую работать над заготовками в сторонних программах как можно дольше, прежде чем запускать Unity, используя Balsamiq, Axure, InVision или Origami Studio, в зависимости от предпочтений художника. Когда заготовки сделаны и одобрены, художник делает префаб экрана, который программисты добавляют в игру. Если времени на весь рабочий цикл нет, программисты могут делать собственные версии экранов, чтобы добавить нужные функции, а потом менять их на одобренные префабы. Код системы интерфейса разделён на три части: главный фасад, контроллеры слоёв и контроллеры экранов. В моём примере иерархии было два слоя, в реальности их почти всегда больше. Можно каждый раз создавать новый слой, но я пользуюсь пара-слоями (para-layers): дополнительные объекты в иерархии, к которым код слоя привяжет все изменения экрана (Screen Transforms). Все контроллеры слоёв — это вариации AUILayerController. У этого класса есть код для показа и скрытия экранов, и он общается с самими экранами. PanelLayer просто указывает, что он управляет панелями, и отправляет их к пара-слоям. DialogueLayer контролирует историю и очерёдность диалогов. Вот код базового класса. Каждому экрану можно добавить параметр Properties. У этих параметров класс [System.Serializable], так что их можно менять прямо в префабе. Экран появляется при регистрации, когда префаб привязывается к слою. Экран привязан к ScreenID. Вот отрывок из AUIScreenController. UI Manager получает запросы методов (method calls) и направляет их к нужным слоям. Я обычно добавляю ещё ярлыки для отдельных вещей, которые точно пригодятся, вроде UICamera или MainCanvas. Никакой код не должен прямо взаимодействовать с кодом экранов или слоёв, всё должно происходить через UI Manager. Animator — мощный инструмент, если нужно анимировать гуманоидного персонажа, но для интерфейса он не очень подходит. Разве что анимации должны быть очень простыми: тогда можно дописать код к стейт-машинам (state machines) Animator. Чаще всего в интерфейсе очень много анимаций для экранов, которые постоянно появляются и исчезают. При их настройке легко случайно создать условия для зависания при нажатии кнопки. В коде экранов есть встроенные возможности для появления и исчезания, и во время анимации взаимодействие с ними заблокировано. Чтобы избежать проблем, можно тщательно контролировать EventSystem или, как я, создать прозрачный прямоугольник поверх всего. Вот ATransitionComponent. Их можно выставить в полях transition in или transition out в любом AUIScreenController. В нём также есть два события, к которым регистрируется слой и предупреждает, когда анимация закончилась. Это позволяет обеспечивать плавность анимаций по времени и блокировать экран: когда диалог открывается или закрывается, он вызывает блокировку интерфейса и включает анимацию. Блок снимается, когда анимация закончилась. Благодаря этому можно создать несколько типов переходов, и они могут быть напрямую настроены художниками. Для более сложных анимаций можно создать AScreenTransition, который работает с Animator. Самое плохое, по моему мнению, что даже для самых простых движений нужен набор анимаций и контроллер Animator. В Unity всё зависит от иерархии и названий, так что даже для создания элементарного затухания экрана нужно сильно постараться. К счастью, теперь есть SimpleAnimationComponent, для которого не нужен контроллер Animator. За годы разработки описанная здесь система интерфейса почти не изменялась. Решение не использовать существующие архитектуры окупилось: если мы хотели добавить что-то новое в UI, мы легко можем написать грубый локализованный код, а потом почистить его. #опыт #unity Ещё интересные статьи от dtf.ru : Do you know de way: как угандийские наклзы оккупировали виртуальную реальность Утраченный потенциал: ранние концепты «Чужого: Завет» Новогоднее обращение к читателям DTF Лучший подарок Как я оказался на сцене перед тысячей человек Мама и Final Fantasy XV Две реальности — обзор фильма «Джуманджи: Зов джунглей» «Это не мой Люк Скайуокер»: Марк Хэмилл против Disney Эмулятор DOOM на сайте «Грязные» приёмы разработчиков игр

Создание архитектуры UI на Unity
© DTF.RU