Unity canvas environment что это
Сanvas (Полотно)
Canvas (полотно) – это область, внутри которой находятся все элементы UI (пользовательского интерфейса). Полотно – это игровой объект (Game Object), с добавленным к нему компонентом Canvas. Все элементы UI должны быть дочерними этому Canvas.
Область Canvas отображается в виде прямоугольника в окне Scene View. Это облегчает процесс расположения элементов UI без необходимости видеть игровое окно (Game View).
Canvas uses the EventSystem object to help the Messaging System.
Порядок отрисовки элементов
Элементы UI на Canvas появляются в том же порядке, в каком они расположены в иерархии. Первый дочерний элемент отрисовывается первым, второй – за ним и так далее. Если два элемента UI накладываются друг на друга, добавленный позднее будет поверх того, что был добавлен ранее.
Чтобы изменить то, какой элемент будет находится поверх остальных, просто поменяйте местами элементы в иерархии путем перетаскивания. Порядком также можно управлять при помощи скриптинга, используя следующие методы компонента Transform: SetAsFirstSibling, SetAsLastSibling и SetSiblingIndex.
Режимы отображения
Этот режим отображения помещает элементы интерфейса на экран поверх сцены. Если меняется размер экрана или его разрешение, полотно автоматически примет нужный размер вместе с ним.
Интерфейс на Canvas в пространстве экрана в режиме перекрытия
Интерфейс на Canvas в пространстве экрана в режиме камеры
Пространство игрового мира (World Space)
При этом режиме отображения Canvas ведет себя также, как и любой другой объект на сцене. Размер Canvas может быть задан вручную при помощи Rect Transform, а элементы интерфейса будут отображаться перед или за другими объектами на сцене, в зависимости от их трехмерного расположения. Этот режим удобен для тех интерфейсов, которые предполагаются как часть игрового мира (diegetic interfaces).
Интерфейс на Canvas в пространстве игрового мира
Холст (Canvas)
Компонент Canvas представляет собой абстрактное пространство, в котором производится настройка и отрисовка UI. Все UI-элементы должны быть потомками игровых объектов, к которым присоединен Canvas. Когда вы создаете UI-элемент из пункта меню ( GameObject > Create UI ), Canvas будет добавлен автоматически, если его нет в сцене.
Свойства
Подробности
Одного холста для всех UI-элементов вполне достаточно, но и несколько холстов в сцене допустимо. Также, возможно использование нескольких холстов, когда один выставляется дочерним элементом другого, для оптимизации. Вложенный холст использует тот же режим рендеринга (Render Mode), что и родитель.
В этом режиме холст масштабируется для заполнения всего экрана, а затем рисуется напрямую, не ссылаясь на сцену или камеру (интерфейс написуется даже если в сцене вообще нет камеры). Если размер или разрешение экрана меняются, интерфейс автоматически перемасштабируется. Интерфейс рисуется поверх любой другой графики, такой как вид из камеры.
Интерфейс рисуемый поверх объектов сцены
В этом режиме, холст отображается как если бы он был нарисован на плоском объекте, на некотором расстоянии заданной камеры. Экранный размер интерфейса не меняется с расстоянием, т.к. он всегда масштабируется чтобы в точности заполнять пирамиду видимости камеры (camera frustum). Если размер или разрешение экрана, или пирамида видимости, изменяются – интерфейс автоматически перемасштабируется, чтобы помещаться. Любые 3д объекты сцены, расположенные ближе к камере, чем плоскость интерфейса, будут отрисованы “над” интерфейсов, в то время как остальные объекты, находящиеся за плоскостью, будут загорожены.
Интерфейс в режиме Camera mode с объектами сцены спереди
World Space (пространство мира)
Интерфейс в пространстве мира, пересекающийся с объектами сцены
Холст (Canvas)
Компонент Canvas представляет собой абстрактное пространство, в котором производится настройка и отрисовка UI. Все UI-элементы должны быть потомками игровых объектов, к которым присоединен Canvas. Когда вы создаете UI-элемент из пункта меню (GameObject > Create UI), Canvas будет добавлен автоматически, если его нет в сцене.
Свойства
Подробности
Одного холста для всех UI-элементов вполне достаточно, но и несколько холстов в сцене допустимо. Также, возможно использование нескольких холстов, когда один выставляется дочерним элементом другого, для оптимизации. Вложенный холст использует тот же режим рендеринга (Render Mode), что и родитель.
В этом режиме холст масштабируется для заполнения всего экрана, а затем рисуется напрямую, не ссылаясь на сцену или камеру (интерфейс написуется даже если в сцене вообще нет камеры). Если размер или разрешение экрана меняются, интерфейс автоматически перемасштабируется. Интерфейс рисуется поверх любой другой графики, такой как вид из камеры.
Интерфейс рисуемый поверх объектов сцены
В этом режиме, холст отображается как если бы он был нарисован на плоском объекте, на некотором расстоянии заданной камеры. Экранный размер интерфейса не меняется с расстоянием, т.к. он всегда масштабируется чтобы в точности заполнять пирамиду видимости камеры (camera frustum). Если размер или разрешение экрана, или пирамида видимости, изменяются – интерфейс автоматически перемасштабируется, чтобы помещаться. Любые 3д объекты сцены, расположенные ближе к камере, чем плоскость интерфейса, будут отрисованы “над” интерфейсов, в то время как остальные объекты, находящиеся за плоскостью, будут загорожены.
Интерфейс в режиме Camera mode с объектами сцены спереди
World Space (пространство мира)
Интерфейс в пространстве мира, пересекающийся с объектами сцены
26 октября 2015 г. Canvas в Unity
Привет! У меня нашлась свободная минутка, так что я подумал, что пришло время поделиться своим опытом построения интерфейсов в Unity. Поэтому, кому интересна эта тема — прошу под кат.
Сразу хочу предупредить, что все, описанное в этой статье — это мой собственный опыт, поэтому, если вам известны более оптимальные способы решения упомянутых задач, то я буду рад, если вы поделитесь им в комментариях.
Содержание
Игровые интерфейсы
В общем, UI в играх является полностью функциональным элементом, который только опосредованно влияет на геймплей. Его главная задача — донести до игрока необходимую информацию. В принципе, можно взять тот же Arial и отобразить им количество здоровья, патронов и счет (если речь идет о шутере). Да, это повлияет на эстетическую составляющую, а у особенно впечатлительных игроков может пойти кровь из глаз, но со своей задачей разработчик в таком случае справился: донес информацию до игрока.
Но это радикальные методы. Понятно, что самый лучший интерфейс — это тот, который игрок не замечает вплоть до момента, когда он ему понадобиться. И количество патронов на самом оружии, и уровень жизни, который отображается прямо на протагонисте (привет, Dead Space!) — все это на совести геймдизайнера. Мы же, как разработчики, должны воплощать эти прихоти в жизнь. Какие же возможности для создания интерфейсов есть в Unity?
Что такое Canvas?
Canvas для Unity UI — это область, внутри которой размещаются все элементы пользовательского интерфейса. То есть, когда мы создаем новый игровой объект, то Сanvas для него создается автоматически.
Начиная с версии 4.6, для работы с элементами пользовательского интерфейса используется новая версия Unity UI. Как и во время работы с обычными объектами, элементы HUD организовывают в иерархии, корневым элементом которых является объект с компонентом Canvas. При этом порядок в иерархии определяет порядок рендера: объекты, которые находятся в самом низу, отрисовываются последними и, соответственно, располагаются поверх остальных объектов.
Не имеет значения, какой тип приложения вы разрабатываете — как 3d, так и 2d игры используют одну и ту же логику работы с UI. То же самое касается платформы. Не имеет значение, это Web с HTML5 или игра для Android — достаточно будет описать одно полотно Canvas.
Варианты отображения Canvas
За то, где именно будет отображаться Unity UI Canvas (в пространстве экрана или игрового мира) отвечает параметр Render Mode, у которого есть три режима:
Размещение элементов в Canvas
Для удобства проектирования каждый элемент UI отображается в виде прямоугольника. Для манипуляций с ними используется два главных компонента, Rect Tool и Rect Transform. Последний — это новый компонент, у которого кроме уже указанных полей есть особенное поле Anchors (Якоря).
Якоря определяют привязку элементов к размерам родительского элемента. У компонента есть 4 якоря, каждый из которых отвечает за одну из вершин элемента. Позиция и размеры элемента высчитываются на основе расстояния между вершиной и якорем, и позицией самого якоря. Позиция якоря, в свою очередь, определяется в процентном отношении от размеров родительского элемента. Таким образом, если все четыре элемента находятся в одном и том же месте, размер элемента будет постоянным. Если в одной точке находятся якоря одной плоскости (верхний и нижний или левый и правый), то элемент не будет растягиваться относительно этой оси. Если же якоря не находятся в одной точке, то позиция каждого якоря будет рассчитана в процентах и к полученной величине будет добавлено расстояние к вершине (она не изменяется).
Звучит сложно, не так ли? Но если провести 10 минут в редакторе, то все сразу станет на свои места.
Следует также сказать, что кроме якорей у Rect Transform есть также параметры Min, Preferred и Flexible Width и Height, которые можно переопределить с помощью компонента Layout Element, но обычно я его не использую.
Кстати, новая версия Unity UI Canvas позволяет использовать несколько приятных особенностей. Одна из них — это возможность полностью отключить весь UI для упрощения работы с самой сценой. За это отвечает пункт Layer в меню редактора.
Сперва кажется, что функционала, который предоставляет вышеупомянутый компонент Rect Transform, должно хватать для всех возможных задач. Однако недавно, создавая кастомный селектор для Facebook, я столкнулся с необходимостью группировать элементы определенным образом.
При разработке под мобильные устройства (если вы разрабатываете не только под iOS) девелопер сталкивается с проблемой сегментированности, когда его игры могут запускать как на телефоне с 2-дюймовым экраном, так и на устройстве с диагональю 9 дюймов. И это я еще молчу про планшеты. Что делать в такой ситуации? У нас есть несколько вариантов.
Разработка под экраны любых размеров
Почему бы не использовать Anchors?
Первое, что приходит в голову — использовать якоря. Да, если у вас простые экраны без большого количества дочерних элементов, анимаций и остальных фич для пользователей, то почему бы и нет? Но, если вы используете такой тип верстки, следует помнить, что происходит изменение размера, а не визуальное растягивание (скейл) элементов. Поэтому в текстовых компонентах параметр Best fit становится активным, а во всех элементах появляется необходимость контролировать соотношение сторон и привязку к определенным частям экрана или другим элементам. Лично я так и начинал верстать — и решение нашлось (хотя оно и не очень элегантно, но зато работает).
В пакете UI есть компонент Aspect Ratio Fitter. Он работает достаточно просто: в зависимости от типа и изменений в размерах родительского элемента, данный компонент меняет размеры собственного Game Object, сохраняя соотношения сторон.
Кстати, существует еще такой компонент, как Content Size Fitter, который работает «с другой стороны» — он изменяет размеры элемента в зависимости от его содержимого. Обычно он используется с дочерними Game Objects, которые содержат Text-компоненты, но также идеально работает с Layout Element и Grid Layout Group.
Преимущества использования Canvas Scaler
Сейчас я использую Canvas Scaler, ведь в таком случае компонент добавляется автоматически во время создания Canvas. Преимущество по сравнению с предыдущим подходом состоит в том, что все дочерние элементы растягиваются, а не просто изменяют свой размер, а значит, сохранится размер шрифта во всех текстах, а элементы со смещением в несколько юнитов будут выглядеть одинаково на всех экранах.
У Canvas Scaler есть три режима работы:
Последний элемент — мой любимый, поскольку позволяет не обращать много внимания на фрагментацию экранов, выбрав свое целевое разрешение, после чего Canvas оптимальным способом изменит собственные размеры. Поэтому предлагаю рассмотреть его подробнее.
Как я уже упоминал, у этого режима есть свое целевое разрешение, в соответствии с которым Screen Match Mode будет изменять текущее полотно Canvas. Сам Match mode может принадлежать к одному из следующих типов:
И хотя у каждого из режимов есть свои преимущества, но все же моим фаворитом остается Match Width Or Height. У этого режима есть еще одна полезная особенность — для него можно указать, какая из осей будет целевой, и с какой осью будет осуществляться сравнение (вся область Canvas будет увеличиваться в зависимости от ширины, высоты или обоих этих показателей).
Для этого используется параметр Match, в котором через переменную float [0;1] задается соотношение влияния сторон. Таким образом, 0 — изменения будут подгоняться по ширине, а 1 — по высоте. Если целевое соотношение сторон находится в горизонтальной ориентации, то когда Match = 0, мы получаем эффект Expand, а когда Match = 1 — Shrink (в вертикальной ориентации все будет наоборот, 0 будет давать Shrink, 1 — Expand).
Последний параметр Canvas Scaler — это Reference Pixels per Unit, который определяет, сколько пикселей будет в одном юните UI-элемента. Его значение по умолчанию равно 100 метрам. Он работает с Image-компонента, поэтому если у вас каждый метр — это 100 пикселей изображения и вы используете физику Unity, то вам подойдет это значение.
Создание кастомного селектора
Как я уже говорил, в моем случае задача состояла в написании кастомного селектора для Facebook. То есть предполагалось наличие динамически сформированного списка, из которого элементы могли удаляться «на ходу». И хотя работа с Facebook API — это отдельный разговор, предлагаю завершить обзор возможностей нового UI, а точнее — Layouts.
Как видим, некоторые компоненты мы уже рассмотрели. Поэтому давайте по очереди знакомиться с теми, про которые мы еще ничего не знаем.
Canvas Group
Этот компонент легко и просто настраивать, но, тем не менее, он очень действенный. Позволяет оперировать свойствами всех дочерних элементов объекта. Полезен, когда требуется сделать определенную панель неактивной или запретить реагировать на взаимодействие с пользователем (через Raycast).
Для лучшего понимания достаточно будет создать 2 одинаковые панели с несколькими кнопками и чекбоксами, одна из которых будет содержать этот компонент, и просто поменять значения параметров.
И наконец-то самое интересное.
HorizontalLayoutGroup и VerticalLayoutGroup
Два компонента размещают все дочерние компоненты горизонтально или вертикально друг за другом. Можно задать как отступы внутри корневого элемента, так и между дочерними элементами (padding и spacing). Кроме того, объекты можно отцентрировать относительно краев родительского элемента.
Учитывая то, что элементы будут находиться только в одной плоскости (горизонтальной или вертикальной), последний параметр, который состоит из двух чек-боксов, позволят растянуть все дочерние элементы до размеров родительского по высоте или ширине.
GridLayoutGroup
Если вам нужно создать таблицу из однотипных элементов, то это просто дар богов! Как и у предыдущих элементов, у него есть поля padding и spacing, но при этом дальше нам требуется задать размеры дочернего элемента, в соответствие с которыми будут приводиться все объекты, добавленные к родительскому.
Дальше следует задать StartCorner, который будет определять позицию первого элемента, и StartAxis, который будет указывать на ось заполнения (по строкам или столбцам). Так, если выбрано Vertical, то элементы будут заполнять текущий столбец до тех пор, пока не достигнут границ родительского элемента, а затем перейдут на новый. С Horizontal все происходит наоборот — заполнение будет происходить по строкам. Задав, как и откуда добавлять элементы, логично будет указать их выравнивание.
Последний параметр — это Constraint, который определяет, будет ли у данной разметки определенное количество столбцов или строк или же этот показатель будет высчитываться, исходя и размеров родительского элемента. Стоит помнить, что в отличие от остальных компонентов разметки, GroupLayout переопределяет размеры дочерних элементов на Cell Size (его не интересуют показатели Min, Preferred и Flexible sizes).
Кроме того, существует возможность комбинировать GridLayoutGroup с ContantSizeFitter, однако у меня такой необходимости не было. Судя по официальной документации, с этим не должно возникать проблем.
Вот как выглядел конечный результат в моем случае:
Каждый элемент добавлялся динамически, инициализируясь из префаба элемента. Как видим, изменить размеры или позицию элемента мы не можем, поскольку эти значения определяются в GridLayoutGroup.
Кстати, элемент был сверстан отдельно от панели, которая должна была удерживать этот объект и дальше. Все, что от меня требовалось — скопировать размеры элемента в CellSize компонента GroupLayout. А вот хардово забить размеры элемента я смог с помощью CanvasScaler, которому задал тип растягивания Match Width Or Height.
Вот и все, что касается возможностей нового UI. Эта статья — попытка систематизировать для себя полученный опыт, но если она пригодится и вам, то я буду искренне рад.
So Long, and Thanks for All the Fish.
Нужен MVP, разработка под iOS, Android или прототип приложения? Ознакомьтесь с нашим портфолио и сделайте заказ уже сегодня!
Холст (Canvas)
Компонент Canvas представляет собой абстрактное пространство, в котором производится настройка и отрисовка UI. Все UI-элементы должны быть потомками игровых объектов, к которым присоединен Canvas. Когда вы создаете UI-элемент из пункта меню (GameObject > Create UI), Canvas будет добавлен автоматически, если его нет в сцене.
Свойства
Подробности
Одного холста для всех UI-элементов вполне достаточно, но и несколько холстов в сцене допустимо. Также, возможно использование нескольких холстов, когда один выставляется дочерним элементом другого, для оптимизации. Вложенный холст использует тот же режим рендеринга (Render Mode), что и родитель.
В этом режиме холст масштабируется для заполнения всего экрана, а затем рисуется напрямую, не ссылаясь на сцену или камеру (интерфейс написуется даже если в сцене вообще нет камеры). Если размер или разрешение экрана меняются, интерфейс автоматически перемасштабируется. Интерфейс рисуется поверх любой другой графики, такой как вид из камеры.
Интерфейс рисуемый поверх объектов сцены
В этом режиме, холст отображается как если бы он был нарисован на плоском объекте, на некотором расстоянии заданной камеры. Экранный размер интерфейса не меняется с расстоянием, т.к. он всегда масштабируется чтобы в точности заполнять пирамиду видимости камеры (camera frustum). Если размер или разрешение экрана, или пирамида видимости, изменяются – интерфейс автоматически перемасштабируется, чтобы помещаться. Любые 3д объекты сцены, расположенные ближе к камере, чем плоскость интерфейса, будут отрисованы “над” интерфейсов, в то время как остальные объекты, находящиеся за плоскостью, будут загорожены.
Интерфейс в режиме Camera mode с объектами сцены спереди
World Space (пространство мира)
Интерфейс в пространстве мира, пересекающийся с объектами сцены