Search Unity

I recently investigated a tricky bug reported by a user involving the combination of empty states, override layers, and transition interruptions. As I was digging in, I found that our documentation about transition interruptions in the animation system was a bit… minimalist. A long conversation with my team later, we concluded that a blog post was in order.

So let’s dive into some intricate details of State Machine Transitions and interruptions!

By default in the animation system, transitions cannot be interrupted: once you start going from one state to the other, there’s no way out. Like a passenger on a transatlantic flight, you’re cozily nestled in your seat until you reach your destination and you can’t change your mind. For most users, this is fine.

But if you need more control over transitions, Mecanim can be configured in a variety of ways to meet your needs. If you’re unhappy with your current destination, you can hop in the pilot’s seat and can change plans midway through your flight. This means more responsive animations, but also many opportunities to get lost in the complexity.  

So let’s walk through a few examples to sort that out. We can begin with a fairly simple state machine with four states, labeled A to D, and triggers hooked to every transition on the state machine.

image05

By default, when we trigger the A->B transition, our state machine transitions towards B and nothing can keep it from reaching its destination. But if we go on the A->B transition inspector and change the interruption source from “None” to “Current State”, our journey from A to B can be interrupted by some triggers on state A.

image01

Why only “some”? Because the “Ordered Interruption” checkbox is also checked by default. This means only transitions on state A that have a higher priority than the current one are allowed. Looking at the inspector of state A, we can see that this only applies to the A->C transition.
image02
So if we activate the A->B trigger, then shortly after the A->D trigger, our transition remains uninterrupted. However, if we press the A->C trigger instead, then the transition is immediately interrupted and the state machine starts transitioning towards C. 

 

Internally, the animation system records the pose at the time of the interruption, and will now blend between that static pose (X) and the new destination animation. image04Why a static pose, instead of a possibly smoother blend between the current and new transitions? Simply put: performance. When a game faces a cascade of interruptions, keeping track of several dynamic transitions taking place simultaneously would quickly made the animation system unscalable.

Now, if we uncheck that “Ordered Interruption” checkbox, then both A->C and A->D can interrupt the transition. However, if they are both triggered on the same frame, A->C will still take precedence because it has a higher priority.

If we change the interruption source to “Next State”, A->C and A->D can no longer interrupt the transition, regardless of their order. However, if we press the B->D trigger, we will immediately start transitioning from A to D, without completing the transition towards B.

Transition order matters on state B too. The “Ordered Interruption” checkbox is not available anymore (any triggered transition on B can interrupt the transition because they do not have a priority ranking relative to A->B), but the order of the transitions on B will determine which transition wins if both are triggered within the same frame. In this case, if B->D and B->C are triggered in the same frame, B->D will be selected.

image03

Finally, for complete control, we can set the Interruption Source to “Current State Then Next State”, or “Next State Then Current State”. In that case, the transitions will be analyzed independently on one state, then the other.

So, let’s assume we have the following configuration.

image00

During the A->B transition, a very excited player triggers four transitions within the same frame: A->C, A->D, B->C and B->D. What happens?

First, “Ordered Interruption” is checked, so we can ignore A->D right away: it has lower priority than A->B. The current state gets resolved first, so we do not even have to look at state B to know that transition A->C wins.

image02image03
However, with the same configuration, if only B->C and B->D get triggered, transition B->D will take place (it has greater precedence than B->C).  

Now, this is only for one transition… All other transitions can also be interruptible too, with their own specific rules. So if we make transition A->C interruptible from the next state, we can have transition A->B interrupted by A->C which in turn could be interrupted by C->D.

One important thing to keep in mind: regardless of interruptions taking place, the source state remains the same until the transition is complete, and Animator.GetCurrentAnimatorStateInfo() will always return that source state.

In short, transition interruptions settings are powerful and offer a lot of flexibility, but they can quickly become very confusing. So use transition interruptions wisely, and when in doubt, test it out in the Editor.

17 コメント

コメントの配信登録

コメント受付を終了しました。

  1. When you guys write technical (and useful) blogs like this, you should link them in the manual and scripting reference (ex: more information section). These great blogs tend to get lost over time and google isn’t a help there.

    Ty

  2. Alan Mattano

    7月 14, 2016 10:18 pm

    I’m not using State Machine because of there is little manual and videos information on how to use it. I wish to use State Machine not only for animations. So this blog push me to keep looking into it! thx

    1. Catherine Proulx

      7月 14, 2016 10:36 pm

      If you want to use State Machines without animation, look into State Machine Behaviours on empty states. While State Machines were designed with animation in mind, they extend surprisingly well to general state machines (I’ve used them that way in my Hack Week project)

      1. Isn’t that what playmaker is for?

      2. Can you link it here?

  3. How about if you want to cancel the animation mid way. How would that work?

    1. Catherine Proulx

      7月 14, 2016 7:08 pm

      You mean triggering a transition when you’re playing an animation, and no other transition is taking place? The simplest way is to create a transition with no exit time, and hooking that to a trigger. You can then call GetComponent().SetTrigger(“myTrigger”).

      I’ll refer you to the tutorial on Animate Anything With Mecanim for a detailed explanation.

  4. popusMonster

    7月 14, 2016 9:17 am

    “yebać” – Popek

  5. As you improve the documentation, could you also shed light on if a sub-state machine is or isn’t a full-fledged state? They can have StateMachineBehaviors on them but are not taggable, and if you have a series of nested sub-state machines querying an Animator state in runtime becomes difficult quickly.

    I know that one workaround is to record entry and exit in the SMB on the sub-state machine, but in order to actually track the onstate enter and exit for a sub-state machine, you have to transition into the state machine itself (vs directly into a sub-state or sub-state machine, sub-state machines sub-state, etc). That is, you must use the Enter Exit nodes. This can force logic to be moved into inappropriate places; in short, allowing state machines to be hierarchical seems like a natural solution for all of this (see “Stateless” as an example of hierarchical state machine implementation: http://ayvazyan.net/2011/07/stateless-a-c-hierarchical-state-machine/)

    Thanks, as always!

    1. Catherine Proulx

      7月 14, 2016 6:53 pm

      Thanks, that’s actually a good topic for future blog material, exploring sub-state machines, their current limitations and their different use cases.

      1. Thank you for your reply, Catherine. If I can help with blog materials (feedback, screenshots) based on my experience will gladly do so – find my email via my Unity login info and send me a message if so!

        For today, however, what would you recommend as the best (least code) way to query if a sub-state machine is active or not?

        Cheers,
        Arun

  6. Excellent explanation, thanks !

  7. Robert Cummings

    7月 13, 2016 6:59 pm

    Thanks, agreed the manual is lacking, so please keep up the great work. Appreciate your consideration.

  8. Will this post be linked in the documentation? Otherwise it’s still difficult to find.

    1. Catherine Proulx

      7月 13, 2016 5:22 pm

      We are working with the documentation team to improve the animation documentation. But we chose to put the information out there today, rather than letting our users wait for a user manual update.

      1. Thanks, because it is awful.

      2. Mike Croswell

        7月 23, 2016 9:03 pm

        I’ve always felt the documentation is some of the best given the complexity and breadth of the Unity system. However, many of the areas are not getting the love in the documentation (particularly the Reference system with the wonderful code snippets) that they should. Please redirect resources to the original documentation group. My two cents.