REALISTIC Foot Placement Using IK in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Is there realistic ankle sprains as well?

👍︎︎ 6 👤︎︎ u/[deleted] 📅︎︎ Aug 27 2019 🗫︎ replies

That's awesome! I love that people make such detailed tutorials :) thanks for sharing

👍︎︎ 2 👤︎︎ u/Gnodima 📅︎︎ Aug 27 2019 🗫︎ replies
Captions
well that's not right that's better hello and welcome to a new quick bit episode i haven't done one of these for a while i think i've got something a bit interesting for you today you guys can let me know in the comments if i'm right about that but i think it's interesting at least so today what we're going to do is we are going to do realistic foot placement using inverse kinematics which is well i'll give you a quick overview of what we're trying to fix as you can see here i've got a little dude i got this from the asset store it's not free i will place a link to it but just be aware this usually i use free assets this is something that i bought at some point it looks cool so i just thought i'd use it for this we are using unity 29.2.1 and we're using the high definition render pipeline not for any particular reason i just thought it would look nicer for the video it's completely irrelevant to this particular tutorial which version of unity used this should all work as far back as unity 5 as far as know maybe even unity 4. the version i'm using just not really relevant to this so i've got my little dude set up here he has a rigid body on him he's got a capsule collider and he's currently standing on or in rather a sphere obviously you don't want his feet in the sphere so that's what the capsule collider will fix if i press play we'll find out that the rigid body and the capsule glide will take effect and he's now on top of the sphere however the thing we're gonna fix is this how he's just hovering above it he's got technically the capsule collider here is touching the sphere and that's all the rigid body cares about there is contact and it doesn't drop any lower because of well that because it would have to go through the sphere obviously you can mess around with the material the physics materials and make it so that it would slide off the sphere but i for the purposes of this tutorial i don't want him sliding off the sphere because it would defeat the object of what i'm trying to show you so that's what we're going to try and fix if i uh if i just well actually before i get into that i'll just show you what i've got set up so far so we have a fairly standard 3d character like i say is a cool looking 3d model but in terms of what's going on there it's it's there's nothing out of the ordinary he's got a rigid body he's got a capsule collider and i have put a script on him but all the work that we're going to do in this tutorial i will show you what i've done already is just taking a reference for an animator get the animator and then i've put a control to set the animator to walk so basically whenever you press spacebar it sets the bull in the animator to whatever the bull currently isn't so if walk is currently set to true it sets it to false and vice versa and that looks like this and i've childed the camera to the character so the camera just follows him so that's the only coding i've done before this video it's fairly straightforward stuff anybody who's been watching any of my videos should easily get the head around that the animator itself just has an idol and a walk and a parameter for walk and then the transition obviously is whenever the walk is set to true it goes into the walk and then when it's set to false it comes back to idle so that's all that's been done before this video started so the first thing we need to do is we need to adjust our capsule collider because nothing we can do with our feet is going to matter if that capsule collider is holding the feet off the top of the surface so we need a little bit of room for our feet to be able to mold to the surface because if you know if that's as low as the character can go we have to hyper extend our legs to get the feet to touch the surface and we don't want that we want to go the other way we want to have the players overall mass sit a little bit below where it would be if it was standing on the ground and then we bring the feet up to match the surface so let's go ahead and do that first go into our character we'll find the capsule collider i'll just switch to side view just so we can get a better look as you can see he's more or less in line with the sole of the feet there so we're going to bring it up to we'll say around where the edge of this green part of the trainer is and that'll do it doesn't really matter if it's perfect up here we're not doing anything with the head obviously if you're making a proper character for a real game you want to spend a bit of time getting everything just right for this all we're interested in is where the feet are so if i press play now you'll see that now his feet have sunk into the sphere because the capsule collider is higher up just come out of orthographic mode we're kind of back to where we started now but this is what we're going to fix so now we can add some code and we can make it so that the feet are raised up to match the sphere so let's uh get started with that and the first thing we want to do is go into our animator and then if we go up to layers we'll find our base layer and we're going to click on this little cog here and we want to check ik pass so ik is inverse kinematics inverse kinematics is to dumb it down a lot because let's face it i'm not smart enough to smarten things up but to dumb it down a lot basically think of it as working out the position of something from an external point animations are called forward kinematics whereas basically you have a set position like the knee needs to be moved to this position when you're walking or something and then that's what happens the transform of the knee is moved to that position inverse kinematics is you have like an external target and you're moving the knee to the external target and that external target could move so set that to ik pass and then we're done there we go back to our scene for now and then we'll open up our script again and we've got a few things to type so the first thing we want to do is we'll go to the bottom here and we need to add in a function if we go down here and we type on animator ik and visual studio has kindly auto filled all this for me we don't actually need the layer index for what we're doing but you would need that if you were using this system properly on that and that's the other thing by the way i have a tag set up for the floor called walkable and also applied to this sphere and this cube that i probably won't use i thought i was going to use it in the tutorial that's why it's there but i ended up not needing it but we'll see how it goes so what this does is this function is called on any object where an animator is running and it has ik pass enabled so basically this adds quite a bit of workload to these well it doesn't add a lot of workload but relatively speaking it adds a significant amount of workload and obviously you don't want to be adding that workload unless you're actually doing something with the inverse kinematics system so if that's set to true if this is an ik layer then this function is called i think every frame then once we're in here really you kind of want to be putting everything inside of an if statement to say if anime and then that way you don't get an error if you forget to add an animator so the first thing we're going to do is we need to set the weights so if you don't know how weights work basically when you if we just open up here you see this weight slider at the top there now that's set to one and it's not changeable on this one because this is the base layer if you added another layer you could have a weight to it so let's say for example you added a mass another layer and you put a mask that only affected the head and that maybe had the head looking around a bit but maybe the animation for the head is a bit drastic like the head's snapping backwards and forwards and it's a bit much you could change the weight of that layer to like 0.5 and then the animation would be sort of blended halfway between the snapping head motion and whatever the bass idle animation is that you've got in the bass layer so that's what your weights do so if we tell our foot to move half a unit forward but we have the weight set to 0.5 it's only going to move a quarter of a unit forward so that's the first thing we need to do is set the weights so anim set ik position weight and then we need to tell it what we want to set now this only works on humanoid animated rigs it won't work for non-humanoid or generic or whatever it's called that's just the way you haven't implemented that yet you have to implement your own system if you want to do it for non-humanoid characters so the way we tell it which part we want is we say avatar ik goal dot and then you'll see we have these options we have left foot left hand right foot right hand they're the only options you've got really there's some other stuff you can set what you're looking at as in literally what the head is looking at so you can have the character look at things and there's various weights you can set on that so you can have it so it's just the head that's looking or you can have it so that the spine sort of moves a little bit as well so the whole body turns and all that but that's for a different video it's all very easy to use once you've got your head around the ik system it's really not difficult so we are going to be dealing with the left foot to begin with we'll worry about the right foot later and then the next value we need to give it is the weight it's normalized it's between zero and one so we're gonna give it one that's full weight so whatever we try and set the position of our left foot it will be fully set that there's no blending or anything it's all or nothing and then the next one we need to do is anim dot set ik rotation weight and you shouldn't take a genius to work out what this means but basically it's the exact same thing but for the rotation of our foot so now that we've done that whatever we do with our foot now it will be fully applied it's not going to be partially applied it's not going to be blended with the animate with the bass animation or anything it's going to be fully applied so let's apply something now we're going to need a value here and this value is we're going to call well first it wants to be public so we can set it from the inspector we're going to call it float distance to ground and we're going to put a range on that now this will depend entirely on the model you are using as you'll see in a second when i go back into the unity inspector so don't take this range thing as a hard limit i'm just putting it between norton one because there's no reason it needs to be outside of that range for the model i'm using is feasible you could be using a model that is still humanoid but has a very different well i'll show you now basically we are looking at the foot the foot is in terms of the actual model if i can just get closer here and turn that silly icon off the foot in terms of the the architecture of the model the armature oh i'm i'm not entirely sure i'm using the right word there but we'll go with it in terms of the armature this is the foot so as you can see it's not actually the foot it's kind of the ankle so that's we need to take that into account as you can see the toe is actually at the bottom but the problem with that is if i rotate the toe it's only rotating the toe that's not much use to us whereas if i rotate the foot the whole foot rotates that's what we need we need the foot to move to match the terrain that it's standing on so that's why we need the feet and also the where is it ik goal left foot is gonna be looking at this and not the toe so the reason we have this distance to ground value is because we need to know how far it is from the actual foot transform to the actual ground we need to factor that in obviously if it was the toe the toe is on the sole of the foot and that is already going to be at the ground level so we wouldn't need to factor in distance to ground there but we're not using that we're using this this is around the ankle and that's i don't know probably 0.05 or something we'll figure that out in a second so that's what this distance to ground value is and we'll figure out what we need to set that as once we've got the code cell so we'll go down here we're going to create a raycast so that's the hit to store the the result of the raycast and then we create a ray it's going to equal a new ray so we need to give it as you can see here we need to give it an origin so where it starts in a direction and that's all you need you don't need a distance or anything that will be handed by the ray cast itself we just need an origin and the direction that it's going so our origin we're gonna get directly from our animator so anim dot get ik position so we this time we're getting the position out of the animator rather than setting a value and we say avatar ik goal dot left foot so we're getting the position of our left foot and that's always going to be the position that we need because that's the position from the animate so then we want to add to it vector 3 dot up so if you remember directional value all the built-in directional values are one so vector3.up is zero on the x one on the y zero on the z and then obviously vector3.4 would be zero zero one and vector three dot right would be one zero zero so the reason we're doing this is because if we start the ray from our foot position and our default character's placement is below the floor like we've stepped on an obstacle and the foot is below the floor it's going to miss the terrain and then you know we're not going to detect it so our foot's just going to stay the floor so we're starting essentially one unit above the foot and then we need to factor that in in a second when we do the ray cast and then the direction obviously is just vector three dot down we just want to go straight down we're not interested in any like if you're doing anything fancy with your character and having rotate and you're wanting him to walk around a sphere or walk up walls or anything obviously you're gonna have to get a bit more creative with this but if you're doing anything that complicated you know you're a few steps ahead of this tutorial so don't worry about it for now so then we need to do our check so we're gonna say if physics.raycast and then we pass in our ray we're passing our hit to get the results of this ray and then we want distance to ground plus one f so the plus one f gets us back down to where the foot is from this vector three to up remember we're checking that high up in case the foot's already below the ground and then the distance to ground is getting us the rest of the way from the foot position to where the ground should be we're assuming i mean you can assume different like if you want to go a bit past where the foot is that's fine like maybe your idle position i mean the idle position for this guy his leg is slightly bent i mean straight there but in the idle position his leg is slightly bent so you could go a little bit past where the ground is and then you have a little bit of room for your leg to be fully straight but that's entirely up to you that's that's a value to play with and it's going to differ from model to model so once we've done our check inside our check if it's true if we have hit something the first thing we want to do is make sure it's something that counts as ground so like i say you want to use layers in a proper system but for simplicity we're just going to use a tag so if hit.transform.tag is equal to walkable once again then we do stuff if not we don't do anything so only if we've hit something and it is walkable then we do stuff so the first thing we want to get is the position of our foot so we're going to say vector three just call it foot position equals hit dot point which if you don't know is the actual position that the raycast hit something if you were to say hit.transform.position you would get the the root position of the thing it hit so in this case if you hit the floor you'd be getting i don't know somewhere over here wherever the origin point of this floor plane that i've put in is whereas the hit point gets the exact point in world space where the raycast hit the floor now the next thing we need to do is to compensate for this distance to ground thing and i understand this is probably a little bit difficult to follow just from words we've got a foot position we've gone from there distance of ground down so whatever our distance to ground value ends up being and we've hit something so that's what's happened so far we're now using this position that we've hit to decide where to put the foot but remember we're we're placing using this transform here so that means if we put this transform where we've hit we're going to be putting the ankle at ground level and we don't want to do that so we need to work backwards for the position and remove that distance to ground again and in this case remove is add because the y value goes up so the next thing we want to do is foot position dot y plus equals distance to ground so that gets the the foot transform which in this case is at ankle height back to where the ankle needs to be relative to the ground and then the final thing we want to do is actually set so we're going to say anime dot set ik position avatar goal avatar ik goal even dot left foot and then we're just going to pass it in foot position and then the one final thing we need to do because because we are casting our if i just highlight our character again because we are casting our ray from i don't know somewhere up here it's gonna hit its own collider before it hits anything else and obviously we don't want it doing that so we need to tell it to be able to ignore that so the first thing we want to do is give our character a layer so we'll just add a new layer we'll call it player and then we'll go back in here and we'll get a public layer mask and we need to give it a name sorry layer mask and then when we go back into here first we want to do is set our player to the player layer mask and set all the children to it as well and then we want to set our public layer mask value to the player and we go down to where we put our ray cast we can at the end here stick a final parameter and we're passing our layer mask and what that does is that will ignore that layer do you know actually i don't think no that's not that doesn't ignore sorry that only affects those layers so we want what we're going to do is set this to everything and then unselect player so it's detecting everything except for the player which obviously you can change that like you can have it on you don't maybe you don't want it to detect uh water for example but anyway basically right now we just don't want it to hit the player so if we press play now we should find the foot is still in the sphere but that's because we haven't messed with this value here and if i wildly throw it to the top there there goes his leg and we've just broke his hip and everything but basically we can we can bring it back down and we can find the the right value so oh 0.05 looks close i think i guessed that at the start so we'll just tweak that by hand a bit 9.656 that was close enough so what we can do now just to show it in action so if you remember that value 0.056 and then if we grab the sphere and we do this you can see that the foot is moving i mean obviously the other foot's disappearing into the ground that's because we haven't done that for yet but this foot is moving up and that's what we wanted so we'll just reset the game we'll just uh set this value sorry not .056 it was 0.056 but we're not quite done yet if we go in a little closer and we look we can see that our foot's still doing kind of what we're trying to avoid but on a smaller scale in the there's a tiny bit of it touching the sphere and then the rest of it is hovering and we don't want that we want we want the foot to sit neatly on the surface so right now it is just it's a tangent regardless of where it is so we need some rotation in there so let's get the rotation sorted if we go back into our code we've already set the rotation weight so now we just need to add the rotation value so come down here i'm going to say anim dot set ik rotation avatar okay goal dot left foot and then for the value the way we're going to get the rotation is we're going to say quaternion dot look rotation and we're going to say transform dot forward so that's getting whatever direction our character is facing and then for the up value we're gonna pass hit dot normal so again this gets more complicated if you're gonna have your player walking on the ceiling or walking around a sphere or walking on walls or anything but for very straightforward down he's down and up is up this is fine because forward is whatever forward is your foot's not going to be facing a different way to the forward of the player unless something has gone very wrong so we just pass in those values and we try that again and now we should find that our foot actually matches the angle that we're on we'll just move that sphere there we go you can see the foot is moving nicely over the terrain there over the sphere so all that's left to do for the feet now there's a bit more to do but all that's left to do for the feet is to just copy this code for the most part we need to change it a little bit we'll change that to right foot we don't need to redeclare this we're just going to use the same one and again we don't need to redeclare that we're going to need to get our right foot values as well obviously we're just changing that to right foot and then we want to come down here and do the same thing wherever it says left foot change it to right foot and everything else is the same we've got the ev the up is the same we're doing its own independent ray cast so it's you know we don't need to change that it's going from the right foot instead of the left foot and we're setting the right foot position so now if we do it we should have both feet behaving properly and there we go beautiful and it's it's a little bit high maybe and obviously you can mess around with it more and get it to perfectly suit your model and if maybe you've got a bit of a weird model's got one leg longer than the other you can get independent values for the left foot on the right foot for the distance to ground but that's that's kind of fine detail stuff that's not very hard to work out by yourself i'm just going to get you the broad overview of it now we're not quite done because as you'll see if i set our little character walking his walk animation looks a bit weird and the reason for that is because our foot placement system is trying to work all the time now obviously we don't want our code trying to lock the feet to the floor when we're walking so we need a way of telling it not to lock our feet onto the floor when the character is walking but at the same time we do want our feet to match the ground at the bottom of each step so obviously we can't just disable the ik code when the player is walking because then we lose all that nice foot placement when the actual footsteps land so the way we're going to do that is with curves so we're going to add our animator and we're going to add a couple of parameters here a couple of floats we'll just call this ik left foot weight and then another one for the right foot okay right foot weight and then we want to go find our animations my animations are in here in this two tune kids asset folder that's the asset that this child is from and if i find the walk animation and basically you go into your import settings and you go into animation and then we want to go to curves and we want to add some curves so the first curve we're going to call it and it has to match exactly this here ik left foot weight okay left foot weight and then we click on this curve here um we want this one like this i'm not sure why it's uh it's all zoomed out there let's just see if we can get that looking correct i love unity but sometimes it's very weird in the way it behaves so we have our curve here and basically it's starting this value is going to be used to set the weight as the name suggests we're starting at one so that's full weight as i said before that means that wherever we put the foot the foot is going full on to there there's no half measures but then this curve will take it down to zero and then for a while it's zero and then it's going to come back up to one so if you imagine this is happening during a footstep but the tricky part is there's not all we need to match this up to the footsteps in the animation so as you can see we have throughout the complete animation we start off with kind of starting with a left left foot rise and then we have a right foot rise and we need to match that so if we reopen our curve this is for the left foot so we want to start that's right we want to start pretty much full weight because the left foot will be on the ground at the start and then we're going forward and about there that's actually quite yeah that's more or less right that okay so that curve's correct whereas the right foot we want it the other way around we want this big slope here to be at the start because at the start the right foot is landing and then it's down and then the left foot lands and then the right foot comes up so we need to add another curve okay right foot weight again this needs to match whatever we've called this exactly now for this curve we want it to be kind of the other way around so let's go with this one so if we just get roughly to where right so right foot wants to be one up until about there so if we go if we drag this to like that make this a bit more straight obviously this isn't perfect you can spend more time messing around with your curves if you like and then where does it go and then right foot kind of wants to just stay yeah right right foot's going to be a weird one but basically it wants to start at zero and about there i think is where it's coming so we're starting at zero as the right foot is in the air and then it lands we're at one left foot's doing its thing and then we're lifting the right foot up we're probably coming back to i think maybe that's just a little bit too soon so we'll just drag this this way a little bit you know what we don't want this part in at all that just wants to be zero so we'll just delete that key and we'll drag that to there right okay so now if we play our um oh you know what you need to do you need to apply these first never forget to click apply when you're messing around with animations so now if we press play and we set our little character walking as you can see these values are going up and down in accordance with those curves now the player still looks like he's walking a bit weird because we haven't actually implemented those numbers so let's go into the code and do that and the way we do that is basically we're here where we're just setting full weight instead of setting full weight we want to get anime dot get float and then we're just getting the in this case ik left foot uh what did i call it sorry okay left foot weight now we just copy that for the other left foot because the weight is the same for rotation like we're not we're not doing anything independent for rotation then we have a position and we'll copy them again and then just change left to right and now if we go into here and press play you can see the walking's a bit more fluid although we haven't quite got our distances set up correctly i think for the feet that's why disappearing into the ground but now we're not getting that weird slap down so i'll just have a little bit of a play with the positioning of everything try and make it look a bit more natural there we go so that was just because the height for the capsule collider wasn't exactly great but now we should find that if i come out of orthographic mode for one thing and i duplicate these spheres like myself a few more spheres and just sort of place them a little bit randomly along the path of our hero here and then i will move our camera to be looking a little bit closer to the feet and then if we press play we can watch the feet do their thing as he walks across all these random yellow bumps in the road so we just have one last thing left to do and we're all finished and that is because we are using this now to set our weight as you can see by default is zero which is fine when we're getting our weight from the animator uh from the animation whatever it is it's fine when we're getting our animation from here but idle doesn't have that so because the default is zero because idle doesn't have an animation curve set as you can see that means that it's it's going to have a weight of zero and our fancy foot placement code isn't going to take effect when we're idle so the way we get around i mean you could do a check in your code to say if we're idle set the weight to one but it'd be a lot easier to just add the curve like we did so same as before ik left foot weight and another one okay right foot weight and then this time we just want is that one one yeah and again it's it's zoomed out weird for some reason and then the same for this one and then apply them and our idle animation should now have the correct weight there we go as you can see the weights are set to one even though we're idle and then if we set off walking all good and there you have it that's how to get realistic more or more realistic foot placement in unity using inverse kinematics and obviously that's just how to set up the system you want to spend a bit more time playing with the values and fine-tuning everything for actual game and as you can see your feet are just a little bit further into the ground than i'd like but that's just a matter of changing of messing with values and everything and hopefully that is enough to get you started on having realistic foot placement hopefully this tutorial was helpful for you i will be back very soon that's it for now thanks for watching you've all been amazing i just crossed 700 subs recently which is unbelievable i don't know how that happened thank you everyone in the discord server that thing is filling up i hope you all continue to enjoy these videos as much as i enjoy making them bye
Info
Channel: b3agz
Views: 89,649
Rating: undefined out of 5
Keywords: Unity3D, Coding, C#, GameDev, IndieGameDev, MadeWithUnity, inverse kinematics, ik system, game development, unity ik, unity 3d, how to, foot placement, feet ik, foot ik placement, unity (software), c# tutorial for beginners, c# tutorial, c# programming, coding for beginners, c# projects, game dev, foot ik, unity3d tutorial, unity3d game tutorial, indie game development
Id: rGB1ipH6DrM
Channel Id: undefined
Length: 30min 9sec (1809 seconds)
Published: Mon Aug 26 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.