Хорошие методы для синхронизации действий геймплея с определенными временами анимации?

10

Итак, я столкнулся с проблемой в игре, над которой я работаю, но она кажется довольно фундаментальной, которая, вероятно, возникает во многих играх.

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

Вот несколько простых примеров того, о чем я говорю в различных типах игр:

  • Ваш персонаж перезаряжает свое оружие в шутере . Ваш персонаж воспроизводит анимацию «перезагрузки», но важно, чтобы функция, устанавливающая переменную currentAmmo, вызывалась только в тот момент, когда магазин был заменен, а пистолет взведен. Это может быть какой-то момент в середине анимации перезагрузки.

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

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

По общему признанию, мой конкретный случай больше всего похож на второй пример , в котором я создал анимацию, в которой мой пошаговый персонаж выпадает вперед во время атаки, и я хочу, чтобы урон наносился в тот самый момент, когда анимация, кажется, вступает в контакт , Поскольку моя игра использует пошаговую систему (представьте что-то вроде Final Fantasy или Fire Emblem), я хочу урон / исцеление / магия / и т.д. быть примененным в правильное время во время каждой анимации персонажа, хотя я на самом деле не использую коллизии / хитбоксы.

Я должен упомянуть, что я делаю свою игру на популярном игровом движке, и что сейчас я обрабатываю это, используя их анимационные события или уведомления, чтобы достичь чего-то близкого к желаемым результатам - мой персонаж выполняет определенную команду и запускает анимация, специфичная для команды (то есть: 'attack_command'), и ресурсы анимации для каждой из моих команд должны включать в себя событие анимации / callback-вызов notify в функцию ExecuteCommand моих персонажей. Другими словами - персонаж говорит анимации атаки играть, а затем анимация атаки генерирует обратный вызов события / уведомления в персонаж в тот самый момент во время анимации, когда должен быть нанесен урон.

Честно говоря, пока это работает, но кажется, что это неправильно - как будто мне не хватает какой-то части общей картины! Одна из причин, по которой этот метод кажется неправильным, заключается в том, что он связывает игровую логику с активами анимации; если мой ресурс анимации забывает включить событие / обратный вызов ExecuteCommand (), команда не будет выполняться должным образом, и потребуется дополнительный код для проверки завершения анимации команды без ее выполнения. Это грязно, и это означает, что мой игровой процесс имеет странную зависимость от его активов. Конечно, я хочу, чтобы повреждение происходило в определенный момент во время моей анимации атаки, но я чувствую себя действительно странно из-за вызова кода геймплея внутри ресурсов анимации.

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

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

MrKatSwordfish
источник
1
Я смущен. Вы говорите, что хотите, чтобы игровой процесс зависел от времени анимации, но затем говорите, что не хотите, чтобы ваш игровой процесс зависел от ваших ресурсов, а анимации - это тип ресурсов. Как вы ожидаете, что эти пожелания будут совместимы?
Анко
Я хочу, чтобы некоторые элементы игрового процесса были синхронизированы с анимацией. Однако синхронизация между двумя вещами не всегда подразумевает зависимость, верно? Мне интересны некоторые приемы, которые люди используют для синхронизации своих анимаций с игровым процессом. Я сказал, что я пробовал и что я в настоящее время делаю, чтобы достичь этого - и поэтому мой вопрос, есть ли другой / лучший / альтернативный метод, который можно использовать, или это (анимационные события / уведомления / обратные вызовы, запеченные в активы) стандартным способом? Это то, что вы используете в своих проектах?
MrKatSwordfish

Ответы:

5

Для синхронизации вам нужно решить, кто (ваш код, анимация или ни один из них) является органом синхронизации, «ритмом», под который «танцуют» все остальные.

Разные аранжировки подходят для разных игр:

  • Анимации - это источник времени (ваша текущая настройка)

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

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

    Инструменты анимации Blender (3D) и Spine (2D) позволяют аниматору определять события, на которые может подписаться игровой код.

  • Код является временным органом

    Обратное из вышеперечисленного: события, происходящие в игровом мире (например, игрок, решивший перезарядить свое оружие), приводят к запуску анимации и передаче параметров (например, времени до завершения перезагрузки). Каждая анимация использует предоставленные параметры, чтобы изменить ее внешний вид (например, запустить анимацию с соответствующей скоростью, чтобы «заданная часть» появлялась, когда она указана).

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

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

    Анимация персонажей Overgrowth в значительной степени структурирована таким образом: Дэвид Розен объясняет это в своем выступлении на GDC 14 (см., В частности,сегменты« Движение и продолжение» ).

  • Неявные сроки (внешние полномочия)

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

    Если ваше игровое состояние и анимация в значительной степени зависят от внешнего источника синхронизации, рассмотрите этот подход.

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

Анко
источник
0

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

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

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

В моей файтинге состояние - это объект, который наследуется от класса BaseState и имеет метод Update (). Каждый персонаж имеет набор состояний, но одновременно может быть назначено только одно. И метод Update () текущего состояния вызывается один раз за кадр.

Он находится внутри функции Update (), в которой я выполняю всю эту логику: устанавливаю скорость персонажа в определенном кадре, увеличивает / уменьшает здоровье и т. Д.

Эмир Лима
источник