- Home /
How Complex Should Mecanim State Machines Be?
I'm toying with some Jump'n Run character controls like in those those old twitch action console games (run, dash, slide under obstacles, zig-zag wall-jump, ledge hanging, etc.)
Now I've only added a few animations to the character (and half of them don't even have proper transition animations yet) but my Mecanim Animator state machine is also getting nigh unmanageable:
I've looked and blend trees and maybe I can merge the "Stand", "Walk" and "Run" animations into a single state and decide the "Jump" and "RunJump" states via conditions on the transitions, but it wouldn't do much good.
Sub state machines also don't seem to be particularly suited to relieving me of the maze of transitions that is slowly developing.
Is it normal for those state machine to get that complex? Can anyone recommend measures to simplify my state machine?
So what is different between RunFall and Fall, or RunJump and Jump?
"Jump" is a vertical jump, legs together, very low horizontal momentum. "Fall" is the normal falling pose when walking off a platform or letting go of a ladder.
"RunJump" is a running jump, legs split, like a hurdler, with great horizontal momentum. It would look silly to suddenly take the free-fall pose after that, so the fall uses the "RunFall" pose. Unless momentum is lost (eg. player hit a wall), in which case it'll turn into a normal "Fall".
Hmm, it almost seems like you can combine the similar states, but I'm at a loss at the moment as to how to account for them within the newly combined state (at least in an easier to follow manner).
Are you finding a lot of repeated code too, or is it just hard to following state transitions?
Of course not, duplicate code is a cardinal sin ;)
I'm a software developer, so I feel more at home on the code side. In code, I can just decompose this into logical components, eg. maintain player state in a shared object and use a design akin to the strategy or state pattern to isolate swim$$anonymous$$g, walking, climbing, jumping, rope-swinging etc. into pluggable behaviors. Which allows me to extend the player movement controller without adding complexity.
But in $$anonymous$$ecanim, it seems the idea is to lay out the whole world state graph in one big diagram. Unless I'm missing something, which is the point of my question.
I'm thinking of trying to combine the (stand,walk,run), (jump,runJump), (fall,runFall) etc. with blend trees and choosing the right transition animations (eg. run to runJump) by setting up appropriate conditions.
And I've yet to try out if switching the $$anonymous$$ecanim Animator state machines on the fly is possible. If that works well, I could give each Behavior class its own animation state machine.
Answer by Cygon4 · Nov 28, 2012 at 05:12 PM
I have dug out a thread from the Unity forums where a user with 700 animation clips asks the pros whether Mecanim will support this and is given some concrete advice:
Q: We had around 700 animations on the player (that number is still rising BTW) and I was wondering if mecanim will be able to handle such a number?
A: Well the intended design here is to use sub statemachines. About performance it doesn't matter how many states exists, what counts is how many transitions exist in the current state(s) and how many animations are currently being blended (on all layers combined)
After looking at your graph I would recommend making 4 sub state machines.
Jump + Fall - Walk + Turn - Crouch - Prone
Then each of these areas could have the space and layout they deserve.
UPDATE: After experimenting with sub state machines and blend trees for a while now, I am slowly figuring out how to effectively use them.
This would be my recommendation to other people finding this topic:
Blend trees can cut away entire dimensions of the problem space. If your character animates differently based on speed, health or other properties, but essentially still does the same things, you can use blend trees to kill any complexity that would arise from this right away (and you can nest blend trees, too).
Create layers for any animations that need to be superimposed on others (a typical example is shooting, which could happen while holding onto a ladder, jumping, running or squatting). Layers let you can decide whether these superimposed layers override bones or only contribute (bone masks control which bones are affected).
Whatever animations remain now should be organized into groups and put into sub state machines. A sub state machine is actually a folder, not another state machine. Transitions never go to a sub state machine, but to a specific state contained in a sub state machine. Likewise, transitions out of a sub state machine don't just go up, they lead to a specific state outside the sub state machine (and possibly inside another sub state machine).
To provide an example for how I resolved the messy situation that lead me to ask this question, here's the revised version:
With hanging, kneeling and sliding being sub state machines. Here's the kneeling sub state machine, for example:
I left the basic ground-based motion (running, jumping and falling) in the root state machine. Many of those states are actually blend trees (for example 'Locomotion' is a blend tree between standing, walking and running based on speed, same goes for 'Jumping' which blends between a standing jump and a running jump based on speed).
So the moral of the story is, don't fear sub state machines and know all the tools at your disposal in Mecanim - which is a bit difficult since the Unity docs currently only describe the what, but not the how or why. I hope this helps other new users finding this post :)
Hey this was really valuable, thank you. I am currently working with a sprite animator, and the list is getting high. The transitions are doing my head in.
I have a question, though, within the script for 2D sprite animations, what would be the best way to call the animations. I am using boolean at the moment, just switching sprite sheets on and off. But I can see this getting pretty complicated as it grows too. - Hope you can give a tip. Cheers!
I am not sure if this has changed since you've answered but what you say in point 3 about State$$anonymous$$achines is not true: "Transitions never go to a sub state machine, but to a specific state contained in a sub state machine. Likewise, transitions out of a sub state machine don't just go up, they lead to a specific state outside the sub state machine (and possibly inside another sub state machine)."
You can make transitions from the State$$anonymous$$achine itself to a state or another State$$anonymous$$achine and vice versa. As there are no $$anonymous$$otions on a State$$anonymous$$achine, Transitions have no exit time and no FixedDuration but they can have conditions.
Answer by Paulius-Liekis · Nov 28, 2012 at 02:42 PM
Yes, state machines can get pretty big :) I attached a BlendTree defining movement of character in "Battlefield - Bad Company" (obviously not made in Unity). This is only for movement. There was another same size for shooting and a couple more for cutscene and similar stuff :)
So yeah, you can expect the state machine to get quite big for detailed character setup.
Well, I was looking for a way to avoid this mess, not for encouragement to accept it as the way things are ;)
Thanks for posting that bad company blend tree; is there a higher-res version of that somewhere?
Yeah it would be very cool to see a higher res version of it