Never use the Unity Animator EVER AGAIN - Full Guide

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this video was an absolute doozy to make oh my gosh so in a previous video we explored converting all of unity's animator functionality into code this proofer concept explored getting all the animation States and putting them in the animator without linking any of them then in the script we played specific animations using animator doc Crossfade whenever the player would move in a specific way the backbone of this workflow was to Simply store the current animation that is playing in the script if an animation is requested to play it will check the requested animation against the animation that is currently playing if they are different it will play the requested animation this worked really well it means you can bypass using animator Transitions and animator variables and Trigger every single animation through code you all gave a lot of great feedback on the video of how to make the system even better and really appreciate your comments I listened and spent the past week designing a brand new system to handle animations entirely through script what I'm about to share with you completely changes the way we do anim a and unity to make them more intuitive straightforward and cck to design by the end of this video you'll have written or copied and pasted the one script that will allow you to play all animations through your script and then you won't need to use the animator ever again this script is my gift to you I just want to help your game development Journey so without further Ado let's get into what this magical script is the script I talking about is the animator brain so let's go over its importance for any project you have a unit which has animations this could be an enemy player or an NBC these units all linked to the animator brain script the animator brain makes all the decisions whether an animation should be played or not so let's go through what this means let's say the player is in the running forward animation the player presses the reload key and so the reload animation is requested to the animator brain the animator brain approves this request and so the reload animation is played now let's say Midway through the reload animation the shoot key is pressed and so the shooting animation is requested to the animator brain the animator brain observes that the reload animation is currently playing and knows it cannot be overridden because the reload animation needs to play all the way through so the animator brain denies this request and continues playing the reload animation then when the reload animation is finished the animator brain will now allow new animations to play we can give animations a couple of important attributes to dictate the difference between a shoot and a Reload animation the first is whether the animation can be overridable examples of an overridable animation are idle walk and shooting animations let's say the player is standing still and is playing the idle animation if the player starts moving the Run animation should override the idle animation and play that instead on the contrary there are also locked animations which are the opposite of overridable animations examples of locked animations are reloading jump hit and death animations once these animations start playing it should play all the way through and another animation should not be able to override it the next important attribute is whether an animation can override an already locked animation let's say the player is reloading and is Midway through and the player gets hit since the reloading animation is a locked animation it should block all incoming animations from playing but if the player gets hit the hit animation should play regardless of the animation is locked or not the animation should override any locks currently in the animator I'll call these animations critical animations so we have two key attributes an animation should have should it be locked and play all the way through or should it be able to override that lock so when a unit requests to play an animation what animation should it send to the brain first it should send the animation that is being requested the layer the animation is on whether it should lock the animation whether it should bypass the lock and the transition time of the animation in unity terms this is called the Crossfade by the end of the video you will have a script that holds all the logic in the animated brain now we know exactly what we're making let's hop into unity and see what this looks like all right so the unity editor and if I already to click play this is what I've got set up right now I've got my chicken and he can run around he's got the Run animation he can run left run right run back and forward he can also jump in the air he can also shoot and he can also reload and if he runs it here if I press a button I can also make him fall over and die now the key error is that every single animation in here is done bya script Nothing in here is done in the animator and of course separated it so you've got the top animation and the bottom animation right it can jump and it can shoot at the same time you can also jump and reload at the same time you know everything is separated and if I were to look at the animator here's proof I've got the player and I've got upper body lower body and look at all that there's no transition lines and if I were to go to perameters oh there's one here but I can delete that one there we go now this is empty and we've got nothing here now I'm actually using one of my new assets called light flicker ultimate and I'm using it on this lamp over here and at the moment is 50% off because it's a new release and it will end around next Tuesday so for the setup I've got the player over here now when it comes to the animator I've got two layers I've got the upper body and the lower body to separate them out I used Avatar masks so you can add one by going right click create and Avatar mask down here you can see there's two options you got humanoid which is the most common one and this is where you choose which parts of the body you want to keep and then over in the layers here I've got this upper body as the default layer and I've got no Avatar mask or anything here and in the lower body this is where I've added the lower body Avatar mask and I've set it to override and also the weight is to one so that the lower body is completely overridden by these animations you can see I've got all the things as before except the player does not have any animations they can jump they can reload but they just don't do any animations at the moment so I'm going to split this video into two chapters in the first chapter we're going to create the animator brain and once that's done we'll create a unit which will utilize this animator brain and this unit will be of course Alfred the chicken here and in the uh play movement script you can see there is nothing here to do with animations but first let's add the animator brain so I'm going to go into my scripts I'm going to right click and create a new script and I'm going to open that up so the first thing I'm going to do as I've created this class here is I'm going to make the play movement inherited so I'm going to make it inherit the animat brain so this works because the play movement inherits the animat brain and the animat Brain inherits monob Behavior so there's this really smooth train of inheritance that eventually leads to a mono Behavior so the first thing I'm going to do is I'm going to delete this and first create a e num and this e num contains every single animation that will ever need so I'm going to do this because if we want to send through a animation to play instead of sing through a string I'm going to send through an En num so it has to be one of these animations that's going to send through and at the very end I'm going to make a nonone animation over here this is so that you know you can send through a null animation and it'll just reset the entire thing so now next step is we need to link these animations to an actual animation so I'm going to create an array that contains all the animations that I can link it to all right so you'll notice that I've matched each of these to the animations and I'm storing them as an INT as a hash because you can actually go animator doplay and play it as a hash and that is going to be far quicker than trying to use it as a string so now I've got these stored one other thing to note is that these have to match the animator perfectly so if I to go back and yeah it has to load up but you can see here's Ido one AO 2 Ido 3 and I've matched these words up like perfectly so the next thing what I got on my notes is we need to put the variables in the first one is we need a reference to the animator that we want to play it through uh so this animator will be attached to in this case the player movement script um cuz you can see here if I go to my player I've got my animator here the next one is we need to know what the current animation is so I'm going to make a animations array and I'll tell you why in a sec and I'm going to name this current animation I put it as an array and the length of this array is the amount of layers that you have in the animator in the upper body what of these has to be the current animation right so let's they run one left is the current animation for upper body in this top layer and then in the lower body your current animation is I don't know the idle animation right so there could be two different kinds of current animations in each layer and I'll do the exact same thing but for if the layer itself is locked so I'm going to make a bull array so here we can see if any of the layers are locked and we talked about locked at the very start you know if a layer is locked then nothing else can be played right so let's say upper body is locked right now and you are playing the reload animation well if you would cue the Run left animation well it won't play because the upper body layer is locked right so yeah so this will keep track about which layers are locked and which ones will allow new animations to override them now these three are pretty straightforward but the last one might dig you hidden a little bit and I'll explain what it uses Okay so I've added an action here and it takes in an INT so what is this right you you might have never seen this before so it basically just stores a method and I'm calling this default animation so here's what it is in every single script that inher it's animator brain needs to have a default animation method and this is what it looks like so what this method does is it takes in a layer and it will play the default animation for that layer so what does this mean it means that if we were to reset everything to the start this is what this method does so let's say the default is a idle animation right well then we can say okay well the default animation is Idle but what if they're moving so let's do another chicken here then we can add another chicken here we can say if the player is not moving then we run an idle animation but if the player is moving then we do a run animation right so this is like the default a default chain right if everything else fails then we just run this and then we can get it to the right animation again so over here I'm going to hold what that method actually is and it's going to hold this method and in the animator brain if it needs to it can run this method from anywhere now we've got that done we need to make the initialize Method All right so this initialized method is going to be called in the start method of whatever script inherits it so in this case in the play movement script I'm going to go to start and I'm going to go initialize and I'll put all the variables I need in here right so that's what we do at the start now for these variables why have I put these variables in well first of all we need to pass in how many layers the animator has and of course there's two layers in this case the second one is we want to know the starting animation so you know what what animation do you want to start with and really it's we we're mimicking what this is we are mimicking the default state so that's what we're doing here and for the third one we are passing through the animator so that we can set it to this animator and we're also passing through the default animation method so that we can set it to this here so I'm going to start to fill this one all right there we go let me just walk through this real quick uh so first of all I'm going to get the layer locked array and I'm going to make the length of this the amount of layers now if you don't use C this here is going to ring a lot of alerts but since we are using C we can put our variable in here and yeah that's great love C uh so down here we've got current animation and I'm going to get the length of the current animation array and set it to the amount of layers and I'm going to set the animator to the animator and the default animation to the default animation and then I'm going to Loop through each layer and I'm going to make each layer not locked so I'm going to unlock each layer and going to set the current animation to the starting animation for each layer now there's a couple methods I'm going to add here now this one's pretty simple you know I'm taking in a layer and then it will return the current animation for that layer now I'm going to add a method to set a specific layer to be locked or unlocked right so this one just takes in do you want to lock the layer or not and it takes in the layer so you're just setting a specific layer to be locked or unlocked now we get to the fun part let's make the brain of the animator so I'm going to add a method called play now when play is called from the play movement script it's going to do a bunch of checks to see if it can play that specific animation or not now if you remember back earlier in the video we actually said the parameters that it needs to pass through right so these are the things I'm passing through when you play an animation or you request to play an animation you pass through the animation that you want to play you pass through the layer that you want to play the animation at you pass through whether you want to lock the layer or not you know like this animation is important and so want to play it all the way through so we're not going to allow any other animations to play we will pass through whether it should bypass that lock you know whether it's a really critical animation and it needs to play it and we're going to pass through the cross fade as well now the very first check is we're going to check if the animation is none so here we're checking if the animation you pass through is actually a none animation or like a n animation uh then we want to run this default animation method we want to reset everything back to normal and of course this will be set in the play movement script over here and we'll work on that later on in the video then our next check is if the layer is locked we don't actually want to do any other animations so I'm going to put that in so this is checking if the layer is currently locked then we will return it we don't want to play any animations however if you can bypass the lock then we will keep going we will play the animation regardless so at this rate we know that the animation is now going to play if it gets through all of these checks so now I'm going to update if the entire layer should be locked or should be unlocked there we go so let's say a Reload animation comes in of course the layer would want to be locked if the reload animation comes in so it goes through it's not a nonone animation and the layer is currently not locked then it gets to this stage and then will lock the layer I'm going to add one more check in here and that is to check if the current animation that is playing is equal to the animation here so here we're just checking the current animation that is playing is it equal to the animation that is being requested if it is we're going to return it because it's already playing now we get to the bottom of our checks now we're going to update the current animation so now we are actually now going to Crossfade the animation all right so this is quite a long lines I'll walk through what it is so cross fade what does it need it needs the state hash name and here we're just getting into our animations array which is this one up here and we're converting the E num here to an integer on that layer now actually this is completely done there is all the logic you need the only thing to add now is the exit cases now would I do that later so let's head back to our player movement script and let's get animating so the very first thing we need to do is we need to initialize so let's go to our start method and let's add that in all right so the things I passed through here what does the initialized method need it needs the amount of layers so I'm going to get the animator component and I'm going to get the layer count now for the second one the starting animation I'm just going to set that to the idle animation and then we need to get the actual animator so I'm going to get the animator component there and then I need to send through the default animation method and we actually made one previously uh down here now the next thing is I'm going to keep track about which layer is which layer so I'm going to add some constants all right so I've just set the upper body to zero and the lower body to one because the upper body is the zeroth layer and the lower body is the first layer all right now I'm going to scroll down here and I'm going to start making the default animation methods like which animations should be played by default so I'm going to split this into two methods so I've divided it into checking the top animation and checking the bottom animation so this method is just going to check uh the movement animations whether it should be running forward it should be idle whether it should be in the ear you know those kinds of animations so I'm going to run through them here all right so I've added a bunch of checks here first I'm checking if the movement doy is more than zero so what this means up here if I scroll up is our movement is set as a vector 2 to be the horizontal input and the vertical input so here we are checking the Y which is the vertical input and we checking if it's greater than zero so that basically means if we are pressing the W key or pressing the up Arrow key so if we're doing either of these we are moving forward and what animation am I going to send through I'm going to send through the Run forward animation and what's on next thing is the layer that it's on well I'm sending through the layer here so I'm going to put the layer in here and now the next thing is whether we should lock the layer well run forward isn't very important so I'm not going to lock the layer and and should we bypass the lock no it's not very important so I'm going to set that to false as well so now I've put all that in and I'm going to update the rest of these all right now that that's done I've just added in if the movement. Y is less than zero you're pressing the S key and then if we are not grounded then we're going to play the jump ear animation and if all else fails if we are grounded and we're not doing anything then let's play the idle animation now over here in the cheick top animation and the cheick bottom animation I'm going to play this method cool and there we go so our our top animation has been checked and our bottom animation has been checked so now let's run on down to our default animation and we are going to run these methods so now over here when we pass through the layer if the layer is the upper body then we're going to Che the top animation but if it's not then we're going to check the bottom animation now I'm going to be running this every single frame to check if we need to actually change the animations or not so I'm going to scroll up and at the very end here I'm going to check the top animation and I'm also going to check the bottom animation so with that done I'm going to head on back to Unity so you can see that it's running the idle animation when I start running it does the Run forward animation I can run to the side I can can run backwards it does all the right animations there's only one idle animation at the moment so I'm going to add a few more and you can see here on the upper body I've got three idle animations and the lower body I've got the same three idle animations so I wanted to cycle between these to do that I'm going to keep reference of what the current idle animation actually is and then in the start method I'm going to make a co- routine that switches between them every like 2 seconds so here what this Cod routine does is it repeats forever while true and it waits 2 seconds it adds one to current idle and then if the current idle exceeds the amount of idle animations then it sets it to zero so let's figure out what this is so here I'm just making a animations array and I'm setting the to every single idle animation that we have so if I scroll down all I need to do is replace this with the length of that array there we go now we've got every single idle animation that we need and we are changing the idle animations every 2 seconds so now I'm going to scroll down here to our check movement animations method so instead of just playing ID one every single time I'm going to play the animation that it's currently on all right so what does this do is it gets the idle animations that we specified up here and it gets the current idle and it's it finds the elements that's in the array right now and it plays that idle animation so let's head back and press play and you can see that the idle animations slowly transition from one to another and if I start running you know and then if I stop it'll go to that ID animation that is playing next all right so let's switch tactics and let's do the death animation what if the player dies well I've got a little bit of scripting here and that is in the update function and under the check death method so what this basically checks is if I press a left shipped then I'm going to kill the player right but just disables the play of movement script at the moment but let's make it actually play the death animation so what is this doing well I am playing the death animation and what layer am I playing it on I'm playing it on the upper body and what is the next one the next one is lock layer I do want to lock the layer so nothing else can get into it when I die and also I want to bypass any locks and I'm doing it to both of these so basically when you die it locks the layer and it locks it forever so here we go I'm running around and then I press left shift and he collapses there he goes and you'll notice that I'm trying to move and nothing happens because I disabled the play of movement script when I press the left shift button yeah you can see that death animation has played and it's played all the way through and it's locked all the other animations from playing all right now that one's off the list we are going to do the reload animation so how are we going to do that so under my update function I'm going to go to our check shooting method and under our cheick shooting method here if I press the R button then it will simply play the reload sound so I am going to change it all right so now when the r key is pressed it will play the reload animation and it will only do it to the upper body layer and what's the next one whether it should lock the layer so I've set this to true because we want the reload animation to play all the way through and nothing should be able to override the reload animation and also I've made it so it can't bypass any locks since it's not that important but there's one problem with doing this and you'll notice it if I go back and I'll keep my upper body open here all right and if I press R and do the reload animation then it will continue doing the reload animation and it won't stop right so we need some way of detecting when the entire animation has finished so we're going to add a new script and this script is going to be called on exit so I'm going to open this up so what we want to do is when the whole entire animation finishes or when the state is finished it will transition to another state and you might be wondering why not use on state exit well if the state is just going to keep on looping it's never going to exit so that's why I'm going to use enter now let's add a few variables in now when the animation finishes we're going to put in what animation we want to transition to next and we're going to put in do we want to lock the next animation and now let's add the cross phase for the next one so there we go now we've got our three variables when the animation finishes what we're going to transition two whether we should lock the layer for the next animation and whether we should cross fade it and by how much so I'm going to add a CO routine here and this Co routine is basically going to trigger once the state is over so let's walk this through when it enters the state it will play the co- routine and then it will weight the length of the State minus the cross fade so that when the cross fade is done crossfading it will be exactly finished and if I were to go back to our player movement script and scroll up you can actually see that I've made a public static variable here and named it instance and then in the awake I've set instance equals to this so here you just need to put any static monor behavior in here and then you can start the Co routine so once it has waited that number of seconds what are we going to do well let's first get the animat brain component that is on the animator right what are we going to do to it well we finished it so we're going to open back up we're going to unlock the layer so there we go I've set the layer to be unlocked to false so now we can play any animation again so now I'm going to play the animation all right there we go so after that's finished we will unlock the layer and then play the next one so if we head back to Unity you can see that we've got on exit here and we can select what animation it will go to after we reload so the animation we want to go to is actually none we just want to set it to the default animation again do we want to lock the layer well no do you want to cross fade yeah sure I'll set it to 0.2 actually to make my life easier I'm going to go back to our on exit and set the Cross Fade to 0.2 right now let's click play and let's try reloading it reload and once it's done we'll go back to idle and I can start moving around and I can reload and that'll work now another thing you'll notice is if I start spanning R it only does one reload animation at a time like it doesn't it doesn't override it and that's because I've locked the animation so that nothing else can get through even another reload animation now there's one more thing I need to add now this is a little bit more complex but we need to add it for everything to work so here's the scenario what if I were to start reloading and then die well you will notice that I go back to the idle animation but when we die I I don't want to go to any animation so what's actually happening here is I'm reloading and then I am overriding that reload with the death animation but but then if we're going to go back to our on exit script well the ctin is still going to have effect because it's going to transition to this next animation so if I do it again if I start reloading and then die we'll do the death animation and we'll go back to Idol so how do we stop this well I'm going to add another variable in here and name it cancel all right so what does this do at the very start of the animation when it enters the state so when the reload starts it will set cancel to be false and then when it goes through all of this it will check if cancel is still false if it's still false then it will play through this however if cancel has been SK to True somewhere then it will yield break and then it will stop all this from happening so all we need to do is if the death animation is played we need to set this cancel to be true so that this does not play so in our animated brain here's what I'm going to do is under this section here if we are bypassing the lock so like you know if the animation is critical such as a death animation or a hit animation then I'm going to set cancel for every single on exit Behavior to true so I do not want it to carry out all right so so here's what we're going to do if we are bypassing the lock like if the animation is really critical uh like a death animation then we're going to loot through each behavior that is on exit and then if the layer of the behavior is the same as the layer we're going to set the cancel to equal true but first of all we need to do this so there we go I've got the layer index over here so whenever the state is entered I will set the layer index to what the layer index is so let's head back to Unity and let's click play okay if I were to start reloading and die I should just die I shouldn't play any other animations and there we go now even though I was in the middle of reloading it did the death animation and it cancelled the rest of the reload animation so that worked fine all right so now let's get on to shooting let's do the shoot animation so let's go down to our check shooting method which is in the update method and is called right here and let also we replay the reload animation so here let's change what Al conts are for shooting so at the moment it's just whenever we hold the left Mouse button down but first of all I want to check if the current animation is not the reload animation because we can't shoot while we're reloading all right there we are so I've used the git current animation method which we put in our animat brain uh class over here and that is this method here so now we're finally getting to use it that's not all we want to play the animation if the ball shooting is equal to true so here in our top animation we're going to make some changes cuz when we shoot we don't even need to care about what the bottom half is doing cuz our shooting is in our hands all right there we go so if we're shooting we play the shoot animation and we don't even need to bother about the rest of them and of course the last change is that if we die then of course I'm not going to be shooting anymore so I'm going to get shooting and set it to false and I'm also going to change this a little bit I'm going to get the check death method and I'm going to move it underneath the check shooting method so here I can shoot and if I reload then it will stop shooting and it will reload and it will keep on doing that if I start shooting and then die then you can see I sto shooting and I just fall over all right let's add the very last thing and that is jumping so first of all let's go to our check jumping method which is of course in the update method and if we start jumping well I want to start playing the jump start animation and what I'm going to do here is it plays jump start on the lower body and also it locks the layer so it has to go through the entire jump start animation and it it cancels everything out now let's go back to Unity because let's go to our lower body and we've got jump start jump air and jump end so here we go so in the jump start when that finishes all the way through I want to make the on exit and I want to transition to jump air and I want to lock that layer and let's add a cross fade of like 0.1 a little bit less now in Jump air I want it to keep playing this animation until it hits the ground so I'm going to add another method in here that's going to be called check grounded so here's what this is going to do is if it's grounded then it's going to play a student animation so let's run through this here so I'm going to run the animation if it's grounded or in the air and that's what this one is giving you and here should we unlock the layer beforehand and here what animation do we want to play if it's grounded or in the air and here do we want to lock the layer of this next animation and then here's the Crossfade so here in the update we're going to check if grounded is in fact equal to grounded and then we're going to either lock it or unlock it and then we're going to play it so here we've got a squiggly line here because how do we know what is grounded how do we how do we know that our player is grounded so what I'm going to do is I'm going to get to our play of movement and here I've got a variable called grounded in our play of movement I'm going to remove it and put it into our animat brain instead all right so here I've added a protected grounded and a public grounded and this public grounded can only get grounded it cannot change it so let's go back here and now it accepts this so let's head back so first of all we start the jump and now we're in the A and let's add some things here so when we are grounded we want to unlock the layer and then we want to play the jump end animation and then we want to lock the layer again and then do the cross fade and I'm going to make this 0.1 again now when we end the jump I'm going to go on exit and then the animation I want to transition to is none I I want to reset it and I don't want to lock the layer and then I want to add maybe point one of cross fade and there we go you can see it does the jump animation all the way through and I can start running and it will only do the jump animation on the bottom half and if I start reloading and jump you can see it does the reload animation even though I'm in the air and there we go so we've got all our animations all sorted and of course I can make my character die any moment and there we go
Info
Channel: Small Hedge Games
Views: 1,345
Rating: undefined out of 5
Keywords: unity, unity tutorial, animator, unity animator, mesh, crossfade, unity c#
Id: Db88Bo8sZpA
Channel Id: undefined
Length: 36min 26sec (2186 seconds)
Published: Thu Mar 21 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.