Искать на сайте Unity

СТОЙТЕ, Я ПЕРЕДУМАЛ! ПРЕРЫВАНИЕ ПЕРЕХОДОВ МАШИНЫ СОСТОЯНИЙ

13 июля 2016 г. через Engine & platform | 5 мин. читать
image05
image05
Поделиться

Is this article helpful for you?

Thank you for your feedback!

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

Итак, давайте погрузимся в захватывающие подробности переходов и прерываний машины состояний!

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

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

Давайте разберем несколько примеров. Возьмем довольно простую машину состояний — с четырьмя состояниями от A до D, и обработчиками, подключенными к каждому переходу.

image05

Когда мы запускаем переход A->B, наша машина состояний по умолчанию переходит к состоянию B, и ничто не в силах ее остановить. Но если мы перейдем в инспектор перехода A->B и сменим источник прерывания с «None» на «Current State», окажется, что путешествие из пункта A в пункт B все же можно прервать некоторыми обработчиками состояния A.

image01

Почему только «некоторыми»? Потому что флажок «Ordered Interruption» выставлен по умолчанию. Это значит, что допустимы только те переходы из состояния A, которые имеют более высокий приоритет, чем текущие. Если мы посмотрим на инспектор состояния A, мы увидим, что это относится только к переходу A->C.

image02

Так что если мы активируем обработчик A->B, а затем сразу A->D, с нашим переходом ничего не произойдет. Но если вместо этого мы щелкнем триггер A->C, переход будет немедленно прерван, и машина состояний начнет переход к C. 

Внутри анимационная система записывает позицию и время прерывания, и сейчас выполнит плавный переход между статичной позицией X и новой анимацией назначения.image04Почему выбрана статичная позиция вместо плавного перехода между текущим и новым переходами? Да просто ради производительности. Когда игра получает ворох прерываний, попытка отследить сразу все динамические переходы одновременно очень быстро заблокирует всю анимационную систему.

Если же мы снимем флажок «Ordered Interruption», можно будет прервать оба перехода — и A->C, и A->D. Но если вызвать их с одного и того же кадра, переход A->C все же окажется главнее, так как его приоритет выше.

Если сменить источник прерывания на «Next State», A->C и A->D больше не смогут прерывать переход независимо от их порядка. Но если вызвать обработчик B->D, мы немедленно начнем переход от A к D, переход к B при этом не будет завершен.

Порядок перехода влияет и на состояние B. Флажок «Ordered Interruption» становится недоступен (любой вызов перехода к B может прервать переход, так как у них не ранжирован приоритет по отношению к A->B), но именно от последовательности переходов к B будет зависеть, какой переход произойдет, если они оба вызваны с одного и того же кадра. В данном случае будет выбран переход B->D.

image03

Наконец, если нам требуется полный контроль, мы можем установить источник прерывания в «Current State Then Next State» или «Next State Then Current State». В этом случае независимо от состояния будет анализироваться сначала один переход, а затем другой.

Предположим, что мы имеем следующую конфигурацию.

image00

Во время перехода A->B игрок увлекся и запустил четыре перехода с одного и того же кадра: A->C, A->D, B->C и B->D. Что будет?

Во-первых, поскольку флажок «Ordered Interruption» установлен, о переходе A->D можно забыть: его приоритет ниже, чем у A->B. Сначала разрешается текущее состояние, и на состояние B можно даже не смотреть — победит переход A->C.

image02
image03
13 июля 2016 г. через Engine & platform | 5 мин. читать

Is this article helpful for you?

Thank you for your feedback!

Unity, логотипы Unity и другие торговые знаки Unity являются зарегистрированными торговыми знаками компании Unity Technologies или ее партнеров в США и других странах (подробнее здесь). Остальные наименования и бренды являются торговыми знаками соответствующих владельцев.