With version 4.0 Unity added Mecanim to its animation system, introducing a number of great features like animation retargeting, body masking for humanoid rigs, inverse kinematics and – my favorite of all – a visual animation state machine window. Anyone who has worked with the previous, exclusively code-driven legacy animation system might appreciate the ability to not only visually assemble the state machine of animations, but also being able to preview the motions, their trainsitions and blendings edit-time.
However, as with all state machines, complexity can really mess things up, whether you have a visual inspector or not. And animation state machines can get complex real quick: when you have a fairly detailed locomotion system, attacks with some variations, a number of non-combat motions and effects like injury and fatigue, you can easily find yourself having to maintain a sphagetti animation tree with 50-100+ states with transitions like that of a particularly diligent spider’s web. And just like that cobweb, you may never want to touch that state machine again…
Speaking from experience, let me share the techniques I use to overcome this issue.
When you feel your state machine is getting too big, ask yourself the question: is it necessary for every state to be in the same place? Chances are, you will be able to create logical groups of states that stick together and could be placed in a sub-state machine.
To create a sub-state machine, click on an empty space on the animator window and select “Create Sub State Machine”. This creates a new, hexagon-shaped sub-state, which you can edit by double-clicking it.
Below is an example state machine with mixed locomotion and combat animations, all in the same place.
Since combat-related animations are clearly distinguishable, we can separate them into a sub-state machine (“Combat” in the example).
The power of blend trees
Blend trees are great ways to blend between similar animations (for example running, walking and turning) based on one or more supplied parameters. This aspect of blend trees alone can help out a lot to keep your state machines more ordered. But despite their name, blend trees can also be of use when you don’t actually need to blend between the motions involved: whenever you use a numeric parameter to choose an animation from a number of options (e.g. when having variations for the same animation), placing them into a blend tree instead of giving all animations a different state might be the more maintainable way to go.
Take the below scenario for example, where we have 3 different attack types (two-handed, polearm and dual-wield), all having 3 variations.
To decide which state to transition into in case of an attack, we need to check two conditions in every transition: WeaponType and AttackVariation.
Below is the same animation logic placed into a nested blend tree.
Here the primary blend tree, Weapon Types decides which nested blend tree to pick based on the WeaponType parameter, and then the chosen blend tree selects an actual animation to play based on the AttackVariation parameter. Note that this is the same logic as in the previous scenario, but instead of regular states and transitions, all realized in a single blend tree.
There are of course many more ways you can harness the power of blend trees, and I haven’t even touched the topic of multi-dimensional blend trees (with which you can for example put together complete locomotion systems).
An important purpose of layers in Mecanim is to let you simultaneously play different animations for different body parts (with the help of avatar masks), like playing a wave animation with the right hand while all the other body parts play a walk animation. Another useful layer feature is letting you control the weight of the individual layers, which makes it possible for example to have a winded animation in a separate layer, and displaying how fatigued the character is by adjusting this layer’s weight, and thus overlaying it on top of the currently playing animations.
If your animation logic benefits from utilizing layers, doing so will also do its share to help keeping your state machine from growing overboard. However, using layers only to organize your state machine is not a good idea, simply because layers are not meant for that, and in that case one of the other alternatives would be the way to go.
Keeping your state machines organized is not just about aesthetics. A well-planned state machine is easier to navigate, and the logical grouping of states helps your brain to process the information faster, which pays out every time you need to expand or debug your animation tree.
Do you have your own techniques, questions or remarks? The comment section is all yours!