Всем привет. Публикую статью от именно своего коллеги Дмитрия Качкова - основателя Sobaka Studio.  Наша небольшая команда уже больше пяти лет занимается разработкой инди-игр в жанре beat ’em up, где весь игровой процесс жестко завязан на боевую систему. Наверное, многие замечали, что в самых успешных играх жанра beat’em up игрока увлекает не столько сюжет или оформление окружения, а сам бой – интересный, разнообразный, стремительный. Именно за приятную боевку критики хвалят обе наших игры. Redeemer: Enhanced Edition, где игровой персонаж – мощный монах Василий – зачастую должен раскидывать своих врагов подальше от себя кулаками (и не только). И 9 Monkeys of Shaolin, в которой персонаж сражается посохом против множества противников и в ходе игры должен улучшать свои боевые приемы с помощью системы прокачки навыков. Ощущения насыщенности и сочности боя в обоих проектах достигается нами с помощью комбо-атак. Тому, из чего они состоят на движке Unreal Engine, и будет посвящена данная статья.  Изначально компонент ”Комбо-атака” - это проигрывание анимации удара. Но сразу после того как анимация начинает проигрываться, появляется огромное количество дополнительных условий, эвентов и триггеров, которые и придают (при должной настройке) весь необходимый сок. Этот компонент развивался последовательно, довольно долгое время, и вырос в большой компонент, работающий с огромным количеством дополнительных настроек. Сейчас, просто покрутив одно или другое свойство можно превратить “обычное” проигрывание анимации в сложносочиненную последовательность действий. Прежде чем рассказать о внутренней функциональности, давайте посмотрим как настраивается каждая комбо-атака в uobject сабклассах. Параметры, которыми можно настраивать комбо-атаку, состоят из нескольких категорий: Анимация. Сюда входит указания анимации как для героя, так и для его оружия. Дизайн. Сюда входит группа параметров по балансировке геймплея. Урон (damage), шанс нанесения критического удара (critical hit), урон от кровотечения (bleeding damage), возможность блокировки удара противником и т.д. Плюс здесь же находится список модификаторов, получаемых игроком по мере прокачки персонажа, которые изменяют параметры удара. Атака. Сюда входят параметры, которые сопровождают анимацию: радиус поражения атаки, название кости, отвечающей за трассировку ударов (hit trace), дистанция до противника - насколько игрок должен “подъехать” к врагу, прежде чем начинать атаку, и т.д. Их настройкой, что неудивительно, занимается в основном аниматор. Заряженный удар. Сюда входят параметры относящиеся к усиленной версии удара при зажимании кнопки. Например, какой спецэффект проиграть при зарядке, и на какой удар надо переключиться, если этот “зарядится” (удар будет подменен в части геймплейных и атакующих параметров). Комбо. Здесь хранятся атаки, которые могут продолжить текущую в комбо, если игрок будет нажимать кнопки во время удара. Попадание. Здесь собраны параметры, относящиеся к тому, какой урон получит враг при успешно проведенной атаке, и как будет выглядеть нанесение удара. То есть здесь хранятся настройки эффектов, для которых используются частицы – дым, огонь и т.п. (particle effect), звуки, мерцание врага, сотрясение камеры (camera shake), застывание (freeze), а также ссылка на блюпринт (blueprint), описывающий реакцию противника после попадания удара (анимацию, время недееспособности – в нашем случае, время того, сколько враг лежит на земле, дистанция полета до стены и прочее). Мы активно используем Animation Notifications (далее по тексту - нотификаторы) для настройки и балансировки геймплея, а также декоративных визуальных и звуковых изменений. Давайте рассмотрим сперва основные геймплейные нотикаторы с помощью которых геймдизайнер вместе с аниматором могут вытачивать тонкости великолепного геймплея. При выполнении атаки персонаж игрока (или враг) сначала может рывком перемещаться к противнику. Этот рывок может быть унаследован атакой как часть прокачки персонажа, либо изначально являться особенностью приема. Вся соль в том, что во время создания анимации аниматор не может знать на какое расстояние герою придется переместиться, чтобы попасть по врагу. Поэтому мы устанавливаем анимационный нотификатор в то место, где анимацию следует поставить на паузу и дать игроку с помощью рывка сперва добраться до врага. Места установок этих объявлений рассчитаны так, чтобы герой не подвисал надолго. Но тем не менее, сколько-то повисеть иногда надо в угоду эффектности.  Сам процесс dash’a происходит внутри компонента простым кратным увеличением максимальной скорости и форсированного толкания персонажа в сторону точки назначения рывка (авто наведенный враг). Далее в каком-то моменте анимации атаки включается состояние AOEAttackState. Аббревиатура AOE расшифровывается как Area of Effect – область действия. Это состояние активирует вычисление трассировки луча удара примерно в области оружия (иногда с сильно увеличенными размерами), чтобы определить, есть ли попадание по врагу. Для регистрации попаданий по врагу используется не только AOEAttackState, но и специальный отдельный анимационный нотификатор StrikeHit. В момент активации нотификатора врагу, стоящему перед персонажем игрока в пределах определенного радиуса, принудительно наносится урон. Все настройки попадания (и трассировки в состоянии AOE и зоны попадания во время действия strikeHit) хранятся в блюпринте (blueprint) текущей комбо-атаки. Именно в нем дизайнеры могут детально настраивать попадания разных ударов.  Дальше по ходу анимации удара может встретиться анимационный нотификатор ShortTick (моментальный удар). При срабатывании нотификатора ShortTick система проверяет, была ли нажата кнопка атаки после начала текущей. И если это произошло, значит атаку нужно продолжить следующей, которая настроена также в блюпринте комбо-атаки.  Т.е. блюпринт атаки содержит ссылки на блюпринты других атак которые срабатывают при условии, что на момент активации ShortTick была нажата одна из кнопок какого-либо удара. Важно, что ShortTick может задаваться несколько раз для тонкой настройки таймингов комбо. Замыкает настройку одной анимации атаки. Это группа нотификаторов, которые задают места, в которых можно прервать проигрывание анимации каким-то новым событием. Такими событиями могут быть нажатие игроком кнопки движения или получение им урона. Например, суперудары в игре в активной фазе не должны прерываться атаками слабых врагов. Но если активная фаза суперудара закончилась, и модель героя завершает воспроизведение красивой анимации, в этот момент нанесение урона уже должно прервать анимацию атаки и проиграть анимацию попадания. Большая часть приемов в игре могут иметь “заряжаемые” версии, т.е. при зажимании кнопки герой делает усиленную атаку и наносит больший урон. Все удары в игре очень быстрые и наносить их нужно быстро, а держать кнопку зажатой надо долго. Поэтому чтобы не вводить игрока в пассивное состояние зарядки, мы сделали кривую замедления скорости анимации, если игрок держит кнопку атаки. В этом случае скорость проигрывания анимации замедляется и, когда накопится нужное количество заряда, появляется специальный визуальный эффект и удар наносит двойной урон. Помимо описанных выше нотификаторов, влияющих на геймплей, у нас есть те, что отвечают за звуковые и визуальные составляющие атаки. Они максимально дополняют картинку и делают ее завершенной.  Одна только атака состоит из ряда нескольких звуковых эффектов, это: взмах оружия, шаги игрока, крик при взмахе, звук возврата игрока на землю из атаки и другие. Все персонажи в игре имеют один гуманоидный скелет, но при одной и той же анимации атаки, разный набор звуков и эффектов может кардинально изменить ее восприятие. Например, у нас может быть большой враг в железной броне, а может быть вообще без брони, поэтому голос вскрика например может быть принципиально разным. При определении удара на враге должна сработать реакция. Для того чтобы игрок лучше почувствовал обратную связь от своих действий. Причем чем сильнее - тем лучше, но при этом реакция должна быть управляемая для дизайнеров. В каждой комбо-атаке есть ссылка на блюпринт описывающий как будет реагировать тот, в кого эта комбо-атака прилетит: На скриншоте можно видеть, что наши враги делятся на три типа –. Это сделано для того, чтобы иметь возможность назначить разные реакции на один и тот же удар разным врагам. Мы не сразу пришли к такому разделению. Сначала пробовали задавать в блюпринте каждого врага настройку связи реакции на удар, но в этом случае приходилось перечислять все классы атак, которых могут быть сотни. Это долго и можно легко сделать ошибку.  Потом мы пробовали задавать классы врагов в самой реакции на удар. Но тут обратная проблема: в каждой реакции на удар надо прописывать много врагов и не забывать добавлять их по мере создания новых классов.  Поэтому для упрощения настройки этих связей мы поделили врагов на на четыре категории “легкие”, “средние”, “тяжелые” и “специальные”. Специальные враги особым образом обрабатывают попадания по ним, а вот обычные выбирают себе анимацию и настройки исходя из своего типа. При этом анимация реакции может отличаться не только длительностью, но и особенностью блокирования поведения врага или счетчика его атак. Т.е. тяжелый враг, например, может проигрывать анимацию попадания, но при этом в любой момент может прервать эту анимацию, если решит атаковать. Есть несколько вспомогательных эффектов с помощью которых можно вызвать у игрока более яркие впечатления. К ним относятся: Тряска камеры. Как на удары по врагам, так и на удары по игроку мы можем назначать настройки тряска камеры (конечно в основном это еле заметная тряска, но всё же). В момент особо мощных ударов по персонажу игрока эта тряска может быть сильнее, чтобы передать ощущение боли. Эффекты частиц. Мы придаем большое значение разного рода эффектам (в данном случае речь о эффектах частиц) и помимо эффектов самого удара (взмах палкой, порыв ветра, энергия Ци) мы настроили множество эффектов для попаданий по врагам. Особенно важным в нашем случае стоило назначать разные типы попадания когда враг просто получил урон, или когда он от удара умер. Зачастую мы сознательно преувеличиваем некоторые параметры, чтобы придать зрелищности. Вся наша работа нацелена на зрелищность в той или иной степени. Микрозадержки. Но и это не всё, помимо эффектов и тряски камеры очень важной особенностью нашей боевой системы являются микрозадержки, которые на самом деле используются в огромном количестве топовых слэшеров. При попадании удара анимация героя и врага на доли секунда останавливаются. Это придает каждому попаданию вес. При этом каждый удар имеет свою выверенную длительность этого эффекта. При убийстве врага эффект длится дольше, чем при простом попадании, а при убийстве последнего врага в схватке, он длится еще дольше, словно мы ставим последнюю точку. Чтобы подчеркнуть особенности дизайна 9 Monkeys of Shaolin, мы внесли несколько новшеств в систему. Анимация оружия. Аниматор делает анимации оружия синхронные с анимацией удара персонажа. Трассировка попаданий, обсчитывающая траекторию оружия. Зачастую удары в нашей игре очень быстрые и могут длиться всего пару кадров, в том же время оружие может пройти длинный путь и даже успеть пройти сквозь врага. Чтобы это предотвратить, мы рассчитываем пройденный оружием путь и делим его на отрезки, на каждом из которых проверяем пересечение оружия с врагом. Прокачка ударов - возможность улучшать атаку получая усиления. Так как параметров у атак довольно много и некоторые из них сильно отличаются от обычного нанесения урона, у нас есть естественная возможность улучшать эти характеристики и передать игроку над ними контроль. Например, у нас есть параметр, отвечающий за автоприцеливание игрока и насколько далеко враг может находиться, чтобы игрок мог его атаковать. Если увеличить его значение, то можно добиться очень интересных результатов и даже поменять ощущения от боя в лучшую сторону. Вот так благодаря грамотной работе с состояниями атаки, категоризацией врагов и атак и индивидуальным настройкам анимаций мы получаем сочную боевку с приятной обратной связью, что и требуется хорошему развлекающему битэмапу. Надеюсь наш опыт оказался вам полезен. И вы сможете проверить, как он реализован в наших играх, переосмыслить и применить в своих прекрасных проектах. Большое спасибо, что дочитали до конца. Результат можно посмотреть здесь:  Исполнительный продюсер