Об планировании виджетов в Unreal Engine. Быстропост.
Честно говоря, я не являюсь правильным спикером по этой теме. Причина для этого до банальности проста. Я в первую очередь разработчик - программист. Это делает меня слегка предвзятым в сторону UI, так как для меня некая условная красота UI почти не является важным параметром. А вот, скажем, удобство, скорость изменения и правильность концепций UI - вполне. Поэтому, стандартная плашка. Я не претендую на абсолютную истину. Давайте начнем.
В первую очередь определим что мы имеем ввиду под UI. В посте я буду говорить об UI только как об системе User Widget, хотя это разумеется не единственная система UI. Проговорим также довольно банальные факты - UI, это а первую очередь оболочка. Основная ее обязанность - вывод информации и изменение по запросу пользователя. Оболочки геймплейной логики приемущественно не должны знать об существовании UI. Хотя лично я дозволяю ряд исключений, приемущественно в владеющих (прочитайте мой быстропост про декомпозицию) объектов, вроде контроллера игрока. Указатели на классы UI или некую логику зависимости UI от сущности также можно оставить в не UI обьекте. Однако вся остальная логика по инициализации, настройки и тд должна проводится на стороне UI. Ui бывает статистическим и динамическим. Статический UI это UI "экранный", другими словами не изменяется при изменении положения чего бы то ни было на экране. Второй - динамический, в Unreal это как правило Widjet Component. Это UI прямо зависящий от положения объектов на сцене. Выбор за стилем UI за вами. Статический куда проще контролировать и проектировать, так как вы заранее при правильном планирование знаете, как будет выглядеть любое из состояний UI. Это также удобно для игрока, поэтому статика является пожалуй, более распространенным UI стилем. Динамический же вариант довольно удобен, особенно при небольшой модификации перемещения UI. В особенности динамический UI хорош в стратегиях, где от положения виджета напрямую зависит геймплейной опыт.
Основных задач при планировании три.
1. Максимальная применимость. Чем чаще используется виджет, тем лучше.
2. Самоинициализируемость. Принцип тот же что и с компонентами. Чем меньше сил требуется для инициализации виджета, тем лучше.
3. Размерность. Виджет должен иметь возможность быть читаемым для любых устройств.
Первая и вторая часть могут конфликтовать между собой. К сожалению, единого правильного подхода к UI я все ещё не сформировал, поэтому могу ограничится советами, которые помогают мне не путаться в кошмаре UI.
1. Делите код на виджеты. Любые достаточно крупные компоненты, имеющие единую логику создания и шанс на дублирование должны быть созданы как отдельный виджет.
2. Заведите себе библиотеку "модульных" виджетов. Это простейший список виджетов, во многом дублирующих функционал движковых slate, которые вы будете применять во всех частях проекта. Например, это может быть кнопка с надписью, слайд с обозначением значения и тд. Делается это для того, что бы на поздних стадиях развития проекта вы могли легко менять его стиль под себя, не перенастраивая пол проекта.
3. Старайтесь обеспечить визуализацию данных внутри Widjet, а не вне ее. Например, если вам нужно выставить значение имени и силы главного героя, создайте функцию Initialization, в которую будете подавать эти значения и уже внутритой функции выставите в нужные поля значения. Не стоит получать поля (slate) из Widjet Parent. Это некрасиво, начнет путать вас и сделает ваш код менее модульным.
4. Используйте систему Child - Panel. Многие элементы требуют перебора некого заранее не тзвестного количества объектов и инициализации виджетов под них. Всегда структуруйте эти моменты под два класса, каждый из которых будет обеспечивать свою часть логики.
5. UI, особенно статический, условно, можно поделить на 3 вида - Ingame , IngameMenu, OutgameMenu. Я предпочитаю для каждого отдельного вида создавать отдельный компонент, который потом добавляется в HUD и отвечает за инициализацию и прочее. Так уменьшается связанность. Каждый из компонентов инициализирует свой класс виджета Main Widjet. Это ваш главный планировщик UI. Именно здесь вы будете планировать, как будет выглядеть верхний, и , по сути, крайний вариант вашего UI.
6. Не пытайтесь достичь идеала в размерности Widjet. Разумеется, это не отменяет стандартных примеров, вроде использования Scale на текст и тд, но как бы вы не старались, маловероятно, что вы сможете организовать адекватный Scaling для Child Widjet. Поэтому, рекомендую не переживать по этому поводу и использовать Size Box для Child Widjet с выставлением минимальных значений.
Собственно, все:)