Unite 2016 - Mecanim Bonsai: Lessons from Firewatch and ReCore

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everybody I'm will Armstrong I'm on the spotlight team here at unity and before this I was the lead programmer at Campo Santo on fire watch I'm gonna go through a lot of what we learned from fire watch and a lot of what I've learned working with armature enric or here is it on the spotlight team at unity the mecanim is a very very powerful tool used for animation but I see it get kind of misused a lot misunderstood a lot mecanim at the end of the day is a visual scripting language it's a visual scripting tool it's a visual scripting tool that's built specifically for making animations but that doesn't make it not script and as you're building your mecanim for your animator controllers for any given character you need to treat it like you would treat a script you need to build for clarity you need a build for reuse you need to build to extend support and debug your entire mccann instead of the whole way through development it's very easy for animation tree to grow unbounded and become a sort of web of states it's very difficult to work with if you take time out of your schedule and kind of trim it back as it goes you can get your tree to grow in a sustainable way in a way that you can build on as your game becomes more and more complex and as your characters become more and more expressive so I'm going to start with an overview of the character Henry on fire watch nope still no anyway let's skip the video it doesn't seem to want to load if you're not familiar with fire watch it's a first-person game with full body awareness you play Henry a sort of out-of-shape middle-aged forest ranger out in the woods Wyoming there's a lot of very expressive player animation in the game despite only being hands and a body and because it's first-person with full body awareness it kind of mixes a lot of the problems of both a first-person character controller and a third person character controller you need it to be very expressive but you also need it to be very responsive and you can't really cheat a ton you can look down at any time and see your legs you see your hands touch things the state machine that I'm going to show you all the data that I'm about to show you is all from the animation controller that we shipped Firewatch with this is Henry as he shipped out so there can be a lot of really good lessons on what to do and a lot of stuff that I'm going to use an example of what not to do I'm gonna go over very high-level then kind of dig into a couple of really good examples afterwards so I'm going to be going quick for the next ten minutes or so kind of apologize in advance the things you should be looking out for is places that we were able to encapsulate complexity Henry was a complicated character and dealing with all of that complexity at once in one layer or one state graph was completely unworkable so we had to pull everything in as much as possible get things hidden in sub States get complexity only where needed to exist and not everywhere the other thing to look for is patterns we used very very similar patterns in the state machines over and over again it lets you familiarize yourself and kind of get your bearings no matter what sub state you're in no matter what layer you're in we're gonna start out this is the list of every parameter that we shipped within Firewatch it's a lot but it could be a lot lot worse you'll see a few things in there like item type item type could be think we had over 40 different kinds of unique items that you would hold in your hands use type same thing we had a lot of different variations on them it very quickly became obvious that having a different parameter for every single item used every single pickup which is sort of the naive implementations how we started was not going to work over time it's very very handy to pack those kind of similar bowls into one INT that you can then say if I'm gonna pick up a mug that's item type 0 if I'm gonna pick up a book that's item type 1 and I'll show you how to organize that so that the fact that it's just numbers ends up being an aid not a detriment this is our first layer basic locomotion everything builds off of this so you want to keep it as simple as possible when you're thinking about layers think of them as like kind of a rough analogy to a class in script you want everything in a layer to serve a similar purpose because every layer controls both what other layers it overrides whether or not it affects certain bones whether or not that layer is said to be additive or standard overriding animation it can get very complicated very quickly if your layers don't serve sort of a holistic purpose again think of it like scripts think of it like a class you want everything in a layer to share both the same behavioral and the same logical function so I said that the base locomotion state was simple it's not it's hiding all of its complexity this is our locomotion blend free it's scrolling off both the top and the bottom of this screen it's there's a lot here this however was built over the year development of fire watch and it never really gave us any problems blend trees don't have state they don't call back out into code all they do is blend between all of these different clips based on your whatever parameters you pass it that means that you can iterate on it without about breaking the rest of your game this is a perfect place to hide complexity the second you start seeing a tree that has lots of different clips that are transitioning back and forth between them interrupting all of those transitions what you probably want is a blend tree a blend tree is going to hide that web of states but in a much much simpler way and prevent you from causing bugs down the road because you can't tie behavior to most of these animations you won't and you'll end up with a much more stable setup for iterating on as you move forward also you'll notice that a lot of these clips are actually the same clip duplicated multiple times in a blend tree the reason for that is it gives you really tight control over the final look of your game if for example if you're going from like a jog to a walk to a run you may want that jog to walk transition to happen at like 10 or 20 percent of your total speed hang out in the walk for until you're at 80 or 90 percent of your total speed and then finally move into your faster run by putting the same clip in twice you can then just control those blend tree weight knobs to be at those percentages and you'll just crossfade the clip between itself and then the final result will look consistent across the board so an example of going back into your macadam trees and turning trimming them as you go is this layer it doesn't do anything in the final game it was a feature we added and then cut and forgot direction remove the clip from this is a pattern you're gonna see over and over again in this tree this is kind of the hub and spoke most layers have this pattern this pattern is really really powerful what this what this layer does is it just hangs out and does nothing most of the time this layer is responsible for all the actions on the right arm mostly that is being driven by the lower level states like locomotion but when you're doing something specific it bounces out of that empty state goes and does whatever sort of conceptual job needs to do interact with an item interact with the world pull out your compass and then goes back into that empty state when you're looking at this tree for the first time it's you know you can see those just come out come back in and come out come back in and it's easy to sort of spot where the problem might be as you're debugging this is the other pattern I've used very very heavily throughout this state machine shared entry share to exit this got added relatively so Firewatch started development in unity for six so these mecanim features were coming in as we progressed I think this came in in five or five to using the entry and exit states in a sub state machine is guaranteeing to whatever other team members might be using this animation system that you're you don't care about the sort of higher level state structure you don't care what the tree that is above this looks like you will handle any variations that need to hint need to be handled on the entry you will handle any variations that need to be handled internally and then you will exit gracefully use this pattern over and over again to have an encapsulated piece of state all right I'm going to start going through these layers real fast now because they're just the same this is the left hand it's hub-and-spoke bringing down into the map very similar you've got idle the empty map locomotion nothing very complicated here going on you'll know though this is kind of a web everything kind of cycles around this probably should have been double entry this definitely should have been ample entry look at I mean this is just exactly the kind of web structure I was talking about this is raising and lowering a map and idling we should have just driven that parameter around if you want to get the behavior of having a nice slow graceful transition from something like a raise to an idle to a lower you can do that by just controlling the rate at which your game code alters your parameter you don't have to use a transition of a transition isn't the best fit because like I said everything can interrupt everything else this was a source of quite a bit of bugs and this is what happens if you don't do any of the things I've been talking about if you just let animation run wild this is all of the different performance on the radio hand raising it up bring it to your face gesturing with it is a nightmare fortunately almost none of this affects game code this is all purely visual because it was purely visual it was allowed to run a little rampant and I never went back and fixed it up it was also always working since it wasn't causing bugs we didn't fix it it's not worth making something elegant if you're gonna just to fix bugs later if it means you're injecting bugs now there's just a bunch of additive anims hub-and-spoke you can see the beginning of the item type pattern all of these transitions key off of item type and all of these transitions are ordered for in an ascending order so that first transition happens when item type is 0 the next one what item type is 1 the next one is item type is 2 that let's just collapse what could be a really ugly number of variations into a single integer and then you can track down exactly where in the list that is requires a lot of discipline to keep that working but it's completely worth it I have no idea what this layer does I actually found it when I was making this presentation I never saw it before a couple of weeks ago and I couldn't be happier about that it's the hub-and-spoke model it uses all of the same parameters that we had already established it uses the same patterns that we had already established and our animator was able to add an entirely new layer completely by himself to make new gameplay systems happen but work correctly without a programmer that's the dream of mecanim that's why you have a visual scripting system so that people other than programmers can make complicated systems this was the upper body blend used both hands hub-and-spoke nothing complicated generic use also nothing complicated hub-and-spoke just as simple as the last layer okay I lied this is actually what's inside that sub state machine it goes on for a while here we we have a lot of different items that you can use in fire watch and all of them ended up with separate animations while this looks like a nightmare again we were very very rigorous and making sure that every state in here had a shared entry a shared exit had and flowed freely through there no interruptions no cycles no way that it could get stuck in the sub state so once it went in it was going to play some sort of use animation and then come back out the specific animation didn't really matter for the logic this is also strictly ordered from item type zero all the way to you know I don't think forty six or however many we have up there spine blend this is roughly late in the tree because any time that you're setting up an additive layer it's gonna affect every layer below it this is why you kind of need to think about your layers ahead of time having a layer this deep in the tree lets you have a consistency motion across a bunch of different states in this case it's just a spine blend so it's kind of like doing the sort of resting breathing motion you want that to move across all of your locomotion relevant states otherwise you're gonna see hitching it every time you change between one layer another if you put this sort of spine blend animation into all of the clips with holding an item or picking up an item or moving around you're going to get the player jerking at when they pick up an object it's a really good use for additive layers and like I said why you need to kind of think about the structure of your layers ahead of time so now we're off of locomotion we no longer need that spine blend there's another hub-and-spoke this is for all the full-body animations moving around the environment repelling down walls spawning in in the first place this is all of those navigation moves we called them cool guy moves because you were using through the world like a cool guy we once again packed a whole lot of variation into one sub state we have a really consistent pattern the entry exit again and we once again sorted by move type so every we put edges in the world and you could just put an int on them that said what kind of move should I do when I get here and these moves are in order of those in zero two however many we had it 20 this is the lockbox this is not how you should set up tree is it get another example of just letting it kind of grow organically over time there's also one of the first things we set up we got it working once and we're really really hesitant to break it this is an example of what you could don't want to do with visual scripting all of these states use animation events to tie in very directly to UI state and game state so any alteration to this state machine would break like the lock box UI or render the game unplayable so we could never clean this up try to avoid getting in the state in the first place additive spine blend looks like the simplest layer in the game all it is is how we keep your hands on screen as you look up look down the subtlety here is this layer it's weight was actually driven by a animation parameter every frame we read the value of the spine blend weight and write it to this layers weight if you look in the animation editor you can see there's like an ad curve button that allows you to go in and and hand animate any animation parameter you want the game so this let James go in animate the strength of the spine blend inside of every animation in our game to fix any bugs he ran into where you know your hands are you're looking up and then all of a sudden you start to vault over a log you need your hands to come down and we need them come down quickly but we don't want it to pop so by X by letting mecanim animate itself and feed into itself you get a lot more power to your animators wouldn't be possible without the parameterised and kind of scripted the nature of this the next two states were just additive States for little tiny fix up they don't really do much this is all the different animation systems working together this is a full-body animation that's keeping Henry looking down and getting his hands more less than the area this is our spine blend completely turned off because all of these lock boxes are the same height and then additive finger layers on top of that causing the movie to actually play the movie to actually play so moving quickly into our specific case studies here's going back to those cool guy moves all the different Mantle's you'll see they all have kind of two sub state machines this is a pattern that you should probably be using on any character that has a very player-driven interactive feature you've got a critical period and then a settle if you think about like a shooting or revolver you want the gun not to fire again until you're done once but after that and you're trying to come back to neutral you want to be able to fire again that would be critical section settle every one of these moves has the same thing you jump over a log you've land we want to let you start walking again quickly but we don't want to let you interrupt that jump so you're breaking it up logically you're saying here's the part you can't interrupt here's the part you can digging in deeper to those each one of those has variants inside of itself so this is another example of hiding complexity there's fast and slow versions of all of this if you're here you can see maybe so this is getting over a log slowly from a standing start and same logical animation different Clips when you're moving fast the reason you pull all of this into a sub-state inside of a sub-state inside of a sub-state is you've got a full-body animation you know that that's gonna take over everything you've then got you know it's a cool guy move so you pull into the cool guy moves you know that there's a critical section you look in the critical section you've got the fastness level breaking all that down like that means that you can track down a bug very very quickly if you have a problem with settle in general if you have a problem with the critical section in general you know that it's at the transition in the parent state machine if you have a problem only with slow only with fast you know it's a problem with the transition inside your sub state machine using patterns like this we found speeds up development massively our our animator can go in look at a perfectly setup cool guy move and make a variation on it and he knows exactly how to do it there's just you have the one new int the one new parameter that gets you into the sub state machine everything else is exactly a duplicate you know every transition you're gonna have to make every clip you're going to need to override makes it very easy to estimate how long the variations take and as I said makes debugging and fixing this stuff of worlds easier another example of this is the hands are we had like a bottle grip and then a big book grip we had a small object grip all of these are gonna have the exact same pattern here this is the this is the book this is large items you can see that they're almost identical both of them have a pickup holding it and then like five different ways to put it down there's also another case where probably should have pulled some of this into a sub state machine so once you have your animations working correctly and your clips playing correctly your characters looking like you want them to you then need to feed back the state of your animators into the state of your game mecanim gives us a bunch of really good tools for doing that animation events let you tie a specific moment of a clip into a specific change of state of your game these are perfect for like firing off effects firing off sound effects firing off particle effects attaching and detaching other actors they are however a little bit tricky to use reliably if you transition out of a clip before the animation event is fired it never will fire and if the animation that is is playing on a layer that has zero weight no animation events will fire from that layer in order to solve this on Firewatch we actually added a state machine behavior that let us say always fire this event I don't care what happened I don't care when we transitioned out if we get to this point in time fire it if we leave this state fire it anyway this was perfect for things like dropping an object once the player is said I want to put down the baseball I don't really care what else happens at the end of that animation clip it should be put down ideally it gets thrown at the moment of release but yeah the speed of state machine behaviors it's a bit of code similar to amount of behavior that you can attach to any mecanim state you want these have excellent like on start state on exit state on state machine start on stop state machine exit callbacks very similar to like on start on the navel they're perfect for attaching behavior that you want to tie directly to your the state of your animator itself they are extremely bad however for writing gameplay code in inside of them if you write too much gameplay code inside of a state machine behavior it very quickly becomes difficult to track down where your changes in state are coming from I highly recommend that if you're using state machine behaviors to drive gameplay code use a messaging system talk to a manager fire off parameters at a higher level try not to write a ton of complicated code inside of them you'll never remember what animator what state what layer what where did I put that code the exception is if you're writing state machine behaviors that drive your animator themselves and debug break it is the single most useful state machine behavior on state enter debug break you can attach it anywhere in your mecanim setup and you have a breakpoint just like you wouldn't any other visual scripting system so while fire watch had Henry which was one complicated character recore had Luna there jewel and the core BOTS these had jewel has an enormous amount of player state and every one of the core BOTS has combat special attacks environmental attacks and navigation so very very complicated very very complicated while this is definitely not gorgeous it did work this ship the game the ship game and extremely high quality with extremely complex characters on some level when you're dealing with complex content you're going to end up with complex data if you look at this state machine though you'll notice that there's a most states only have transitions out not transitions in the reason for that is not only did every one of the core box have a complicated animation state machine they also had a complicated a eye state machine that they needed to keep perfectly in sync all the time if you find yourself in a similar situation that's when you should just skip mecanim it's a visual scripting language built to do animation but if you've got another scripting language if you have another state machine that's driving your behavior mecanim can still just be used to drive just the animation itself use an animator dot play crossfade crossfade over fixed time you can make dynamic transitions without having to worry about the complicated tree structure that you know can otherwise get really really difficult to look at once you're dealing with a tree at the complexity of jewell you can't really afford to set up that kind of state machine more than once you have to remove as much work as you possibly and you're you know once you've gotten to the point where your tree is sprawling you don't want to have to grow another one a couple of different ways that we mecanim lets you do that for jewel armature use sink layers so a sink layer those the may not know is you set up a tree once you set up all of your state once in the case of jewel it was every single piece of locomotion animation every movement every jump all of it all every possible player state when moving around the world and then they made to sync layers for aiming and hip firing you immediately get every state replicated you get every transition replicated you're guaranteed that all three of those layers will always be identical except for the clips inside of them so you can then go in and say replace all of these clips with the exact same animation but holding the gun out aiming the gun up if you're doing the same kind of thing for multiple controllers multiple characters we have a there's a better tool in mecanim which is the runtime override controller works kind of similarly it lets you take a dictionary of animations and replace them with a dictionary of other clips an example of that would be the core BOTS these guys are both playing their idle they look entirely different exact same state machines set up only difference is when you spawn in the spider there's a runtime animation controller that's a runtime override controller that says replace the dog idle with the spider idle this is best used for spawning in AI variants or variant players currently there is a bit of a hitch when you first set the runtime override controller you'll lose any state that you have so if your characters are on screen while you're doing it it causes a little bit of issues this I believe is getting fixed above for the time being use this on spawn though between fire watch and recore and a bunch of my friends in new projects I've seen a lot of the same sort of problems crop up over and over and over and over in an animation setups if you find yourself with a chunk of your tree that has just become unmanageable occator you're having constant transitions constant interruptions it's very easy to lose what state you're supposed to be in that chunk of your tree should probably be a blend tree you also want to make very very keep a close eye on the interrupt settings of all of your transitions it's very easy to find yourself in a situation where you're transitioning from say walking to falling you begin the debt transition you land because you were just off of a little step transition back to from falling to walking but you still play an entire cycle of that fall loop if you set your initial transition to interrupt based on the next state it'll shortcut all of that if you start finding problems where you're just not responsive enough it's probably the interrupt settings on a given transition if you find yourself completely in the wrong state it could be that you've got animation of instead of getting skipped use the reliable animation events that I was talking about earlier and there's gonna be a rough one to say I feel bad for any buddy that uses this heavily but the other problem is you might be using triggers I know triggers are widely used in mecanim they're super simple they're really easy to set up they cause a ton of issues if you use a trigger and any transition anywhere in your mecanim setup listens for that trigger it's gonna clear it that means that you can have a perfectly working animation controller anybody on the team can go in on any layer for any reason and instead of any transition that uses that trigger and brake previously perfectly functional code and it's really really difficult to track that down is having a bonfire watch more than once we eventually just sort of moved away from triggers where possible additionally triggers won't set and do not get unset until you manually do it or the trigger actually gets used in a transition this very often will cause issues where you know you hit the button to throw an object while you were vaulting over something you can't buy the time Henry was done finishing his long animation jumps or thing stands back up I got a perfect Wow why oh right I clicked the button 15 seconds ago and I don't even remember what happened you can fix that by clearing out triggers manually but it's a lot easier just to avoid using them in most cases so if you're making like a simple mecanim for a UI element or a door that's gonna open and close by all means use triggers but if you're shooting for something that's going to have multiple layers multiple sub states lots of transitions try to avoid them or possible as a tree gets this big it's going to start getting slow you're gonna start running into performance problems potentially one of the first things I would look at if you're having the animators show up in the profiler is if you see the Tim palette that overflow message anywhere in the profiler that means you just have too many clips what that's saying is that we've run out of our extremely fast memory allocator space and are now go following back to this sort of default under the hood generic unity allocator the other common problem is too much blending macadam is very smart if you have a layer at zero weight or a blend at zero weight nothing will get processed whatsoever however zero and very very very close to zero are not the same number the easiest way to fix this is to just go in and make sure that your parameters clamped to actually zero if they get low whenever you're setting your parameter if you're setting it's like lower than 0.01 0.001 just clamp it to zero this can actually cause a lot of speed up if you have a lot of different blend states that are all minutely in there because you've got like a tiny tiny bit of like left or right on the stick all the time because of a dead zone yeah so as you build your original script in visual state machines as you build in mecanim just try to keep in mind that you are working with a visual script system think about it like code code takes maintenance every time you go have a big public-facing demo schedule a day to go back in and clean it up just like you would all of the hacks that you put in to ship it try and simplify where possible write a build with reuse as you go forward and if you keep your you know tree from growing uncontrollably you'll end up with a very you know polish ax Balearic tur you can end up with a very high quality bar like armature jib with Luna or we did with Henry thank you very much [Applause]
Info
Channel: Unity
Views: 48,501
Rating: undefined out of 5
Keywords: Unite 2016, Mecanim, Animation in Unity, ReCore, Game Development, Animation, Unite 2016 Los Angeles
Id: 8VgQ5PpTqjc
Channel Id: undefined
Length: 33min 28sec (2008 seconds)
Published: Thu Dec 01 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.