Анимация в Unity для чайников — проблемы и решения

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

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

Эта заметка будет:

- полезна тем, кто только начинает работать с анимацией в Unity;

- довольно бесполезна для опытных разработчиков, хотя мне было бы приятно получить от них фидбэк;

- совершенно не нужна тем, кто не имеет ничего общего с Unity и Mecanim. Разве что они хотят почитать про Mixamo.

Fuse и Mixamo — панацея для инди-разработчиков (?)

Если кто не в курсе, Mixamo — это облачная служба автоматического риггинга и банк персонажей и анимаций, а Fuse — это приложение для создания гуманоидных моделей (редактор типа как в Sims), которые потом можно анимировать через Mixamo. К сожалению, в 2015 году все это купила Adobe, которая полностью забила на дальнейшее развитие этих продуктов и прикрутила Fuse к своему Creative Cloud. Что примечательно, все это сейчас совершенно бесплатно — бери не хочу, только зарегайся в Adobe и поставь себе кучу их ненужных сервисов.

Основные затраты по времени у нас вызвал тот факт, что для разных двуногих моделей, на вид одинаковых и с одинаковым скелетом, нужны разные анимации. В частности, если вы натаскаете разных человечков с Mixamo и скачаете для одного из них весь набор нужных движений, эти анимации к другим человечкам подходить не будут. С другой стороны, если вы сделаете персонажей в Adobe Fuse (потратив несколько часов на его установку и полчаса на запуск), то скачанные с ними Mixamo-анимации будут взаимозаменяемы. Если бы кто-то сказал нам об этом в самом начале, это бы сэкономило уйму времени, которое мы в итоге потратили на закачку тонны анимаций, их смену и (неочевидный момент) вставку оружия в руки персонажей, что нам пришлось делать дважды (а это ужасно муторный процесс).

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

Анимация в Unity для чайников — проблемы и решения

Вторая полезная фишка — в окошечке загрузки, это возможность не загружать скин (модельку), а скачать только анимацию, уменьшив вес загрузки раз в 10. Таким образом, вам нужно только одну анимацию скачать с моделью (with skin, не забудьте пометить как-нибудь этот fbx, чтобы в юнити проще было его найти), а все остальные можно оставить без нее.

Анимация в Unity для чайников — проблемы и решения

Импорт моделей из Mixamo в Unity

Хорошо, модельки и анимации у нас есть, только при импорте в Unity все текстуры куда-то пропали. Что делать? Про магию импорта моделек из Mixamo хорошо рассказывается здесь: https://www.youtube.com/watch?v=xOeodlLTx8g

А на скриншоте ниже показаны две волшебные кнопки, которые и достают текстуры и материалы из моделек (здесь и далее версия Unity 2017.4.0f1).

Анимация в Unity для чайников — проблемы и решения

И не удивляйтесь, если у вас получаются вот такие ресницы:

Анимация в Unity для чайников — проблемы и решения

А дальше мы переходим к самому интересному…

Mecanim — типовые проблемы и решения

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

Проблема 1: как зациклить анимацию (например, ходьба или idle). Или же наоборот, не зацикливать. Мы помнили, что где-то этот флажок был, но проискали его целый вечер. Вот он:

Анимация в Unity для чайников — проблемы и решения

Проблема 2: как прервать анимацию другой анимацией. Например, как запустить анимацию выстрела в момент нажатия кнопки игроком, не дожидаясь окончания 4-х-минутного айдла «я-держу-ружье». А по умолчанию Unity делает именно это. Когда вы создаете переход, ему автоматически ставится флажок Has exit time — это значит, что переход между анимациями начнется тогда, когда первая анимация подойдет к концу. Если нужен переход в момент триггера, просто снимите этот флажок.

Анимация в Unity для чайников — проблемы и решения

Проблема 3: как задать нужный момент в анимации. Например: вот у вас есть анимация «бью-мечом». Она состоит из замаха, собственно момента поражения врага и возвращения меча на место. Любая анимация какой-либо атаки строится по этому принципу. Как определить момент, в который нужно сделать проверку попадания и вычесть хиты? А точнее, как это сделать лучше и правильней? Потому что для этого есть как минимум три способа:

  • Повесить коллайдер на оружие и проводить проверку попадания по физике. Честно. Зато дополнительный коллайдер жрет мощность, хотя мог бы этого не делать. Даже если его включать только на время атаки. В нашей игре мы сделали вначале коллайдеры. И они работали… до какого-то момента, когда они работать стали нестабильно. Я почти целый день пыталась выяснить, в чем же, собственно, причина, и не нашла ее. Зато официальный туториал Unity меня убедил, что триггер-коллайдеры должны быть статичными. Пришлось уйти от коллайдеров. (Апдейт: триггер-коллайдеры могут прекрасно работать с кинематическими rigidbody)
  • Анимационные события. Мощно. Удобно. Если бы не тот факт, что анимации, идущие вместе с моделями, закрыты для редактирования. Для того чтобы повесить на них ивенты, надо создать новую анимацию в Юнити и скопировать туда все точки нужной анимации вручную. Это не сильно долго, но довольно муторно, если у вас этих анимаций хотя бы десяток. И хорошо бы это пришлось делать один раз — но ведь анимации подлежат постоянным изменениям, и тогда придется все опять переделывать. Как бы то ни было, этот способ лучше всего подойдет в том случае, если у вас на одну атаку несколько разных анимаций (для разнообразия) или больше одного момента атаки в анимации.
  • Параметр задержки, настраиваемый в редакторе. Лучше всего, если он будет в долях от длительности анимации атаки (во многих случаях подойдет 0.5) — тогда будет проще менять анимации при необходимости. Мне показался этот вариант самым простым и удобным.
Событие анимации<br />
Событие анимации

Проблема 4: состояние смерти. Trigger vs bool. Триггер, если кто опять не в курсе, это такой bool-параметр анимации, который сам выключается где-то там после запуска этой анимации. Очень удобно использовать для запуска тех же анимаций атаки. Когда именно он выключается и что там потом происходит — этого никто не знает. И в этом кроется огромная проблема. У нас персонажи после проигрывания анимации смерти по триггеру снова возвращались в idle-состояние. И происходило это даже тогда, когда уже было полностью исключено как в коде, так и в аниматоре (см. скриншот). Так и не выяснив причину, мы решили поменять тип параметра на bool. И столкнулись с еще одной неприятной проблемой: персонажи зависали в начале анимации смерти и дальше не продвигались. Происходило это от того, что анимация смерти все время переходила сама в себя. Как оказалось, это лечится простым флажком:

Анимация в Unity для чайников — проблемы и решения

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

Проблема 5 (для классических спрайтовых анимаций):

И вот в очередной раз принимаемся за анимацию главного персонажа, вроде бы все на месте, но откуда-то возникают задержки (заметите на гифке?)

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

Анимация в Unity для чайников — проблемы и решения

Что мы так и не поняли

Как обрабатывать анимацию, в которую зашито движение (root motion). Благо, большинство анимаций Mixamo имеют флажок In place, который отключает рут-моушн. Но что делать, если вам хочется использовать в игре подобную анимацию, а возможности убрать у нее перемещение нет? Как отключить его или хотя бы скормить это перемещение navmesh-агенту — мы так и не придумали. Поэтому неписи в нашей игре прыгают от врагов, а потом оказываются в начальной точке, и все это выглядит так, будто они телепортируются вокруг зомби (в целом довольно сносно:)) Если кто сможет предложить иное решение, помимо «не использовать анимации с вшитым движением» — welcome, очень жду. И да, на флажок enable root motion в компоненте аниматора мы пробовали нажимать:)

1010
5 комментариев

 Анимационные события. Мощно. Удобно. Если бы не тот факт, что анимации, идущие вместе с моделями, закрыты для редактирования.

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

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

4
Ответить

Спасибо за комментарий!
Туториал конечно был, но давно (иначе как вообще понять, что делать?) А статья больше для таких же чайников в Mecanim, как мы.

Ответить

не пробовали использовать UMA вместо фьюза?

Ответить

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

Ответить