Как генерировать разных персонажей, а не рисовать каждого вручную?

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

Сгенерированный персонаж из Galaxy Pass Station. Олег Савин, Дмитрий Зайцев
Сгенерированный персонаж из Galaxy Pass Station. Олег Савин, Дмитрий Зайцев

А прежде чем я расскажу всё, попробуйте этот генератор в действии. Мы выложили его web версию тут: galaxypassstation.com/character-creator (для ПК и Планшетов)

Дмитрий Зайцев, один из авторов игры

Об игре, контекст

Игра называется — Galaxy Pass Station. Вы смотритель первой космической станции, куда прилетают гости со всей галактики. Есть множество инопланетных рас и культур, а в галактике правит Галактическое Правительство, которое устанавливает правила межзвездной миграции.

Подробнее об игре я рассказал в этой статье:

Мы используем Unity и C# для разработки нашей игры, но описанные подходы в статье годятся и для других движков. Можно сказать, что это статья первый наш девлог.

Разнообразие лиц

Наша игра предполагает, что вы будете часто видеть лица забавных и глупых пришельцев и землян. Они должны вызывать эмоции у игрока. Визуальный стиль игры нам помог упростить эту задачу.

Мы вдохновлялись «Футурамой» и «Риком и Морти». Мы выработали в пиксельной графике стиль, похожий на взрослую анимацию. Такая анимация предполагает довольно простую структуру лиц, которую можно собрать из частей. Мы пошли по похожему алгоритму, постепенно улучшая качество лиц.

Все персонажи сгенерированы, любые совпадения случайны Генератор из Galaxy Pass Station
Все персонажи сгенерированы, любые совпадения случайны Генератор из Galaxy Pass Station

Как это реализовано?

Представьте, что у вас есть десятки вариантов носов, глаз, ушей, причесок и т.д. Теперь их надо стандартизировать, выработать общие правила компоновки, чтобы всё друг с другом стыковалось наилучшим образом.

Дмитрий Зайцев, Программист

По отдельности нарисовали:

  • Каждую форму головы + варианты причесок под формы.
  • Разные части лица — уши, глаза, рты, и т.п.
  • Разные варианты костюмов.

Все это хранится через Scriptable Objects и редактируется прямо из редактора Unity. Выглядит это так:

Это из редактора Unity + Odin.
Это из редактора Unity + Odin.

ScriptableObject очень хорошая штука, чтобы хранить контент игры, если вы разрабатываете в соло, на мой взгляд.

На скрине представлены варианты формы головы для землян. На практике, мы выяснили, что проще всего хранить варианты причесок через форму головы. Если быть точнее, варианты чёлок, т.к. прически мы тоже храним отдельно.

Женское и Мужское

Наш генератор не предполагает выбора пола. Это исходит из особенностей нашей игры. В 90% случаев сама игра должна генерировать персонажа и определять, кто примерно получился — женщина, мужчина или что-то среднее.

Непонятно кто Генератор из Galaxy Pass Station
Непонятно кто Генератор из Galaxy Pass Station

Вы могли заметить выше на скрине, что у каждой части тела и лица встречается опция — Female. Это процент женственности части тела — от 0 до 1 (от 0% до 100%). Он помогает нам определить пол персонажа после генерации. Тут ничего сложного:

Берем среднеарифметическое female коэффициента от всех частей тела.

  • Если результат больше 0.6, то это скорее всего женщина.
  • Если меньше 0.4, то скорее всего мужчина.
  • Если от 0.4 до 0.6 — это может быть как мужчина, так и женщина.

Зачем игре нужно знать пол персонажа? Он фигурирует в документах посетителей станции, от пола зависит имя персонажа и многое другое. Но в целом, такой подход позволяет определять не только пол персонажа, но, например, уровень «забавности» персонажа или уровень чего-то еще.

Если каждой части тела задать коэффициент funny (т.е. забавность), то игра сможет определять, получился ли персонаж забавным. Удобно, можно чередовать забавных персонажей с обыкновенными, чтобы игрок не скучал.

Зерно генерации

Для генерации мы используем Random с определенным seed числом. По-русски, это зерно генерации.

Какой-то весёлый парень с усами Генератор
Какой-то весёлый парень с усами Генератор

Мы имеем объект Random со случайным или неслучайным числом-зерном, из которого генерируются варианты глаз, ушей, волос и т.п. Это позволяет нам сохранять сгенерированного персонажа, просто, храня его зерно.

Что если сгенерированный персонаж должен появится в игре несколько раз? Для этого не нужно хранить результат генерации, сгенерированную графику и т.п. Достаточно сохранить число и заново сгенерировать по этому числу персонажа!

Алгоритм работы Random предполагает, что передав на вход одно и то же число (т.е. зерно), вы всегда получите одни и те же случайные числа. Конечно, нужно сохранять порядок их генерации. Примерно так мы и делаем.

Сборка тела и лица

Мы используем шаблон с точками, в которых создаются определенные части тела и лица. Сделано это через prefab, в нём собран типичный персонаж. Для каждой инопланетной расы у нас свой шаблон или даже несколько вариантов шаблонов:

Вручную созданный шаблон
Вручную созданный шаблон

Генератор использует этот префаб, чтобы определить в каких локальных точках создавать глаза, рот и т.д. Мы сделали такой способ настройки, чтобы было проще визуально понимать, где нужно расставлять носы, рты и т.п.

Однако, что делать, если у нас разные пропорции формы головы? Мы используем всё тот же шаблон, только высчитываем разницу между формой головы в шаблоне и в той, которую создает генератор. Полученная разница — это коэффициент, на основе которого мы модифицируем координаты наших ушей, глаз, рта, носа и т.д. Тело и шея в нашем случае это одно целое и они не зависят от формы головы.

Тут есть один нью-анс. Мы часто используем Pivot точку самого спрайта, чтобы регулировать корректное смещение части тела. Например, для волос, точка pivot соответствует месту, откуда приблизительно должны расти волосы. С носом похожая ситуация.

Дмитрий Зайцев, Программист
Как генерировать разных персонажей, а не рисовать каждого вручную?

Pivot точки спрайтов позволяют нам регулировать место появления части лица или тела без изменении логики генератора.

Да, есть некоторые особенности и исключения из правил при генерации, например, брови привязываются к координатам глаз и их высоте, есть и другие исключения. Скорее всего, их будет больше когда мы начнем добавлять негуманоидных пришельцев в свой генератор.

Как рисовать для генератора?

Выше я писал про наш графический стиль. Всё, будет зависеть от него, но художнику нужно объяснять, что все части, которые он нарисовал, должны между собой стыковаться. У нас не было больших проблем с этим. Периодически, мы отбрасываем неподходящие варианты, хотя, их довольно мало.

Это наши усы и бороды
Это наши усы и бороды

Мне пока не нравятся многие наши бороды, и мы не научились нормально стыковать прически с лысиной. Поэтому лысины еще нет в конструкторе. Если вы рисуете в векторе, вам должно быть еще проще — не нужно выверять пиксели как делаем мы.

Мы не используем sprite sheets для частей тел. Да, это не очень оптимально для Unity, но в нашем случае, это не влияет на производительность так сильно, чтобы мы начали оптимизировать этот момент. Мы избавляем себя от ручной разметки спрайтов в редакторе, на что у нас уходило много времени. Однако, всегда можно использовать функцию Sprite Atlas из новых версий Unity. Она позволяет собрать несколько спрайтов в одну большую текстуру без особых изменений в игре.

Графику мы храним в одном цвете. Наш генератор, если это нужно, заменяет цвета на другие. Используется это для изменения цвета кожи, перекраски костюма и изменения цвета волос. Делаем это через создание новой текстуры с заменёнными пикселями с одного цвета на другой.

Дмитрий Зайцев, Программист

Есть еще вариант делать это через шейдеры, у нас есть в разработке такой вариант перекрашивания.

Конец статьи

Буду рад любым комментариям к статье, игре и т.д. Если вам понравилась игра, не забудьте её добавить к себе в список желаемого в Стиме, чтобы не пропустить релиз в 2022 году:

1818 показов
10K10K открытий
55 репостов
43 комментария

Сначала я подумал, что это попа

Ответить

а вместо отверстия pivot-точка

Ответить

Если только собачья

Ответить

О, какие люди

Ответить

Как генерировать персонажей

Вот так!

Ответить
Комментарий удалён модератором

Игра называется — Galaxy Pass Station. Вы смотритель первой космической станции, куда прилетают гости со всей галактики. Есть множество инопланетных рас и культур, а в галактике правит Галактическое Правительство, которое устанавливает правила межзвездной миграции.Звучит как “Papers, please”.

Ответить