Автоверстка и стили в Unity: наш новый пайплайн и инструменты для UI +29




Начну с главного: мы сделали удобный инструмент для верстки и изменили пайплайн работы. Теперь по порядку.

В мобильных играх много разных интерфейсов, включая HUD и огромное количество экранов для меты. UX-дизайнеры их проектируют, UI-дизайнеры отрисовывают, а чтобы всё это оказалось в движке существуют специально обученные люди — технические UI-дизайнеры. Ну или по-простому верстальщики. Частично их работа заключается в том, чтобы кропотливо из PSD-макета перенести все в префаб, чиселку за чиселкой. Еще они занимаются UI-анимациями, заливают спрайты, делают верстку адаптивной, расставляют ключи локализаций и так далее.

И мы поставили себе несколько целей:

  • ускорить работу верстальщика и избавить его от рутины;
  • оптимизировать взаимодействие между отделами UI-дизайна и разработки;
  • внести в UI единообразие: создать гайдлайны и сформировать на их основе Unity-ассеты;
  • обеспечить расширяемость и универсальность UI, реюзабельность ассетов, устойчивость к правкам, и легкую оптимизацию.

Вот как это происходило.

Мы попытались создать некую дизайн-систему из средств движка Unity и Adobe Photoshop (который, кажется, кроме геймдева, мало где используется для создания интерфейсов). Грубо говоря, перед нами стояла задача подружить Photoshop и Unity.



В первую очередь нужно было спроецировать весь набор «визуального языка» в Unity. Для этого мы выбрали стили и подстроили их под собственные нужды. Это довольно распространенная практика среди компаний. Так набор шрифтов стал стилем со шрифтами, набор лейаутов стал стилем со спрайтами этих лейаутов, набор цветов — стилем с цветами и так далее. Достаточно было один раз создать все это, а потом просто переиспользовать и дополнять вместе с расширением psd с гайдлайнами. Таким образом UI-дизайнер вынужден отказаться от 1001 подложки на разных экранах и создать несколько универсальных.

Текущие стили, которые есть:

  1. Color Style <Название, Цвет>
  2. Text Style <Название, Шрифт, Размер шрифта, Материал шрифта, Межстрочный интервал>
  3. Font Style <Название, Шрифт, Материал шрифта>
  4. Button Style <Название, Настройки кнопки>
  5. Layout Style <Название, Спрайт, Отступы>
  6. Sprite Style <Название, Спрайт>
  7. Localization Style <Название, Ключ>
  8. Icon Style <Название, Спрайт>

И в целом создавать стили можно легко и просто, наследуя его от базового. Например:

[CreateAssetMenu(menuName = "UIStyles/ColorStyle")]     
public class ColorStyle : BaseStyle<Color>    
{
}

Единственное ограничение: тип должен быть Serializable. Так что с созданием своего типа стиля справится даже верстальщик.



Некоторые стили нужны, чтобы изменять состояния UI. Например, Color Style, Text Style, Sprite Style, Button Style, Localization Style. Все они влияют на разные геймобджекты. Картинки красятся в разные цвета, в них подставляются разные спрайты и так далее.

До сих пор не было ясно, как все это юзать. Приведу простой пример. Допустим, у нас есть одна кнопка офферов разных цветов. Цвет кнопки зависит от самого оффера. И выглядят они вот так:



Тогда мы создаем один префаб с Image, на который повесим ColorStyleComponent, вставим в него стиль ColorStyle, где будут храниться все цвета, в которые может перекрашиваться кнопка, а потом внутри кода применять стили в зависимости от оффера.



Стили же FontStyle, IconStyle и LayoutStyle применяются для автоверстальщика. Это библиотечка всех шрифтов, иконок и подложек в проекте.

У системы со стилями есть огромное количество преимуществ (только куча ассетов в проекте могут раздражать):

  • переиспользование;
  • при изменении стиля не меняется префаб, но если что-то надо изменить, то это будет влиять на все префабы;
  • верстальщики сами создают стили, меняют их и удаляют, что позволяет программистам забыть о куче полей в монобехах с цветами;
  • стили можно применять прямо в редакторе за счет того, что для BaseStyleComponent<T, TStyle> пишется свой Editor.

Чтобы поменять состояния одного большого виджета, могут использоваться несколько стилей, выключаться/включаться разные объекты. Для этого в проекте был создан StateStyleComponent, который собирает в себя все стили и объекты, которые нужно включать/выключать. Затем прямо в виджете создаются и переключаются все его возможные состояния. Это избавляет программистов от кучи одинакового кода переключения цветов/шрифтов/текстов/спрайтов.





Затем мы создали автоверстальщик. Это инструмент, в который засовываешь psd, а на выходе создается сырой префаб, в который уже подставлены некоторые спрайты, проставлены позиции, имена, шрифты, размеры, алайны — все то, что так тщательно ручками копируется из psd верстальщиками. Он даже примерно проставляет анкоры и сохраняет иерархию. И делает это за считанные секунды, что в итоге экономит часы кропотливого копирования.



Само окно автоверстальщика выглядит скудным на настройки. В ходе использования эти настройки будут добавляться.



Чтобы получить все данные, был написан парсер psd именно под эти нужды на основе psd-спецификации. Это довольно скучный процесс, можно взять уже готовые библиотеки. Но так как мы хотели делать все по одной кнопке, пришлось написать с нуля.

Всю иерархию в фотошопе автоверстальщик копирует. Сначала создается корневой объект с названием префаба, который прианкорен к краям экрана. Внутри него создаются объекты по принципу, описанному выше — объект создается в корневом объекте, а потом ему присваивается настоящий родитель с сохранением глобальной позиции. Анкоры расставляются по принципу — к какому краю или центру объект расположен ближе всего, к тому и прибивается, отдельно по осям ОХ и ОY. Все позиции и размеры делаются целочисленными. Скрытые объекты автоверстальщик игнорирует.



В фотошопе есть 5 видов слоев: группы, пиксельные, формы, тексты и смарт-объекты.

  1. Группы (group layer) в автоверстальщике превращаются в пустой геймобджект, поэтому в группу можно легко объединять какую-нибудь большую компоненту интерфейса типа хад, слот, группа слотов и так далее.
  2. Пиксельные (pixel layer) просто становятся Image с белым цветом. Это могут быть иконки, бэки, картинки, светяшки. Потом вручную добавляются в проект, как спрайты и вставляются в Image.
  3. Формы (shape layer) становятся картинкой с цветом шейпа. Это могут быть любые векторные элементы: лейауты, иконки и другие.
  4. Тексты (text layer) в автоверстальщике становится TextMeshProUGUI и наследует текст, шрифт, цвет, обводку, тень, градиент, размер шрифта, позиционирование (справа, по центру, слева).
  5. Smart-объекты становятся обычными пустыми геймобджектами. Смарт-объектами логично делать то, что уже версталось в качестве nested prefabs (например, верхний бар, который везде один)

Автоверстальщик также умеет собирать цвета из всех мест (например, цвет шейпа, цвет шрифта, эффект цвета, слой цвета) и преобразовывать их в один hex. Аналогично с прозрачностью.

Отдельно UI-дизайнер сразу проставляет опции в имена слоев и групп (как в Zeplin).

Примеры опций в таблице
Опция Аргументы Значение Пример Объект в Unity
-l Название подложки из гайдлайнов (без пробелов) Добавление на картинку спрайта Hud Layout -l pink228 Image_HudLayout с компонентом Image с вставленным спрайтом лейаута pink228 из гайдлайнов
-cs Название_стиля. Опционально (без пробелов) Добавляет ColorStyleComponent со стилем Название_стиля Hud Layout -cs HudLayoutColors
Hud Layout -cs
Image_HudLayout с компонентом ColorStyleComponent со стилем внутри HudLayoutColors
Image_HudLayout с компонентом ColorStyleComponent
-ts Название_стиля. Опционально (без пробелов) Добавляет TextStyleComponent со стилем Название_стиля Ability -tsAbilityColors
Ability -ts
Text_Ability с компонентом TextStyle со стилем внутри AbilityColors
Text_Ability с компонентом TextStyle
-bs Название_стиля.
Опционально (без пробелов)
Добавляет ButtonStyleComponent со стилем Название_стиля Play -b -bs
-b Это кнопка Play -b
Play -b -l 1
Button_Play с компонентом Button и Image
Button_Play с компонентом Button и Image с вставленным спрайтом лейаута 1 из гайдлайнов
Опционально
-hg Горизонтальная группа (исключительно на группе) Module Buttons — hg ModuleButtons с компонентом Horizontal layout group
-vg Вертикальная группа (исключительно на группе) Module Buttons — vg ModuleButtons с компонентом
Vertical layout group


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

Но у подхода есть и минусы: если psd-макет сделан из 1000 слоев для одной только кнопки, он будет практически бесполезен, в этом случае рекомендуется добавлять кнопку в смарт-объект. Также инструмент требует от UI-дизайнера нормальный и правильный нейминг — называть слои «Прямоугольник_copy_21_1005» уже не получится. С другой стороны, это делает макеты более читабельными для других UI-дизайнеров.

В планах придумать систему, которая бы избавила от экспорта спрайтов подложек.

Верстка с автоверстальщиком popup из этой статьи заняла 3 минуты 13 секунд (если не считать закидывания спрайтов в проект). Ручками занимает 18 минут 32 секунды. При этом в верстке ручками есть еще и проблемы — местами неверные позиции, которые заметит зоркий глаз UI-дизайнера и придется переделывать. Поэтому автоматическая верстка хороша ещё и тем, что она исключает человеческий фактор.

И несколько отзывов об автоверстальщике:
«Автоверстальщик значительно ускоряет работу, но пока, кажется, что нужно упростить порог вхождения, установку и настройку»
«Думаю, если стили настраивать верстальщику — по времени без особой разницы, а вот дизайнерам и программистам сэкономит время и нервы точно»
«штука очень крутая))»
«Стили — тема очень крутая, в нашем проекте подобного не хватает, так как любят перекрашивать кнопки на макетах, тексты и т.п. Очень здорово, что теперь такое можно закрепить в стилизаторе и никакой головной боли, что у тебя разные цвета или разные спрайты в однородных местах»
«Версткой должны заниматься сами UI-дизайнеры, потому что только они знают особенности своих макетов. А автоверстальщик — отличная штука для тех, кто не хочет разбираться в тонкостях верстки. Если у инструмента будет понятный интерфейс и он научится в Figma, то будет просто роскошно»
Лично я думаю, что автоматизировать надо все, что можно автоматизировать, а людям давать возможность заниматься более творческой и изобретательной работой.




К сожалению, не доступен сервер mySQL