[#11] Unity animated character controller with root motion

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
kia ora welcome back i'm nikki ricotta in this video i'm going to show you how you can convert your character from a rigid body to a character controller so you can see here the um character can walk down steps it can walk down slopes uh it can jump and like shoot in the air i think it can also like reload in the air uh it can fall off ledges and it can also um yeah like push around uh rigid bodies like this like dynamic rigid bodies and can like jump on top of them and stuff as well okay um so this is all done using just the native uh unity's character controller um and there's various different properties that the character has that you can play with um just give you a look at them now jump height gravity step down air control jump damp ground speed and push power okay so let's get into it so this video follows on from a previous video i've made the weapon reloading using animation events in unity so in the scene i actually want to convert this character from using a rigid body and capsule collider to a character controller one of the main reasons for that is so i can walk upstairs like this um so these ones sort of seem to be okay sometimes it does get a little bit stuck at the bottom like there but larger stairs are just it can't handle and i think a character controller is much better for that um the other thing is you'll notice like if i go up this ramp the character gets like a little bit airborne at the top of it and also when i walk down these steps it sort of bounces down the steps rather than walking down them smoothly so those are the main reasons for converting to a character controller and i think you you just have much more fine grained control it'll be a little bit more work but um it'll be yeah give you a lot more flexibility i hope fingers crossed um so just a couple of things i want to point out is um in my project settings these are the physics uh settings that i'm using um so set the time step to 0.01 just to make it a little bit smoother and also one other thing i noticed is um when the character sort of if you go left and right you can see the animation sort of snapping there and it looks pretty bad so an easy fix for that is going into the input manager and turning snap off on the horizontal and vertical axes and this will just mean that the input values that are fed to the animation are now blended smoothly and the character will look much better okay so yeah with all that let's get into it so the first thing i'm going to do is uh remove the rigid body and the capsule collider and add a character controller and the height needs to be just pretty much the same values as what we had before 0.8 0.9 and 0.2 for the radius um and it actually looks okay in the scene here but when i hit play the character actually floats like a little bit off the ground you can see and that's because of this um skin width if i zero that out it falls back to the ground but you don't actually want to clear that you want to leave that in there so um a better way to do it is just change these offset values so i'm going to use make the character slightly smaller and offset it slightly higher and that just means the character's feet should be on the ground even though the the character is in the air sorry the capsule is not directly on the ground um yeah and the other thing that we need to do is just set this minimum move distance to zero i've found that um they can have some pretty weird effects on the is grounded property of the character controller um yeah cool so uh the animator is still set to update mode normal and if i hit play the you can see the character is really jerky now um and in easy fix you would think would be to just set it to animate physics uh which will mean the character controller is no longer being animated in update it gets animated in fixed update which fixes the um the locomotion part of the character except um what happens is the aiming portion of the character now the the aiming portion is not actually matching up with that dot anymore and it's kind of a tricky problem i found to solve because the animator it's now animating the character controller and running the um the animation rigging is all being controlled by this property here so we actually want to separate those two and update the character inside fixed update like we are here but then i carry on running the animation again during the normal update which will um sorry if i just turn this laser back on that will that fixes the uh the sort of alignment here of the laser to the crosshair so to do that i've come up with like sort of a hacky way to do it but it works and i'm gonna roll with it so if you open up the character locomotion script what we can do is just override on animated move and in here um i'm just going to create a new variable called root motion and what this what i'm going to do is basically accumulate the root motion of the animator by adding the delta position so this is a vector three and in the delta position of the animator that's basically the root motion of the animator every time the animator runs um so yeah i'm just going to accumulate it here and now the character won't actually move anymore if i went into play mode so i need to actually move the character inside fixed update um so to do that i need to get a reference to the um the character controller uh just i'm just going to call it like cc and just get that inside start cool and now we can just do cc.move by that root motion amount and um after we move it we just need to clear the root motion so i'm just going to set that to vector 3.0 and what this has effectively done is move the root motion from running inside the update mode normal but now we've moved just the root motion portion of the animator into fixed update so now the character controller has been moved inside fixed update but the animator which runs the animation rigging as well is happening inside update so everything um basically is still happening in the same order as when we were using the rigid body and you can see that the um the laser is now correctly aligning to the uh the crosshair and also the character is moving around smoothly um so yeah that is a workaround i've got if you've got a better idea please let me know but it seems to do for now actually i'll just go back into play mode and because we're now using a character controller um we can actually walk up the stairs um but the character doesn't fall to the grounds now and i can't jump or anything so yeah this is the next stage to fix so if you just open up the character locomotion we're going to add jumping and gravity at the same time so just create a couple of new variables one called the jump height and one called gravity so this is how high the character can jump and basically how fast the character is going to fall to the ground and we just need a couple of other variables private ones one for the velocity of the character and just a another variable to store the state that the character is in so i'm gonna split the fixed update into two paths one for when the character is in the air and one for winner is um on the ground so currently this is just handling when the character is on the ground okay so just uh create one more function called uh jump and what we're gonna do is inside update just check if input dot get key down key codes dot space and then just call that jump function and first of all we just want to check that we're not already jumping um and if we're not jumping then we can see it is jumping to true and what we'll do is just set the y velocity of the character equals to this crazy equation here which is math dot square root times gravity times jump height and the reason for this equation is basically it lets you change the gravity without affecting how high the character actually can jump and there's two times it's uh it's i think what it's doing is basically differentiating like the force due to gravity or something i think it's some kind of calculus which just kind of meshes everything to one cool um so yeah now the character um will be will jump if i press space but we're not actually using this velocity anywhere so just inside update i'm going to split this into two one for when the character is jumping um we want to basically reduce the y velocity um by that gravity amount times time dot fixed delta time and then we can just uh move the character controller uh by integrating the velocity again um time dot fixed delta time like that and finally like when we're jumping when we hit the ground we want to set this as jumping to false so we can just set it as jumping equal to cc dot is grounded and basically this variable will will store if the character was touching the ground after the last call to this function here move so it's always best to check is grounded immediately after you've you've called cc.move um and yeah so there we can see that is jump into false and for the other case when the character is grounded we're just gonna do exactly what we were doing before um so yeah now there's two piles one for when the character is in the air it's going to do all this logic and the other one is when it's on the ground it's just going to get the root motion from the animator which is uh gonna make everything look pretty smooth um so yeah if i just press play now i can show you how that looks there's still a couple of extra things to do oh i need to set the the jump height um so if i set the jump height to like three and gravity to like 20 for example well don't know what that was cool so now that the character can jump and then it lands on the ground and if i uh there's still a couple of issues like if i walk off there's nothing to say it's jumping at this point but if i do jump then it will reach all the way to the ground and yeah the character can move and everything is good except if i move forward and then jump the character just jumps like straight up into the air and you'll also notice this weird glitching that happens when the character lands and there's two things to fix here the the glitching is caused by now let me just come out of play mode the glitching when i land is caused by this root motion um it's accumulating even when the character is in the air so when the character hits the ground i'm just going to set a root motion basically just clear the root motion again set the root motion back to zero when it hits the ground um or just when it's in the air i guess yeah you could check if it's no longer jumping then clear it but i think more branches is a bit less clean um and so that will fix the glitching and the other bit is just the character jumping straight up and down as we move um i actually want to inherit the velocity that the character had when it was walking when we hit the jump key so we can do that just by reading the velocity value out of the animator and this velocity will come from the root motion inside here so now if i go into play mode oh let me just set these properties again jump height 3 gravity 20 go into play mode now and if i walk forward you can now see it's kind of easy to see if you go sideways the character inherits the velocity that it had when it um when i was walking along the ground and also that glitching when uh when the character lands is no longer happening okay cool um so the next bit is uh just making it so we can like walk down these slopes it looks a bit silly right now so just open back up the character locomotion script and what we want to do is every time the character walks takes a step forward which is what this uh root motion part is doing we also just want to step down by some amount so the character is kind of going in this path here like it's walking down some stairs and i'm just going to control how much it steps down by um by something called like step down just to create a new public float variable step down and what we can do is just add on um the vector3 dot down times by that step down amount and yeah so if i just set this property i'll just make it like the same as the step offset for the character controller so the character controller has got the step offset 0.3 i'll just make but it only steps upwards it doesn't it doesn't step down which is kind of surprising you have to implement that yourself so um the step down i'll just set to 0.3 and now this should let us just walk downstairs so if i walk up and yeah now the character correctly walks down slopes and it can also walk down these stairs as well um so that's all nice and smooth okay so the next bit is um just adding there is still an issue like if i walk off the edge here it just like drops down immediately because it's just taking a huge step down and um the character never goes into that is jumping state so the gravity never comes into effect um so what we need to do is just inside the character locomotion script if we're moving along the ground um what we want to do is just check if the character is still grounded so we can do that just using like if cc dot is grounded so if the character was this is the um let me just put some comments here this is like is grounded state and then this one is like is an air state so if the character controller is no longer grounded after we took a step we know that we've stepped off an edge so at this point we want to basically do everything that we're doing in here set is jumping to true so it becomes in air that means on the next tick it will come around to this section of the loop and gravity will be applied but before that we want to set the just reset the gravity on the y axis to uh to zero and then the final thing and here is uh just also inheriting that velocity from oh i'll do that before inheriting the velocity from the animator again so when we walk off a slope we kind of get some momentum going out and falling off the edge and that should be enough to let us walk off the edge of things now so if i just open this back up hit play oh unity is so slow sometimes yay so now the character um falls falls off the edge you notice there is like a small little kind of one frame glitch where the character steps down before it goes before it starts falling and you can actually tune this by just reducing the step down amount so it's not as noticeable there and i should still be able to walk down yeah i can still walk down these things um so you can play with that amount now one thing that you could do which i'm not going to do for this tutorial is after we step down if we're no longer grounded then you could actually step back up again and that should get rid of that small little one frame glitch uh in here but uh for now i'm just gonna leave it as is okay um so i think the next stage is just going to be adding some air control like if i go into play mode and if i jump and then hit the keys left and right um the character like can't move when it's in the air and it feels a little bit awkward um so we'll just add that now okay so we just want to add like a new property here for to control how much the character can move in the air so i'm just going to create a new public float called air control and can i create a new function here called calculate air control and what this is going to do is oops this should return a vector3 this is going to basically return the transform dot forward so the forward vector of the character times the vertical input on the keyboard so that's w and s on the keyboard and add that to the horizontal input and you can just use that using transform.write times input.x and the result of all of that i'm going to scale it by that air control value so if that's zero it'll have no effect and one last thing is i'm just going to divide this value by 100 because i prefer working in a bit larger units and the value i'm going to use for air control in here is uh 2.5 it's it seems to be a little bit subtle but not too strong um so yeah the final thing is just to integrate it into this uh the in is an air state or is jumping state um so let me just try to make this a little bit simpler to read if i extract that uh section there the gravity section and just call this displacement equals velocity times fixed delta time and we can just pass that in there so now what i'm going to do is just from that final displacement due to gravity i'm going to add on this uh calculate air control factor and one reason for doing it like this uh rather than adding another force to the velocity like the same way gravity has done is um i wanted the uh the character to move linearly throughout the year so if this um if we just have a look at this again it's it's just reading from the input values right so say let's just ignore the horizontal part let's say the character is walking forward in the air say this is one this whole equation will will return like the same value every time and then that same value will get added on to the character um every frame so it won't get faster and faster the longer you hold the the keyboard down whereas gravity the character does get faster and faster the longer it falls but i don't want that behavior for the air control just because it felt a little bit weird it would start off moving slowly in the air and then suddenly get really fast whereas just having this linear i found just it was a bit better to control in my opinion um so yeah if we just check this out now hit play and if i jump then um you can see if i start moving in the air then the character will move left and right and forwards and backwards and yeah that's uh that's the air control so now if i like move along and then jump um there is still some you can like the the motion that we inherit from the uh the root motion of the animation is now getting added on to the air control so the character actually speeds up more than uh more than the velocity ahead when it was uh walking along the ground so i just want to add an extra value in here which um called like the damping amount and we'll just damp the uh i'm gonna call it like jump damp and we'll just multiply this value by that inherited velocity um anywhere that we're using it so uh there and also there um and this just lets it's just another kind of thing to play with um so if i now set the jump damp to like something like 0.5 then because we have now air control uh then you can kind of tune it so the character is still walking about the same speed but um i've still got air control and it kind of just feels a little bit smoother you can uh you can do crazy things like set the jump damp to like three and then you won't hear it like three times the uh the motion of the the character as it's walking along but yeah this just gives you like some extra stuff to play with i'm just going to leave it at 0.5 okay for this next section i just want to um clean up these scripts a little bit so this this is a gotten a little bit kind of hairy to read so i'm just going to split this code into my update in air function and this one into a function called update on ground or something so just uh if you select all that code and then you can refactor out using quick actions and refactorings and just use extract method and i'm gonna call this update in air and then just do the same for this section here quick actions refactoring hit enter update on ground and yeah now we've got uh two two chunks of code here um and yeah and it's calling each of them from up here correctly so the next bit is just refactoring out these uh three lines of code because this stuff is happening in two places uh one is up here and one is down here the only difference being this uh y value that is set so first i'm just going to extract uh this section using introduce local and i'm going to call this like jump velocity and move that up and now i can extract all of these three lines out um using another function called like set oops extract method sit in here and it's actually figured out how to pass in that jump velocity there amazing um so now i can just call this uh set an air function from up here and just pass in this zero amount man i love c sharp the tools are so good much better than c plus plus um so update in air uh update on ground yeah that's all good oh the last thing i want to do is actually um split this bit on ground into two factors here so there's two kind of distinct things going on one is the character is stepping forward and then the character is stepping down so just gonna again like extract this as a parameter um called like step down amounts and then extract this is a parameter called whoops step forward amount and i might actually just swap those around the other way cool so the character first steps forward and then steps down which is cool so one easy thing that we can do is actually just scale the root motion by some factor which will uh let us speed up the um the character without changing the animation speed so if i just go into play mode you can kind of see if i if i walk forward the character can't get any faster than what the animation is playing right now there's no way of basically making the character kind of run or artificially run but an easy way to do that is just by scaling this uh this root motion amount um when we take a step forward so it's going to create a new property here called uh like uh on a ground speed probably yeah ground speed is probably a good word so public float ground speed and this will just be a value of like one for which will keep the default room motion um you can easily just set that value to zero if you want to cancel out all the root motion but i'll just uh i'll try with a value of like three for example and hit play just yes now you can see the characters like moving much faster um except all of the root motion and stuff is still all being combined together with everything that we've written which is pretty cool um except there is still one issue like if i jump in the middle of that the character is still jumping at like the old speed it's not inheriting that our ground speed parameter so there is one more place where we need to multiply out the ground speed and that is when we sit in air we just need to basically multiply the animator velocity by that um that oops that ground speed value here so yeah when we inherit the velocity from the the animation we just also want to multiply uh by the ground speed and now if i go into play and yeah and jump yeah the characters yeah basically uh inheriting the same velocity yeah and i just made these hills here when i was testing um just to like check that the character wasn't kind of like falling off at high speeds like going over the uh going over the hills it sticks to the ground like pretty well you can kind of see like it's not jumping up and down it did a little bit there but characters walking kind of ridiculously fast at the moment so i'm kind of fine with that so i'll just say that back to like 1.2 and the next stage is just going to be adding some like a different animation so so if i just go back into play mode and if i jump the character is like walking in the air so this is yeah like a just cosmetic thing obviously it looks stupid right now but um yeah we can fix that up now so just open up the um the animator on the main character so currently there's still only one state which is surprising um but i'm just going to add another state here called like is jumping and for this state we just need to assign an animation um i'm going to use and this one here ron ford's jump frame one so this comes from another one of my animations uh sorry another one of my uh tutorial videos and you can find that um if unity would let me drag these windows out inside animations mail animations aerial jump running jump and it's uh it's one of these so i can show you what that animation looks like it is pretty simple it is just a character kind of idling in the air and this is basically what i wanted for the jump i didn't want anything kind of elaborate because we'll blend from the uh the running state directly to the the jumping state so yeah just having something simple like this for jumping worked for me uh depends on the type of game you're making but yeah there's a few other um a few other kind of animations as well but uh so pick whatever one you like but this was my favorite so i'm gonna use that one um so the next thing to do is just create these transitions from the locomotion state to the jumping state so i'm gonna create a new animation parameter called is jumping and create a transition from the locomotion state and another transition back from there is jumping state so this one here um just deselect has exit time because this transition should not happen automatically it should only happen on a condition and i'm going to set the transition duration to 0.1 i want it to blend fairly quickly from the running state to the jumping state and the condition i'm just going to set that as jumping to true and then basically just do the reverse for going back the other way from is jumping to locomotion deselect has exit time so it doesn't happen automatically set the transition duration to one and add a condition of is jumping but this time it's going to be false cool and the last thing is actually just setting this uh this boolean parameter from the code so the place first place to do that is then they set an air function so here we can just go sorry animator dot sip bull uh is jumping and here we just said it's a true and then um so that will happen both when we jump and also when we start falling um so yeah that's good and the other place we just need to set it to false is when we land so that's obviously going to be when we're in the air um we can just sit as jumping to this value here and that is that's been read from is grounded so yeah all of that will work cool so if i go back into the scene after unity loads hit play then what has happened to my window that's weird hey now the character goes into like a really simple jump animation and i can jump with a weapon which is pretty cool and the even coolest thing is i can host my weapon mid-ear which i just reckon looks so badass looks awesome and uh i can also like shoot and stuff in the air it's pretty cool it's like all of the stuff just kind of came together didn't really have to do anything for all of that to work which i'm quite impressed about it's all uh to do with animation again i think so yeah um the final thing to do is i can't actually run into these blocks um because yeah that this sort of uh i would normally be able to push these blocks around like i can shoot them when you're using a rigid body and a capsule collider but with a character controller again you've got to program um that behavior yourself so yeah you don't really get it for free um but luckily unity has a solution for me sorry that was really lame um and i'll put a link to this page in the description um oh yeah i've been checking out videos by this guy sebastian legue uh his stuff is like amazing really highly recommends uh all his videos so massive shout out to him um yeah he's got some some pretty awesome videos definitely check out his page if you haven't seen it um so yeah the address is going to be on controller collider hit um yeah this this function here is basically what we want to copy yeah i'll put a link in the description for this page um this function here is what we want to copy and paste that into just the bottom of the character locomotion um the only thing is i forgot to paste the push power so i'll just create that quickly here public float push power push power and if i set push power to 2 and hit play now when i jump into these things yay i can like push the blocks around and stuff which is cool sweet yeah so that's it for this tutorial um if you've made it to the end again really appreciate you watching and if you want to see more videos like this uh just hit uh subscribe and if you liked the video hit like um really appreciate it if you share it with your friends and stuff there'll be more videos coming soon let me know in the description uh the comments sorry uh what kind of videos you'd like to see um got all sorts of things on my mind um yeah so uh we'll see you again soon
Info
Channel: TheKiwiCoder
Views: 25,086
Rating: undefined out of 5
Keywords: unity character controller, unity root motion, character controller, root motion, unity jumping, unity third person, unity third person character, unity animation rigging, unity walk up stairs, unity walk down slopes, unity tutorials, unity isgrounded, root motion unity, root motion controller, unity root motion controller, unity c# character controller, rpg character controller, unity3d character controller, animated character, unity animated character controller
Id: 4y4QXEPnkgY
Channel Id: undefined
Length: 33min 12sec (1992 seconds)
Published: Thu Jul 30 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.