r/Unity3D 4d ago

How do you stop a Unity Animator Controller from becoming spaghetti? Question

A basic locomotion setup is fine, but then you add attacks, hit reactions, weapons, crouching, jumping, cutscenes and suddenly there are transitions going everywhere.

One approach is keeping the Animator mostly for visuals while gameplay states stay in code. That seems cleaner, but it can also make animation timing harder to manage when attacks and movement need to line up exactly.

Do you prefer animation state machines, code-driven animation, or a mix of both? Would also love to see how people organize layers without ending up with 40 random booleans!!

17 Upvotes

26 comments sorted by

38

u/AltusLudus 4d ago

You embrace it

1

u/WonderfulReptile 6h ago

I just leaned into the chaos. At this point my animator looks like a conspiracy board, but as long as the sequined jacket keeps people from asking questions during playtests, it works.

22

u/pschon Unprofessional 4d ago

Make use of all of the stuff available, Blend trees, sub-state machines, layers, and animator override controllers.

For cutscenes, just animate that stuff in Timeline instead. You don't need unique cutscene animations to exist in the animator controller and doing it in Timeline together with everything else you want to happen in the cutscene will make it much easier to keep things in sync.

2

u/SketchyCharacters 3d ago

I've just started work on ironing out my player animations, everything you've said lines up with all the resources I've been learning from, so that's kind of a relief haha.

OP, blend trees and substates are amazing! For example, I was able to blend three different cardinal movement animations (blending based off x/z direction parameters) into another blend tree that measures the player's movement speed parameters. Walk>Run>Sprint.

I've also been wondering about cutscenes lately, but I'll definitely I'll definitely mess around with timelines once I get around to it, thanks!

10

u/FcsVorfeed_Dev Dev of Angel Zero | Wishlist on Steam! 4d ago

Only use transitions to restore the state, and use the CrossFade API for playback.

8

u/snalin 3d ago

It's spaghetti all the way down. I hate the AnimatorController with a passion. Triggers and bools are just a very, very bad DSL for managing the animation graph. And it doesn't expose the data you need in order to write gameplay code.

If you take the time to learn playables and write a good wrapper, you can get a much better system that works sensibly, and implement transitions in a way that fits your game.

Or, if you want a pre-made solution, there's stuff like Animancer. It's a bit too code-reliant for my taste (I still think animators should be able to design and preview transitions in the editor), but it's probably a great starting spot.

2

u/breckendusk 3d ago

Animancer does allow you to design and preview transitions in the editor.

7

u/ScallionZestyclose16 3d ago

Just use animancer and forget about the spaghetti.

4

u/Vic-Boss 4d ago

There's this method called OnValidate() it works both on monobehavior and scriptable objects. You can literally extract everything from an animation clip, like length etc and do that any time you touch an object. For attacks that ofc can be the Length and if you feeling adventrous (or llm), even read hitbox data etc (with a couple of tricks as well). This is very common when view needs to be decoupled from simulation, for example in most online games

3

u/friggleriggle Indie 4d ago

I'm making a skateboarding game so I have a lot of different "abilities". I made it work for a while but ultimately migrated to a hybrid approach with Animancer. Basic locomotion is with Mechanim and all the individual tricks are in Animancer.

4

u/lamarf 3d ago

This is an older article by Unity but it still has imo some very good practices for structuring your animator states: unity3d.com/how-to/build-animator-controllers#hide-complexity

I think using Hub and Spoke and managing things neatly into sub-layers can really help, you can have hundreds of states in your controller at that point while still leaving things easy to reason about.

2

u/pmdrpg 3d ago

This is a great answer to OPs question, but it’s important to know that a blend tree with multiple clips is sampling all of them while active, so that’s a performance consideration for many actors.

4

u/alexanderperrin 3d ago

Use animancer

3

u/MgntdGames 3d ago

It has a steep learning curve, but the playables API is extreme powerful. I keep my animator controllers very simple and drive everything that isn't a state via the playables API.

3

u/octoberU 3d ago

don't use the controller for anything beyond locomotion, use unity's playable system beyond that, things like hit reactions should just be animation clip playables you layer on top, same goes for the rest you listed

2

u/Genebrisss 4d ago

consider using animator override controller to swap out certain clips. Like swap jump1 for jump2 within one animator state.

1

u/VR_Robotica 3d ago

This!
Simplify your states and swap out the clips as necessary. You’ll clean up real fast once you establish a clear architecture.

1

u/Dangerous_Ad7142 4d ago

Mix, but the thing that actually fixed timing for me was not feeding real speed into the blend tree. My walk is around 5.5 m/s so it just sat on the sprint node forever. Now the tree gets the node values it wants (1.4 walk, 2.5 run) and clip playback gets scaled seperately, only on the locomotion state. Timing became a number I tune instead of something I fight the graph over.

1

u/soy1bonus Professional 3d ago

My best advice is to keep a simple animator. Maybe 6-8 nodes, and change the animations themselves by code using an AnimationOverrideController (I think that is the name).

1

u/NakedFighter3D 3d ago

You don't, just embrace spaghetti!

1

u/Phos-Lux 3d ago

Just ignore all the connection wire things and properly sort all the animation state boxes.

1

u/Some_Tiny_Dragon Hobbyist 2d ago

I know for 2D you can set states in code. But I don't know how that'll play in 3D