Defold предоставляет пользовательский Gui-редактор и эффективные средства написания скриптов, которые разработаны специально для создания и реализации пользовательских интерфейсов.
В Defold GUI, или графический интерфейс пользователя — это компонент, прикрепляемый к игровому объекту и помещаемый в коллекцию. Этому компоненту присущи следующие черты:
Компоненты GUI рендерятся независимо от игрового представления. Поэтому они не размещаются в определенном месте и не имеют визуального представления в редакторе коллекции. Однако компоненты Gui должны находиться в игровом объекте, который имеет местоположение в коллекции. Изменение этого расположения не влияет на GUI.
Компоненты GUI создаются из файла-шаблона GUI-сцены. Чтобы создать новый компонент GUI, кликните ПКМ в каком-либо расположении в браузере Assets и выберите New ▸ Gui. Введите имя нового файла GUI и кликните Ok.
Defold автоматически откроет файл в редакторе GUI-сцен.
В Outline перечисляется весь контент графического интерфейса: список нод и какие-либо зависимости (см. ниже).
В центральной области редактирования отображается GUI. Панель инструментов в правом верхнем углу области редактирования содержит инструменты Move, Rotate и Scale, а также селектор компоновок.
Белый прямоугольник показывает границы текущей выбранной компоновки, ширину и высоту дисплея по умолчанию, установленные в настройках проекта.
Выделив корневую GUI-ноду, в Outline отображаются свойства компонента GUI:
Per Node
— подгоняет каждую ноду под измененный размер родительской ноды или измененный размер экрана.Disable
— отключает режим адаптации нод. Заставляет все ноды сохранять заданный размер.Дерево ресурсов в игре Defold статично, поэтому все зависимости, необходимые для GUI-нод, должны быть добавлены к компоненту. В Outline все зависимости группируются по типам в “папках”:
Чтобы добавить новую зависимость, кликните ПКМ в корне “GUI” в Outline, затем выберите Add ▸ [type] из всплывающего контекстного меню.
Также можно кликнуть ПКМ на иконке папки для типа, который требуется добавить, и выбрать Add ▸ [type].
Компонент GUI формируется из набора нод. Ноды — это простые элементы. Они могут быть трансформированы (перемещены, масштабированы и повернуты) и упорядочены в иерархии “родительский-дочерний” либо в редакторе, либо во время выполнения с помощью скриптов. Существуют следующие типы нод:
Добавьте ноды, кликнув правой кнопкой мыши на папке Nodes и выбрав Add ▸, затем Box, Text, Pie, Template, Spine или Particle Fx.
Также можно нажать A и выбрать тип для добавления в GUI.
Каждая нода имеет богатый набор свойств, которые отвечают за ее внешний вид:
Manual
, это значение можно изменять. Размер определяет границы ноды и используется при выполнении ввода. Это значение можно анимировать из скрипта (подробнее).Automatic
, редактор сам устанавливает размер узла. Если установлено значение Manual
, размер можно задавать самостоятельно.0
не оставляет межстрочного интервала. 1
(по умолчанию) — обычный межстрочный интервал.Alpha
— смешивает пиксельные значения ноды с фоном. Соответствует режиму наложения “Normal” в графических программах.Add
— добавляет пиксельные значения ноды к фону. Соответствует “Linear dodge” в некоторых графических программах.Multiply
— перемножает значения пикселей ноды с фоном.Возможные значения: Center
, North
, South
, East
, West
, North West
, North East
, South West
и South East
.
Если изменить пивот ноды, нода будет перемещена так, чтобы новый пивот находился в позиции ноды. Нода Text выравнивается таким образом, что Center
устанавливает выравнивание текста по центру, West
— по левому краю, а East
— по правому.
Доступны следующие режимы анкеровки:
None
— (для обоих X Anchor и Y Anchor) сохраняет положение ноды от центра родительской ноды или сцены, относительно ее скорректированного размера.Left
или Right
— (X Anchor) масштабирует горизонтальное положение ноды так, чтобы сохранить положение от левого и правого краев родительской ноды или сцены в одинаковом процентном соотношении.Top
or Bottom
(Y Anchor) — (Y Anchor) масштабирует вертикальное положение ноды так, чтобы сохранить положение от верхнего и нижнего краев родительской ноды или сцены в одинаковом процентном соотношении.Нода, созданная в сцене, где логическим разрешением является типичное разрешение ландшафта:
При подгонке сцены к портретному экрану сцена растягивается. Аналогично растягивается ограничивающая рамка каждой ноды. Однако, установив режим корректировки, можно сохранить соотношение сторон содержимого ноды. Доступны следующие режимы:
Fit
— масштабирует содержимое ноды так, чтобы оно было равно ширине или высоте растянутой границы, в зависимости от того, что меньше. Другими словами, содержимое будет помещаться внутри растянутой границы ноды.Zoom
— масштабирует содержимое ноды так, чтобы оно было равно ширине или высоте растянутой границы, в зависимости от того, что больше. Другими словами, содержимое будет полностью покрывать растянутую границу ноды.Stretch
— растягивает содержимое ноды так, чтобы оно заполняло растягиваемую границу ноды.Если свойство GUI-сцены Adjust Reference установлено в Disabled
, эта настройка будет проигнорирована.
None
— отображает ноду как обычно.Stencil
— заставляет границы ноды определять трафаретную маску, которая используется для обрезки дочерних нод данной ноды.За подробностями обращайтесь к руководству по обрезке GUI.
Комбинация свойств Pivot, Anchors и Adjust Mode позволяет весьма гибко конструировать графические интерфейсы, но понять, как все это работает, без конкретного примера бывает затруднительно. В качестве примера рассмотрим макет графического интерфейса, созданный для экрана 640x1136:
UI создан с X и Y Anchors, установленными на None, а Adjust Mode для каждой ноды оставлен на значении по умолчанию Fit. Пивот для верхней панели — North, для нижней панели — South, а для баров на верхней панели пивот установлен в значение West. Для остальных нод пивоты установлены в Center. Если мы изменим размер окна, чтобы сделать его шире, вот что произойдет:
Теперь, что если мы хотим, чтобы верхний и нижний бары всегда были такой же ширины, как экран? Мы можем изменить режим Adjust Mode для панелей с серым фоном сверху и снизу на Stretch:
Так лучше. Теперь панели с серым фоном всегда будут растягиваться по ширине окна, но бары в верхней панели, а также два бокса внизу расположены неправильно. Если мы хотим, чтобы бары в верхней части были расположены слева, нам нужно изменить X Anchor с None на Left:
Это именно то, что нам нужно для верхней панели. У баров на верхней панели Pivot уже установлены на West, что означает, что они будут позиционироваться так, чтобы левый/западный край баров (Pivot) был привязан к левому краю родительской панели (X Anchor).
Теперь, если мы установим X Anchor в Left для бокса слева и X Anchor в Right для бокса справа, получим следующий результат:
Это не совсем ожидаемый результат. Два бокса должны находиться так же близко к левому и правому краю, как два бара на верхней панели. Причина этого в том, что пивот выбран неверно:
У обоих боксов пивот установлен в Center. Это означает, что при увеличении ширины экрана центральная точка (пивот) боксов будет оставаться на одинаковом относительном расстоянии от краев. В случае левого поля она находилась на расстоянии 17% от левого края при исходном окне 640x1136:
При изменении размеров экрана центральная точка левого бокса остается на том же расстоянии 17% от левого края:
Если мы изменим Pivot с Center на West для бокса слева и на East для бокса справа и изменим положение боксов, мы получим желаемый результат даже при изменении размера экрана:
Все ноды отображаются в том порядке, в котором они перечислены в папке “Nodes”. Нода, находящаяся в верхней части списка, отрисовывается первой и, таким образом, будет отображаться позади всех остальных нод. Последняя нода в списке отрисовывается последней, то есть она будет отображаться перед всеми остальными нодами. Изменение Z-значения ноды не влияет на порядок отрисовки; однако, если установить Z-значение за пределами диапазона отрисовки рендер-скрипта, нода не будет отрисована на экране. Индексное упорядочивание нод можно изменить с помощью слоев (см. ниже).
Выделите ноду и нажмите Alt + Up/Down, чтобы переместить ноду вверх или вниз и изменить индексный порядок.
Порядок отрисовки может быть изменен в скрипте:
local bean_node = gui.get_node("bean")
local shield_node = gui.get_node("shield")
if gui.get_index(shield_node) < gui.get_index(bean_node) then
gui.move_above(shield_node, bean_node)
end
Нода становится дочерней по отношению к другой ноде путем перетаскивания ее на ноду, которая должна стать родительской. Нода с родителем наследует трансформации (положение, поворот и масштаб), примененные к родителю относительно родительского пивота.
Родительские ноды отрисовываются раньше дочерних. Используйте слои, чтобы изменить порядок отрисовки родительских и дочерних нод и оптимизировать рендеринг нод (см. ниже).
Слои обеспечивают тонкий контроль над тем, как отрисовываются ноды, и могут быть использованы для уменьшения количества вызовов отрисовки, которые движок должен создать для отрисовки GUI-сцены. Когда движок собирается отрисовывать ноды GUI-сцены, он группирует их в пакеты вызовов отрисовки, руководствуясь следующими условиями:
Если нода отличается от предыдущей по любому из этих пунктов, она нарушит пакетирование и создает новый вызов отрисовки. Ноды обрезки всегда нарушают пакетирование, каждый трафаретный участок также нарушает пакетирование.
Возможность расположения нод в иерархии позволяет легко группировать ноды в управляемые единицы. Но иерархии могут существенно нарушить пакетный рендеринг, если смешать различные типы нод:
Когда пайплайн рендеринга проходит по списку нод, он вынужден создавать пакет для каждой отдельной ноды, поскольку их типы различны. В целом для этих трех кнопок потребуется шесть вызовов отрисовки.
Назначая нодам слои, их можно упорядочить по-разному, что позволяет пайплайну рендеринга группировать ноды вместе за меньшее количество вызовов отрисовки. Начните с добавления нужных слоев в сцену. Кликните ПКМ на иконке папки “Layers” в Outline и выберите Add ▸ Layer. Отметьте новый слой и присвойте ему свойство Name в представлении Properties.
Затем установите свойство Layer каждой ноды в соответствующий слой. Порядок отрисовки слоев имеет приоритет над обычным порядком индексированных нод, поэтому установка графической кнопки ноды Box в “graphics” и кнопки ноды Text в “text” приведет к следующему порядку отрисовки:
Сначала все ноды в слое “graphics”, начиная с верхней:
Затем все ноды в слое “text”, начиная с верхней:
Теперь ноды можно объединить в два вызова рисования вместо шести. В результате — значительный выигрыш в производительности!
Следует отметить, что дочерняя нода с неустановленным слоем неявно наследует настройку слоя своей родительской ноды. Отсутствие установки слоя у ноды неявно добавляет ее к “нулевому” слою, который отрисовывается перед каким-либо другим слоем.