Breakdown. Процедурный генератор парков на Unreal Engine 5.3 Часть 1
время прочтения статьи около 15 минут
Всем привет! Это мой первый пост на DTF и я решил поделиться информацией о создании процедурного генератора парковых зон при помощи PCG плагина в Unreal Engine 5.3. Брейкдаунс, так сказать. P.S. Пост рассчитан на тех, кто более или менее в теме, так как я не делаю подробного описания каждого решения, да и не туториал это.
Я художник по окружению и особенно люблю процедурку. Само собой меня заинтересовал PCG плагин и я решил что-нибудь собрать. Заранее отмечу, что генератор собирался в версии 5.3 и некоторые новые возможности плагина в более поздних версиях движка могут упростить реализацию тех же задач.
Что есть PCG плагин?
Начиная с версии 5.2 в Unreal Engine доступен плагин процедурной генерации, который позволяет реализовывать различные методы спавна ассетов на уровне, их взаимодействия с ландшафтом, водой и так далее. Функционал плагина позволяет реализовывать процедурную логику быстрее и проще из-за наличия готовых узлов для конкретных задач, по сути – все то же самое, что было можно реализовать по средствам блюпринт в более ранних версиях движка получило новую обертку и теперь процесс разработки стал быстрее.
Задачи
Итак, поставленная мной задача звучала следующим образом: Мне нужен интуитивно понятный и удобный генератор для левел арта, при помощи которого я смогу быстро воспроизводить городские парки или зеленые зоны на тротуарах и вдоль дорог, при необходимости быстро менять габариты, форму и наполнение. Генератор не должен быть переполнен настройками, но должен иметь возможность расширения функционала при необходимости. Быстрота его работы и оптимизация также стояли не на последнем месте. И, конечно, всегда хочется сделать максимально элегантное решение, которое сочетает простоту и функциональность.
Решение
1
Мне важно, чтобы результат работы генератора был виден как можно быстрее, без длительных предварительных настроек, а также, чтобы он был максимально дружелюбным для левел артиста. Буквально – поместил на сцену, два клика и готово, а уже дальше можно проводить тонкую настройку и все что душе угодно. Для достижения такого эффекта я сразу отказался от концепции «максимум возможностей на все случаи жизни», так как в этом случае процесс предварительной настройки может затянуться и перебить желание пользоваться инструментом.
2
За основу генератора я взял вариант с масштабируемым боксом, габариты которого изменяются при перемещении трансформера прямо на игровом уровне. Я задаю габариты, а все содержимое генератора подстраивается под этот объем. Вариант со слайдерами в настройках блюпринта мне показался менее элегантным.
Выбор такого варианта изменения габаритов накладывает определенные ограничения с самого начала. Я вынужден взять за основу для генерации точек вид семплера «Volume Sampler». Позже я расскажу почему это является ограничением.
3
Вся логика генератора укладывается в три блупринта и некоторое количество PCG графов, в которых находится разбитая на блоки логика генератора. Использовать Сабграфы с отдельными логическими блоками, помещенные в главный граф – хороший подход, если ваша логика достигает внушительных размеров. Во-первых, это намного более удобочитаемо, во-вторых, сабграфы, как инстансы можно многократно использовать, меняя только входящие в них переменные настроек.
Я сделал два генератора, один из которых отвечает за создание парковых зон, а второй за генерацию зеленых зон на тротуарах, которые могут выглядеть, как последовательность огороженных бордюром клумб, в которых растут деревья. Поместить возможности обоих генераторов в один означает многократно усложнить логику и в итоге производительность инструмента.
4
Так выглядят главные блупринты генераторов. Здесь я ограничиваю возможность скейла и поворота генератора на уровне (в этом нет необходимости, так как все манипуляции происходят в панели настроек генератора). Также задаю условия, при которых в генераторах меняются режимы: это сделано для того, чтобы генератор было невозможно сломать при работе на уровне. В какую бы сторону вы не потянули трансформер, какого бы размера не задали объем – генератор отработает корректно. Также в главных блупринтах происходит передача данных из некоторых переменных в PCG ноды.
Это все переменные из генератора парковых зон. В генераторе зеленых зон их в три раза меньше. Можно было бы поместить все это в массивы и структуры, но я поленился углубиться в этом направлении. Возможно, позже проведу оптимизацию и сделаю апгрейд.
Так выглядит основной PCG Graph генератора парковых зон. Большее количество логики в нем заключено в сабграфы – т.е. сохранено как отдельные файлы PCG Graph. Как я упомянул ранее это оптимальный подход при увеличении размера логики.
А так выглядит граф генератора зеленых зон. Здесь нет сабграфов и логики намного меньше. Это не удивительно, ведь у этого генератора намного меньше возможностей.
5
Далее начинается процесс создания точек в нужных координатах, сортировка так сказать по назначению. Мне нужна поверхность грунта, и основой для этого служат точки, полностью заполняющие пространство бокса. Выборка точек по краям бокса послужит основой для линий деревьев, кустов, забора, лавочек, фонарей и декалей с грязью и лужами. В основе этот процесс заключается в простой арифметике, где я удаляю ненужные и оставляю нужные точки, а также в тонкой настройке различных отступов, плотности точек и так далее. На этом этапе я работаю в режиме дебага и визуализирую расположение точек с помощью встроенных примитивов (кубов). Важно тестировать инструмент в процессе работы, изменять его габариты, подкручивать значения в нодах, если что-то перестает работать корректно.
Так как у ноды «Volume Sampler» есть своя специфика, (упомянул об этом в начале статьи) то некоторые ограничения приходится обходить внедрением дополнительной логики в кастомном блюпринте для ноды «Execute blueprint» в PCG. В частности, нода «Volume Sampler» не имеет локальных координат трансформа и поворота и точки спавнятся относительно мировых (по крайней мере так обстоят дела в версии для UE 5.3) Чтобы все работало корректно, работа с генераторами происходит: во-первых, с привязкой к сетке с шагом в 1 метр (должна быть активирована привязка к сетке во вьюпорте UE), во-вторых корректировка положения генератора на сцене на значения отличающиеся от шага в 1 метр происходят путем оффсета в мировых координатах (реализованно как дополнительная настройка), в-третьих, создается кастомный блюпринт с корректировкой поворота точек относительно родительского актора. Если с первыми двумя пунктами все просто, то третий выглядит посложнее, но на самом деле ничего сложного
Так выглядит блюпринт для корректировки поворота точек, состоящий из двух функций.
Вкратце: получаем массив точек из PCG, вытягиваем их трансформы, из трансформов берем вращение по оси Z, далее берем информацию о вращении родительского актора, передаем вращение актора по оси Z PCG точкам, возвращаем обновленные данные обратно в массив. Эту конструкцию я использую в генераторе зеленых зон, с помощью которой я корректирую повороты линий деревьев, фонарей и т.д. в зависимости от того, какую ось (X или Y) я выбираю для направления.
Не знаю, появились ли локальные координаты у ноды «Volume Sampler» в версии движка 5.5, но это бы облегчило создание подобных генераторов. К слову, если вы берете за основу ноду "Spline Sampler", то там локальные координаты есть по умолчанию.
6
После создания определенных логических блоков в основном графе я сохранял их как отдельные графы и вот что там внутри:
На всю эту логику я сделал соответствующее наполнение в виде набора отсканированных ассетов, (еще я занимаюсь производством сканов и планирую об этом написать пару статей в дальнейшем), каждый из который не является случайным по габаритам, расположению пивота и т.д. Т.е. генератор подразумевает использование сторонних ассетов, у которых габариты и масштаб могут быть любыми, и пивот может быть где угодно, все это подгоняется на места с помощью настроек генератора (не автоматически), но я делал для себя и мои ассеты правильные))
Результат
Генераторы получились весьма быстрые и функциональные, и как и все в этом мире имеют свои достоинства и недостатки.
Из хорошего: получилось сделать дружелюбный инструмент для Левел Артиста, перетаскивай блюпринт на сцену, двигай трансформер и все начинает оживать. Получилось сделать интуитивным: настройки, разделенные на смысловые блоки не ставят в затруднительное положение, не отнимают много времени, не требуют инструкций и технической документации. Легко и просто заполнить внушительные территории за небольшой отрезок времени, подходит как для блокинга так и для продакшена. Все ассеты можно заменить на любые другие в панели настроек генератора, не нужно лезть в графы. Можно сделать любой апгрейд в рамках логической базы.
Из минусов: Только прямоугольная форма зон, так как создание парков неправильной формы или с радиусами, требует иной реализации логики. Слабо оптимизированная логика по части переменных, можно свернуть всю эту рутину в структуру. Не реализовано взаимодействие между несколькими зонами (например, когда вы располагаете две зоны внахлест, то бордюры и заборы подстраиваются под новые габариты и направляющие - реализовать можно довольно просто, сочтем за возможность апгрейда).
Еще есть много разных хотелок, которые можно уместить в эти генераторы, но, как обычно, руки не доходят. Про визуальное наполнение, т.е. материалы, сканированные ассеты и, в особенности деревья, я напишу отдельно, дабы не раздувать статью.
Надеюсь вам удалось найти здесь что то полезное для себя и возможно, этот пост кого-нибудь вдохновит. Мне было бы крайне интересно услышать ваше мнение о подаче материала, насколько удобно/интересно или неудобно/неинтересно читать, а так же любые вопросы или мнения.
Здесь можно посмотреть, что в итоге получилось
Спасибо и успехов в изучении!