Как Rubber Duck Games разработала бой с боссом в Evil Wizard

RUBBER DUCK GAMES Anonymous
Aug 17, 2023|15 Мин
Как Rubber Duck Games разработала бой с боссом в Evil Wizard
Эта веб-страница была переведена с помощью машинного перевода для вашего удобства. Мы не можем гарантировать точность или надежность переведенного контента. Если у вас есть вопросы о точности переведенного контента, обращайтесь к официальной английской версии веб-страницы.
Компания Rubber Duck Games, один из победителей конкурса GDC 2023 Best in Play, рассказывает о том, как они создали захватывающий бой босса. В этом гостевом блоге члены команды Банки и Серджио Ваджсвол проведут вас через весь путь, от дизайна и прототипа до анимации, тестирования, балансировки и окончательной доработки визуальных эффектов и звука для Evil Wizard.

Привет, читатели! Я Банки, гейм-дизайнер и продюсер в Rubber Duck Games. Наша наполненная юмором ролевая игра Evil Wizard уже вышла на Steam и Xbox, и я хотел бы рассказать вам о том, как мы разрабатывали бой с боссом.

Evil Wizard - это игра в жанре Metroidvania, в которой вы окажетесь на месте поверженного "финального босса", жаждущего мести проклятому герою.

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

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

Проектирование Хайльги

Давайте начнем с самого начала. Создать босса (и всех врагов) для Evil Wizard было непросто. Несмотря на то, что игроки сражаются против хороших парней, мы знали, что они должны выглядеть достаточно грозно, чтобы их можно было распознать как врагов.

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

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

Образец таблицы персонажей для игры "Хейлга злого волшебника" (Rubber Duck Games)

Разработав механику, мы могли перейти к следующему шагу: созданию прототипа.

Создание прототипов Hailga

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

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

Когда дело дошло до создания прототипа, вот что сказал наш ведущий программист Диего Ордоньес: "Хейлга была нашим первым боссом в Evil Wizard, и я впервые в жизни программировал босса. Я знал, что это сложная задача, поэтому начал с того, что делает каждый программист: разделил атаки на простые задачи и выполнял их по отдельности. У этого босса есть атаки, которые было просто выполнить, повторно используя снаряды".

"Атаки ледяной пули и ледяной ракеты ощущаются игроками совершенно по-разному: от одной просто увернуться, а другая представляет собой вызов во время боя", - продолжил он. "Ключевое различие заключается в том, как компонент атаки порождает ледяные снаряды, и в количестве снарядов, направленных на игрока. С помощью простых настроек мы смогли повторно использовать всю систему, чтобы представить две разные атаки. Все это прекрасно работало, пока мне не пришлось начать делать атаку метели".

Основная идея

Для боя с Хейлгой мы хотели привнести что-то новое и решили, что ветер может быть интересным. Это очень отличалось от всего, что мы делали для Evil Wizard, поэтому мне пришлось начинать с нуля. Основная идея заключалась в том, чтобы породить ветер в случайном направлении, чтобы переместить игрока к стене, усеянной шипами, которые могут нанести урон. Лучший способ противостоять этой атаке - укрыться за укрытием, поэтому на поле боя мы высаживаем несколько сталактитов, чтобы использовать их в качестве блокираторов ветра. Если игроки окажутся за ледяным сталактитом, ветер больше не будет действовать на них.

Развивающийся ветер

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

Сталактиты порождаются с помощью кругового коллайдера, чтобы получить случайные точки внутри него, а затем, используя эти позиции, создать сталактит со смещением по оси Y. Применяя coroutine, мы заставляем объекты падать, опуская ось Y - простая вещь. После того как сталактиты были спавнены, мы перешли к контроллеру ветра. Этот компонент работает как большой вентилятор прямоугольной формы, который вращается вокруг края круга.

Прототип контроллера ветра в бою с боссом "Злой волшебник". (Rubber Duck Games)

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

Блокировка ветра

Ветер также можно блокировать, как уже говорилось, с помощью ветрозащитного устройства. В этом компоненте есть BoxCollider2D, который проверяет столкновения с игроком. Если игрок окажется рядом с блокиратором ветра, OnTriggerEnter2D включит его, а когда игрок покинет коллайдер, OnTriggerExit2D отключит его. Это иллюстрирует голубая линия между игроком и эмиттером на изображении ниже. Пока линия зеленая, игрок находится под защитой.

Прототип блокиратора ветра в бою с боссом "Злой волшебник". (Rubber Duck Games)
Приемный ветер

Наконец, нам нужно было сделать так, чтобы игрок воспринимал силу ветра и двигался в его направлении. Для этого у нас есть компонент WindReceiver. Он отвечает за проверку того, насколько сильный ветер воздействует на игрока и с какого направления. Эта информация собирается путем выполнения Raycast от игрока в сторону приемника ветра. Эта информация используется для определения того, воздействует ли излучатель ветра на приемник, с какой силой и с какого направления. Получив всю информацию, мы применяем силу ветра с помощью собственного контроллера перемещения и перемещаем игрока в нужном нам направлении.

Поведение Хейлги

Когда Диего начал совершать первые атаки, я начал давать Хейлге повадки.

Для создания ИИ в Evil Wizard мы использовали очень полезный актив под названием Behavior Designer. Я не могу рекомендовать его. Он идеально подходит для дизайнеров игр, которые не занимаются кодом: программист может работать над механикой, а дизайнер накладывает ее на дерево поведения персонажа, заставляя его работать так, как ему нужно, без кодирования. Вы можете ознакомиться с основами здесь.

Вот дерево поведения Хейлги:

Дерево поведения для персонажа Хейлга в игре Evil Wizard. (Rubber Duck Games)

Это большое дерево, но не пугайтесь - это проще, чем кажется.

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

Статический вид дерева поведения для персонажа Хейлга в игре Evil Wizard. (Rubber Duck Games)

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

Более глубокий вид дерева поведения для персонажа Хейлга в Evil Wizard, показывающий поведение для боя с боссом. (Rubber Duck Games)

Приоритетом поведения босса всегда является здоровье. С его помощью мы контролируем, должен ли босс перейти в другую фазу или даже умереть. Итак, сначала мы спросим, есть ли у босса более 75 % здоровья. Если да, то мы выполняем задания первой фазы - ледяные шипы, ледяные ракеты и призыв снежных слизней (миньонов босса). Когда здоровье босса опускается ниже 75 %, дерево переходит к следующему селектору в нижней части изображения и выполняет задания, соответствующие второй фазе, и так далее, пока босс не достигнет своей финальной фазы и персонаж не умрет при 0 здоровья.

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

Вы уже видели их на предыдущем изображении - иконки с тремя квадратиками - это деревья внешнего поведения.

Вид крупным планом на используемую функцию внешнего дерева поведения. (Rubber Duck Games)

Думайте о внешних деревьях поведения как о методе в вашем коде: вы вызываете метод в нескольких местах по всей логике игры, и в каждом месте он выполняет один и тот же код, но у вас он находится только в одном месте. Если вам нужно что-то изменить в этой логике, вы меняете код этого метода, и он будет меняться во всех местах, где вызывается этот метод. Здесь все работает так же. У вас есть внешнее дерево поведения, которое содержит поведение для выполнения определенного действия, например "вызвать снежных слизней".

Если я войду в наше дерево внешнего поведения, то найду следующее:

Внешний вид дерева поведения для "Призвать снежные слизи" в Evil Wizard. (Rubber Duck Games)

Это как мини-дерево поведения, которое проверяет, не повторяет ли босс одну и ту же атаку слишком много раз и не слишком ли много миньонов уже на поле боя, затем призывает миньонов, воспроизводит голосовые реплики Хейлги или завершает, переводя босса в режим ожидания.

Если я хочу изменить количество миньонов, которые могут находиться на поле боя одновременно, мне достаточно изменить его в задании "Check Enemy Amount of Type" внутри этого внешнего дерева поведения, и это будет работать для каждой части дерева, которая используется для вызова миньонов.

Анимация хайлга

При создании Хайльги наш ведущий художник Рубен Гомес начал с отсылки к существующим персонажам в надежде, что игроки их узнают.

В данном случае мы использовали Джайну из Warcraft (как уже говорилось) и Эльзу из Frozen в качестве референсов для персонажей.

Вот что говорит Рубен:

"Принимая во внимание все предпосылки, я начал с дизайна Hailga, - говорит Рубен. "Мы взяли некоторые характеристики из одежды и причесок каждого эталона, элементы, которые могут быть легко узнаваемы в очень маленьком пиксельном спрайте, и заполнили остальное воображением (никакого ИИ, только человеческое воображение, то самое, которое я использовал в детстве)".

Ранние прототипы для анимации персонажа Хейлга в игре Evil Wizard. (Rubber Duck Games)

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

После этого мы провели быстрый тест движений и настроили их таким же образом.

Образец теста движений для анимации хайлга в Evil Wizard. (Rubber Duck Games)

Когда анимационный проект был готов, мы доработали каждый элемент, заполнили пустые места и добавили детали.

Окончательный вариант каждого кадра вы можете увидеть на следующем изображении.

Окончательный вид анимации хайлга для Evil WIzard, демонстрирующий доработки по сравнению с первоначальным вариантом. (Rubber Duck Games)
Тестирование и балансировка

Пока анимация была в процессе, я занялся тестированием и балансировкой боя босса. Для этого мы создали сцену под названием "Боевая зона", в которой тестировали боссов, врагов, заклинания и многое другое. По сути, это небольшая область, в которой есть все инструменты и функции, необходимые нам для тестирования, не касаясь реальной игры.

Так выглядел ранний босс Хейлга, когда мы тестировали персонажа в сцене Combat Zone:

Ранний взгляд на анимацию босса Хейлга в тестовой сцене для Evil Wizard. (Rubber Duck Games)
Ранний взгляд на анимацию босса Хейлга в тестовой сцене для Evil Wizard. (Rubber Duck Games)

Наконец, когда мы были довольны ее поведением, функциональностью и сложностью, мы интегрировали Хейлгу на ее место в реальной игре.

Вид на окончательное размещение анимации босса Хейлга в Evil Wizard. (Rubber Duck Games)
Время для VFX

Когда мы закончили работу над поведением и анимацией Хайльги, мы начали интегрировать анимацию босса, используя AnimatorImporterкоторый является отличным инструментом для интеграции пиксель-арт анимации, сделанной в Aseprite. С ним всего за несколько шагов вы сделаете все, что нужно.

Теперь настало время придать боссу изюминку, и тут в дело вступил наш VFX-художник Теки. Забирай, Теки:

Эй! Серджио Вайсвол (он же Теки), программист и VFX-художник в Evil Wizard.

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

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

Предварительный просмотр эффекта ледяного луча в бою с боссом Hailga у Evil Wizard. (Rubber Duck Games)

Я считаю, что это очень хороший эффект, который можно разложить на части и показать, из каких кусочков состоит волшебство. Для этого мы разделили переход на два VFX-фрагмента: ледяной луч и замораживание пола.

Для первой части моя работа начиналась, как только Диего заканчивал программировать атаку, и обычно сопровождалась красивой заготовкой (в данном случае - вытянутым прямоугольником) - плюс он желал мне удачи. И тут я с головой окунулся в работу, используя те инструменты, которые, как я знал, уже были в моем арсенале. Но поскольку это было начало разработки, у меня их было мало. В прошлом я использовал компонент Line Renderer из Unity для рендеринга линии между любыми двумя точками, управляемой с помощью скрипта, поэтому я начал с него, а затем объединил его с базовым шейдером, чтобы добавить цвет к краям и центру линии.

Компонент Unity Line Renderer в действии в примере сцены из Evil Wizard. (Rubber Duck Games)

Не совсем, как вы можете видеть выше. В VFX я быстро понял, что (вопреки классической философии) "целое - это сумма частей". Я имею в виду, что для создания желаемого эффекта может потребоваться несколько систем, а не один шейдер или одна частица.

Далее мне нужно было, чтобы эффект больше походил на луч (и был менее массивным), поэтому я поиграл с Shader Graph, чтобы добиться этого. Я постараюсь объяснить это вкратце.

Чтобы добиться желаемого, шейдер должен состоять из трех основных частей. Во-первых, я использовал ранее нарисованную текстуру, которая представляла собой просто горизонтальный зеркальный градиент (вы можете увидеть ее на следующем изображении под именем MainTex). Используя узел "Pow", я могу легко управлять шириной луча (текстура умножает себя и, поскольку это градиент, уменьшает луч).

Вид в редакторе Unity на части Shader Graph, использованные для эффекта ледяного луча в Evil Wizard. (Rubber Duck Games)

Затем я использовал анимацию Simple Noise с узлом Tiling And Offset для двух целей:

Растворить луч в определенных частях (всегда контролируется публичной переменной)

Для изменения ультрафиолетового цвета луча, чтобы он выглядел искаженным

Вид в редакторе Unity на части Shader Graph, использованные для эффекта ледяного луча в Evil Wizard. (Rubber Duck Games)

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

Когда я закончил, у меня было что-то вроде этого, чтобы поиграть с разными цветами и переменными.

Вид в редакторе Unity на изменения эффекта ледяного луча в Evil Wizard. (Rubber Duck Games)

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

Поэтому с помощью частиц я создал ледяную сферу, чтобы она могла стать точкой литья для луча:

Вид в редакторе Unity на ледяную сферу, созданную в качестве точки кастинга для эффекта ледяного луча в Evil Wizard. (Rubber Duck Games)

Наконец, нам нужны частицы вдоль луча, чтобы интегрировать его с остальной частью области.

Вид из редактора Unity на создание частиц, интегрированных в эффект ледяного луча в Evil Wizard. (Rubber Duck Games)

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

Для согласования скорости мы использовали регулярный скриптинг для управления скоростью движения балки по переменной от 0 до 1, т.е. насколько сильно должен быть заморожен пол в зависимости от текущего вращения балки. Для лессировки текстур нам понадобился короткий шейдер. Посмотрите, как мы разделили шейдер на две части, чтобы получить радиальный градиент и фактический лерпинг.

Вид в редакторе Unity на шейдер текстуры лерпинга для Evil Wizard. (Rubber Duck Games)

Ниже показана формула, применяемая для расчета радиального градиента, учитывающая положение UV и идущая точно от 0 до 1. Это синхронизирует движение луча с замороженным значением.

Обновлен вид в редакторе Unity на текстурный шейдер lerping для Evil Wizard с формулой радиального градиента. (Rubber Duck Games)

Вот как это выглядит на месте преступления:

Вид эффекта текстурного шейдера lerping в действии в сцене в Evil Wizard. (Rubber Duck Games)

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

Подведение итогов

После того как все было готово, композитор игры Хаакон Давидсен добавил последний штрих - умопомрачительную музыку, которая заставляет игроков почувствовать "накал" битвы. Вы можете послушать его здесь. И, конечно, актриса озвучивания - Бреанна Макдауолл - проделала потрясающую работу, подарив голос Хейлге.

Мы надеемся, что вам понравился этот блог!

Испытайте на себе бой босса Хейлга, заглянув в игру Evil Wizard на Steam или Xbox, и следите за выходом игры на других платформах. Читайте другие истории Made with Unity прямо от разработчиков здесь.