Pull to refresh

Comments 25

Вроде все хорошо, пока не вспомнишь:
1. насколько часто выходят фиксы юнити (не чаще раза в 2-3 месяца) и ngui (бывало по нескольку раз на неделе для важных фиксов).
2. Ngui — это не только рендер, но и куча хелперов обвязки. С этим у штатного гуя все плохо, надо все писать с нуля, либо портировать с нгуя, но зачем, если можно брать и пользоваться.
3. Атласирование — уже разрешили делать на basic-версии юнити?
4. Порядок отрисовки согласно порядку созданя GameObject — это… это прекрасно. Идиот, такое придумавший, однозначно никогда не имел опыта работы с динамическим гуем. Теперь порядок создания виджетов прибивается гвоздями или его придется каким-то образом контролировать относительно других виджетов.
1. После беты rc1 уже не так часто. До этого часто меняли архитекуру UI и если перескачить через ступеньку, UI мог слететь нафик.
2. Базовый набор хелперов есть — есть Layout'ы, Drag&Drop, ContentSizeFitter — вобщем вполне самодостаточный базовый набор, чтоб без кодинга собрать не особо извращённый UI.
3. Если на про не хватает — атласы можно напрячь делать художника или сделать небольшую тулзу, собирающую спрайты в один атлас.
4. Порядок отрисовки зависит от sibling index — тоесть как оно в дереве иерархии висит.
У Transform есть набор функций для его модификации — SetAsFirstSibling, SetAsLastSibling, SetSiblingIndex

В целом на новоый UI получилось полностью перенести то, что было сделанно на NGUI, и успешно доделывать новые экраны на UI — пока не поподалось задачи, чтоб не вышло её реализовать.

Порой приходится поломать мозг, прежде чем получается заставить всё это работать как задуманно — я привык несколько по другому мыслить в рамках UI (раньше в основном писал на C++ и там у нас была своя WYSWYG система UI), особенно когда выстроишь запутанную иерархию из лайутов, контент сайз фиттеров и т.п.
3. Если на про не хватает — атласы можно напрячь делать художника или сделать небольшую тулзу, собирающую спрайты в один атлас.

Атласы иногда приходится пересобирать довольно часто и не все художники имеют доступ к коду. Да, написать можно что-угодно, но зачем, если есть нгуй :)
4. Порядок отрисовки зависит от sibling index — тоесть как оно в дереве иерархии висит.

Это я в курсе. Вот пример:
*) магазин предметов, все предметы инстанцируются динамически, ничего в сцене нет в момент старта.
*) каждый предмет представляет собой иерархию виджетов (спрайты подложки, иконки, оверлейной иконки, дополнительных штук), содержащих данные из разных атласов (например, атлас контролов-кнопок и атлас иконок предметов), порядок отрисовки четко настроен так, чтобы виджеты из одинаковых атласов рисовались в непрерывном пространстве в сцене — получается хорошая оптимизация по батчингу. Здесь слово «сцена» — не ошибка. Циферки порядка отрисовки имеют сквозную нумерацию в пределах панели и это позволяет гибко настраивать рендер.
*) настроенная иерархия предмета сохранена как префаб с управляющим классом (допустим, VisualStoreItem) с последующей загрузкой и инстанцированием, остается только поменять родителя и восстановить скейл на тот, что в префабе. Все циферки порядка отрисовки сохраняются как были настроены, ничего больше делать не нужно: ни отслеживать порядок элемента в префабе, ни в контейнере предметов магазина.
Вопрос — как это сделать в новом гуе без контроля порядка отрисовки всей иерархии виджетов в каждом инстанцируемом предмете?
В целом на новоый UI получилось полностью перенести то, что было сделанно на NGUI

Пока нет, исключительно базовый функционал 3.0.х с кучей особенностей.
3. — у кого нет про, тем наверно будет не так удобно

4. Сиблинг влияет на то, кто кого перекрывает. А вот в каком порядке оно именно отправляется в GPU — это как-то не заботит — настроек, чтоб как-то на это влиять в UI нет. Судя по всему он сам сортирует и оптимизирует, т.к. с переделкой на новый ui fps ни как не просел (к примеру HUD использует спрайті из нескольких разных атласов).

Мне кажется они улучшили систему батчинга (детально не изучал этот вопрос — просто по ощущениям использования — т.к. раньше, к примеру, системы частитц его рвали часто и фпс просаживали, теперь с этим получше стало).
А вот в каком порядке оно именно отправляется в GPU — это как-то не заботит

Заботит. На сложных гуях можно сократить количество отрисовок до 2 раз путем ручного указания «как поздно» будет отрисован виджет.
Мне кажется они улучшили систему батчинга

К сожалению, в автоматическом режиме это не сделать — transparency геометрия может быть отрисована исключительно back-to-front и просто так группировать геометрию, разнесенную по «глубине» отрисовки нельзя — будут ошибки рендера. Поэтому отрисовка будет группировать только последовательные куски, принадлежащие одному атласу. Как только находится виджет из другого атласа — батч ломается. Это относится так же к нгую, но там можно руками подхачить циферки глубины отрисовки, в том числе и в префабе.
я к тому, что проблему с порядком отправки в рендер решает Unity, и что там под капотом — скрыто.

У NGUI есть плюс, в том что его все внутренности висходниках — можно было посмотреть, или при желании поправить (не правил, но идею генерации геометрии брал от туда, для проекта другого, где не было NGUI).
Но опять же — пока что переделка интерфейса с NGUI на UI ни как не повлиял на производительность, даже учитывая то, что хад в 3l игре где-то из 4х аталсов сейчас рисуется.
ВОбщем по результатам опыта ещё на бэте я решил, что new UI имеет права на жизнь, и пока что проблем с производительностью в нём не испытываю. Может какой-то специфический случай всё и испортит.

Если уже весь проект на NGUI и в высокой степенью готовности, то смысла переезжать нет конечно.
Из личного опыта, хочу посоветовать избегать оптимизаций основаных на «недокументированных» возможностях технологий… что будет если изменится батчинг в юнити или изменится АПИ NGUI? Сколько займет трудозатрат добавить новые фичи? Что будет если количество элементов вырастет в двое и оптимизация уже не поможет?
У вас наверняка были причины так сделать, но дабы уберечь других, скажу — старайтесь участвовать в обсуждении требований к интерфейсу своего проекта, добавляйте асинхронную подгрузку элементов, разбивайте элементы на часто/редко используемые, группируйте. Подходов борьбы с этим зло много, главное вовремя его заметить!

И подытожу, все конечно зависит от конкретных задач, но с новым Unity UI я пока видел только прирост производительности и надеюсь эта тенденция в будущем будет только улучшаться!
хочу посоветовать избегать оптимизаций основаных на «недокументированных» возможностях технологий…

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

Она не может не помочь, если есть понимание того, как работает рендер юнити.
все конечно зависит от конкретных задач, но с новым Unity UI я пока видел только прирост производительности

Нужно уметь использовать инструмент и понимать как оно работает дальше. Пока производительность повышается за счет исправления багов и начальной попытки батчинга (эпичный по длине фиксов changelog к 4.6.1).
Из личного опыта

Мое основное направление — исключительно мобильные платформы, где производительность наиболее критична. Основное требование работодателя — должно работать без лагов от iPhone4/Tegra2 до топовых девайсов. Мне, как indie-девелоперу, ничего от прошки на мобилках не нужно — пока штатный гуй будет требовать для атласирования прошку, я буду использовать готовое и проверенное годами решение с уже обкатанной механикой использования.
Вы забываете, что это все можно сказать и про NGUI, а внесение изменений под свои нужды, концептуально ничем не отличается в этих продуктах, я даже лучше предпочту форк-пулл реквест.

У такого рода оптимизаций, как колдовство над батчингом, почти всегда есть порог, после которого они уже не приносят прироста производительности. Даже если нет возможности ограничить отображаемое количество элементов UI на низкопроизводительных девайсах, я предпочту разделить иерархию по слоям, каждый их них положить в отдельный атлас и включать слои по мере надобности/видимости. Все это поддерживается в Unity из коробки.

Я с недавних пор тоже инди-девелопер и тоже предпочитаю использовать проверенные решения, но всегда открыт для «пощупать что-то новое» и особенно готов поддержать инициативы открытия исходного кода!
PS: UI точно также и делаем с префабами, как у вас — только в нашем случае это карты с развитой иерархией виджетов.
Инстанциировал префаб, подцепил его к родителю, а на родителе layout сам выстроил карты в панели согласно её настроек. А сиблингом играться приходится не часто — например аватары (опять же составные обьекты из префабов) стоят с перекрытием, и бросить активную аватару, говорящего персонажа на передний план.
Спасибо за отличную статью. Пока материалов по новой UI практически нет, и ваша статья хорошо восполняет эту нишу.

Я не смог разобраться, как передать параметр в событие нажатия UI-кнопки. Так и пришлось делать разные обработчики по каждую кнопку. Может, вы сталкивались с этим?
Мне в начале помогли вот эти два туториала (помимо стандартных туторов из елпа юнити):
Базовые концепции — www.youtube.com/watch?v=JrlFMwLI1fw
Лейауты — www.youtube.com/watch?v=DAdW_K44Dao

Если у вас функция обработчик принимает string/int/bool/float то его в настройках оработчика клика можно вписать.
Ну а если обьект — то можно его туда просто перетянуть.

Но тут в целом концепция тактая, что обработчик привязан к какому-то обьекту и компоненте функции на нём.
Мне не хватало какой-то глабальной системы обработки события и я сделал менеджер, набор событий (определяется перечислением).
А на копку вешаю компонент, который в OnClick посылает событие, выбранное в настройках.
А все кому надо, подписываются на указанное событие — кода не много пришлось написать, зато куда как гибче стало.

Кстати недавно тут кто-то писал статью о создании простой системы событий в Unityю
Как это сделано в нгуе:
*) допустим, вешаем компонент кнопки — UIButton.
*) настраиваем вызов колбек-метода по нажатию.
*) в самом колбеке в момент нажатия можно потрогать статик свойство UIButton.current — там будет содержаться UIButton, вызвавший колбек. С него уже можно получить любые компоненты через gameObject или как-то еще.
Это справедливо для всех компонентов нгуя — везде при вызове колбека можно узнать, кто вызывал. Как оно сделано в штатном гуе сказать не могу, не было нужды пользоваться им.
Точно такое же реализуется и в новом UI. Достаточно создать публичный метод с аргументом GameObject, а на кнопке в этот параметр указать саму кнопку. Или использовать в качестве аргумента int и на кнопке прописать его номер. Но лично мне проще при динамической генерации кнопок какие-то свойства закладывать в name и уже внутри обработчика определить допустим его порядковый номер.
Если навешивать события програмно, то в новом UI вообще никаких проблем:
button.onClick.AddListener(delegate{
     Debug.Log(button);
});


Но с новой системой событий, которая для триггеров, передает данные объектом BaseEventData (http://docs.unity3d.com/ScriptReference/EventSystems.BaseEventData.html). В нем нас интересует свойство selectedObject — ссылка на объект который инвокнул событие. Тоесть можно делать вот так:
public void MethodName(BaseEventData baseEventData) {
     Debug.Log(baseEventData.selectedObject.name);
}
Рад, что она вам пригодилась!

Все зависит от задачи, можно например сделать один обработчик с аргументом типа enum, который описывает возможные варианты поведения, а в редакторе, при выборе обработчика события onClick, в выпадающем списке, выбрать необходимое значение enum.

Но на мой взгляд это пол дела, если уже делать все красиво, то лучше навешивать события програмно при создании/инициализации. Например используя docs.unity3d.com/ScriptReference/Events.UnityEvent.html

C#
button.onClick.AddListener(delegate{methodName(arg);});


или для Unity Script
button.onClick.AddListener(function() {
     var closuredArg = arg;
     methodName(closuredArg);
});

UFO just landed and posted this here
Не успел добавить…

Использвал офф тутор + справку. Хочу следующие уроки сделать уже ближе к практическим задачам.

До этого использовал NGUI — да, не хватает всяких UICenterOnChild и т.д., но думаю скоро какой-нибудь добрый человек сделает ассет с доп. скриптами.

В целом — новый UI хорош и последние демки/прототипы делаю на нем.
Круто! Это отличный материал, который очень многим поможет. Думаю все согласятся, что лучше их максимально популяризировать (это я намекаю на статью ;)
Отсмотрел все, понравилось несмотря на иногдашние слова типа, ну это я пока не понял как работает ) Я уже начала мини игрушку делать на Unity UI, очень все удобно )
Одного не понимаю, почему они просто не купили/наняли NGUI с потрохами? Неужели не смогли договориться с разработчиком NGUI по деньгами? Во всяком случае, после использования NGUI это первое что приходит в голову.
автор NGUI работал как раз над созданием Unity UI на первых порах. Он даже выступал с докладом на каком-то мероприятии. Почему он ушел — я не знаю, но до сих пор пилит и развивает свой продукт.
Потому, что денег NGUI приносит больше, и он понял, что если забьет на свой проект и перетащит все плюшки в родной UI, то основной проект умрет.
Спасибо за статью, теперь с центровкой и масштабом проблем нет.
Sign up to leave a comment.

Articles