C# Godot | Creating a Celeste Like Character Movement System

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Hey guys!

I thought you guys would like to see this tutorial so I threw it out here for you guys! We build a small movement system that allows you to dash climb and wall jump! If you guys have any questions or wanna yell and tell me im bad at coding (I know) at me hit me up!

Thanks,

Mitch

👍︎︎ 3 👤︎︎ u/finepointcgi 📅︎︎ May 24 2021 🗫︎ replies

One thing I never quite understood, is why each and every tutorial, applies delta to gravity.

It's not just this video. Most other videos do this. It's also in a book I bought.

That always confused me in the beginning, because I always thought: "Shouldn't you apply delta to everything, not just gravity?"

Then I read in the docs, that MoveAndSlide already takes delta into account. So you actually don't need it at all (when working with MoveAndSlide).

Still, every tutorial takes a huge number multiplied by delta for gravity, and smaller numbers for everything else.

I'm not complainig, I'm just curious, is there a reason behind this, or is it just something everyone does, because someone started it?

Nice video, btw.

👍︎︎ 1 👤︎︎ u/DiviBurrito 📅︎︎ May 25 2021 🗫︎ replies
Captions
hey guys this is mitch with findpoint cgi and today we're going to talk about how to create a 2d character controller much like the celeste character controller um inside of godot using c sharp so we're going to go through the process of creating your character we're going to allow you to move and then we're going to allow you to dash and then we're probably going to go through the process of creating a climbing system and a wall jumping system and um if we have time we'll go ahead and create our animated sprites and go ahead and pull down a sprite sheet and use that to create our animations and things like that so that's what i have stored for you guys today so let's go ahead and get started okay so the first thing you want to do is you want to make sure that you followed my previous tutorial on setting up godot to work with c sharp now if you want to you can go ahead and translate this tutorial over to good gd script but in this case we're going to be using the mono version of godot and doing this with c sharp so i'm going to go ahead and download this i've already got all my stuff set up but i'm just showing you that you know you need to make sure that you have the mono version of godot so the first thing we're going to do is we're going to open up godot and we're going to go ahead and name our project which is the hardest part what should we name it um we'll just call it c sharp 2d character controller go ahead and create that folder and then create an edit all right now that the project's open let's go ahead and first set up our 2d scene so that everything's kinda working properly so the first thing we're doing is we're going to click on 2dc we are going to right click add in a child node add in a tile map so now we're going to have to download our tile set so let's go out to hio and pull down a basic tileset and let's go ahead and download this platformer tile set here that's free it doesn't have all the little animations we want but that's okay we don't need all of them necessarily i think this has like running uh jumping and it looks like uh that's pretty much about it so we're not gonna have a climbing animation but i think that's okay so let's go ahead and download this and i've already paid for it so i'm just gonna go ahead and say no thanks and hit download and go ahead and save it show it in folder let's right click it extract let's extract it all right so now i've got all these different sprites so let's go ahead and pull this entire pack here and minimize drag it into godot and godot will go ahead and import it you'll see it do that here now that we have all of that let's go ahead and go to our background tiles and if we go into our tile map here and we need to give it a tile set resource let's go ahead and add in a tile set click on that and then let's go ahead and just drag in a couple of our tile sets here so let's see what we got we drag this in you can see there's our nice little tile set let's go ahead and create a new single tile and you'll see that this is way too large here so if we go ahead and we click on our little tile here you can see it says a step of 32 by 32 let's change that to 16 by 16. now let's go ahead and just select that little region right here and for collision let's do the same thing so let's just create a little box there for it we can zoom in if we'd like now let's go ahead and click on the new single tile let's select this region let's add in collision here there we go new single tile let's select this section let's add in collision here as well and that's really all we need for this little tutorial here so um actually i think we could get away with one more or two more sections here actually because we're gonna need it for whoops yeah that's my new single tile click collision click there we go so now if we go ahead and click on our tile map you'll see that we have all these different tiles here that we can use to build our little project so let's go ahead and zoom in here let's drag this over let's create one of these let's drag this down and then let's go ahead and drag this down and this over which i'm just making something up so don't don't think i'm doing anything like insanely great or anything like that i'm just literally building something basic with what i have so the idea is just to create something simple that you can use to um test your character controller with so i'm trying to create something that my character controller can kind of run around climb up throw jump around things like that maybe dash up to and things like that so that way i have some nice little peaks and valleys and things like that to mess with and so i don't fall off the edge here all right i think that'll work for this so let's go ahead and right click and add another child node let's add in a kinematic 2d basically a kinematic controller allows you to collide with other objects but allows you to really control exactly how your character is going to collide so they can't directly interact with other physics objects however you can code it so that it does interact with physics objects whereas they do have a dynamic character controller which is more of an automated process but you don't have as much control over the movements of the character controller so in this case i'm going to go with the kinematic a lot of people go with kinematics because it's just simpler to code and simpler to deal with from here we're gonna go ahead and right click add in a collision shape 2d and we're going to go ahead and set that shape to be a rectangular shape so now that we got our collision shape we're going to right click add any child node and type in a i m to get animated sprite we're going to drag that under the kinematic body we are going to make sure that we come over here and we add some frames to it because without frames it's not going to be able to animate at all so we're going to click on this we're going to do a new sprite frames we're going to go ahead and click on those sprite frames here and you'll see that we have ourselves basically an animation panel here so i'm going to come up here and i'm going to click on this little add frames from a sprite sheet if you click on this if you have individual frames that you want to use you can click add texture but in this case we want to click add frames from sprite sheet so let's click on that and then let's go to our platform metrovania and our hero chart sprite and let's find our animated idol so let's see if we can find that real quick and i am struggling to find it so i'll click on this little item as a list and we should see it right here idle animation strip there we go so now if we zoom in a little bit providing it lets me i don't think it's gonna let me so let's go ahead and say horizontal is one i'm sorry horizontal is four vertical is one and we're going to go ahead and select all four of these frames we're going to add all four frames and you'll see here if we zoom in here and pan with our middle mouse button you'll see that we got a little guy that if we say play is on and we click on this there we go he's animating now you'll notice that our graphics are really muddy you notice that like look at how blurry all this is well the reason why that is is because we need to reimport it with pixel art enabled right so it doesn't compress our pixel or our uh images so if we come over here we select all of these and we go over to import up here and you come down here and you change the compressed mode to uncompressed or to make it easy for you if you come up here and you just say preset 2d pixel and then re-import it it'll automatically take care of it for you see how it's much better so if we come up here to our background tiles we do the same thing preset 2d pixel reimport you'll notice that our art suddenly just got way better see that so what we're going to do is we'll come back over to our scene we'll go grab our kinematic 2d body providing that it lets me let's turn on our children objects not selectable there we are and we'll just put it right here and we're going to change our collision shape to kind of match our little guy so let's change our collision shape down like that there we go and now what we're gonna do is we're gonna add some code to this to make it so that we can actually start using this as a project so let's right click on our kinematic and attach a script now if you've walked through my previous tutorial which is setting up godot to work with c sharp all this should be set up for you so if you click on attach script and you change it to c sharp and you call it player controller and you create it it should open up your preferred coding editor which in this case is opening up visual studio i actually wanted visual studio code but that's okay um that's not the end of the world we'll just close that and we'll go to our editor settings and change that real quick by scrolling down to the bottom clicking on editor and changing this to vs code instead of visual studio so go ahead and click close and then let's click on the little script icon there there we go much better all right so let me scale this to fit your guys's screen here awesome so first thing we're going to do is we're going to uncomment this so select it control line and that'll toggle the line comment and then we'll need to format this later but i'll just tab it in for now all right now the first thing that we need to do is we need to process our movement right we need to allow our character to move and run and move left and right right so the first thing that we got to do here is we need to say hey if you get input dot is action just pressed and then quote ui we'll say underscore left and we'll open that up and we will say above here because we need to create a velocity so we'll say um vector 2 velocity is equal to a new vector 2 and then we will go ahead and say velocity dot x plus equals 50 and then we'll say hey if you get input dot is action just pressed ui underscore right then i want velocity dot x minus equals 50. oops not 59 50. and then we need to call a very specific method to allow our character to move it's called move and slide so move and slide this velocity whoops not vector 2 velocity comma vector 2 dot up because we need to tell it which direction is up or else the system doesn't know which direction is considered up so you x-axis could be this way or it could be this way you don't know right so it could be this way or this way we wouldn't know so now that we have that what we can do is we can save this go over to our run and you'll see it says hey we can't run and debug this let's go ahead and create a launch.json and let's pick a c-sharp godot now if you don't have this it's because you don't have the c-sharp godot plug-in for visual studio code and you go ahead and just download that over here in these little boxes here just click on and then search for it download it so go ahead and click on that and it automatically creates it so now let's say play an editor and play and you'll see oh i see i didn't define a main scene so let's go ahead and cancel ctrl s save this as our player test scene save it and then if we hit play select and we just select that one for now it'll go ahead and build and it'll try to play now if we hit left and right on our um keyboard the actual arrow keys you'll see that the character moves which is great so that's good news but that's not going to work for an actual game right so we need to go back to our character controller and we need to look at what's going on so is action just pressed what about just is action pressed right just pressed means did they just press it but is action pressed actually means are they pressing it currently right so if you do that you'll notice look at that the character runs but something else is funky if you notice in the bottom right hand corner i have these little these fine little arrows here you'll notice that when i hit left the character goes right when i hit right the character goes left right so that's wrong so let's go ahead and flip back to our character controller and flip these little icons or these little operators here and now you'll see that it does work the way you'd expect it to awesome so that's good we're getting there right but you'll notice that the character doesn't fall so if i run them all the way across to the edge nothing happens well in kinematic 2d systems you need to create the gravity yourself so let's go ahead and close that and let's come over to our character controller and add in some gravity here so let's say velocity dot y right plus equals whatever our gravity is going to be so in this case let's make gravity i don't know 500 and usually you want to pick a number that makes good sense so something like 4 000 or 500 or whatever you're trying to make a feeling of the scale of your world so it's a thing that you're gonna have to fine tune as you go and we're gonna multiply that by delta so what does that do well you're multiplying it by the by delta which means it's being multiplied by time by the frame rate of your actual application so that way it all has something to go off of right so when you're using delta in your process you're saying hey this gets called every single frame and the system is going to calculate all this information within that frame and your character is going to fall at a consistent speed if that makes sense so you're not sitting here going oh my character's falling at um 500 uh units a frame versus two units of frame depending on which machine i'm on so that's why you multiply it by delta is it so that you're keeping track of the time between each frame so that's way it's consistent for every single computer and it's also consistent between all of the things that's going on on your scene so if your frame rates for some reason dips to 20 it's gonna feel the same as if you have 200 frames so let's go ahead and save this and if we just click this little refresh it'll actually reopen the godot game window and you'll see that our character now runs and now falls you can see that that fall is not fast enough so we'll change this to something like 4 000 and we'll refresh it and see if that's better i mean that's probably way too fast it probably needs to be something like 2 000 let's just see what it's like oh that's actually pretty good that feels pretty okay so that's that's pretty good awesome so now we've got our running we've got our falling that's awesome but the first thing that i want to do is i want to make it so that i actually can see my character so let's go ahead and right click that kinematic 2d and create add a child node and type camera and let's add a camera 2d so what that's going to do is it's going to drag our character along with our drag our camera i guess along with our characters so you can see how i put it underneath the kinematic 2d so that way when the character moves it's going to move the camera with it now i need to center my camera so let's go ahead and grab my camera and uncheck our actually if i select this and i uncheck this i select our camera and i drag our camera to focus in on that player character and we're going to want to zoom that in a little bit so let's do like a .2 maybe ah that's probably too much 0.4 and a 0.4 and that's going to allow us to have a nice tight camera focus so you can see nothing happened right now why is that that's because we did not set it as our current camera see that so now if i click on current you'll see that it now is our current camera see perfect now this the speed that the character is moving is probably a little bit too uh too slow everything's probably a little bit too slow but that's okay we can we could finagle that later but something that we really should do is we really should allow our character to um have all those variables at the top of our class and what i mean by that is you can see how this is just says 50 and this says 4000 right but if i actually wanted the character controller to be easily changeable we want to put some variables up here so let's go ahead and type in private and say private int speed and let's say private int gravity and what that's going to do is that's going to allow us to say private int speed is equal to something like let's say 1200 right and private into gravity is equal to 4 000. we said we liked four thousand so let's stick with that and let's say speed speed and then gravity so what that's gonna do is now if we change it up here it's gonna change it in all of these places down here it just makes things way easier for us to work with so if we click run you'll see that when we start playing with it which this might be way too fast yeah it's a little too fast but that's okay um you'll see that uh it's now way faster than what it what it was so let's make it something like i don't know 600 maybe and let's save that run it real quick but you'll see that i can quickly make that change and it doesn't affect or makes everything so much easier but now that we've got this we need to be able to jump because right now it kind of sucks we're just falling and not doing anything so let's go ahead and create a jump in here so let's say hey you know if input dot whoops input dot is action just pressed because if you remember we press it once right we don't want them to be able to hold down the the space key and just jump infinitely right so is action just pressed jump open brace enter and we're going to say velocity not vector 2 velocity dot y minus equals and let's say minus equals i don't know our gravity is 1400 so let's say i don't know 2 000. and now if we save this and it's going to go ahead and compile oh we had a build failure so you'll see that it's mad at us because we are missing some curly or some parentheses right here so let's go ahead and add those in it's my fault all right usually is let's hit play let's see if she plays awesome so if i hit space nothing happens why is that right well if we look at our console here you'll see it says well hold on a minute there's no there's no input action jump so let's close that oh i think i just closed godot actually yep i just closed godot so if we come up here go to our project project settings and we go to input map and we type in jump and we go ahead and add that because you can see if we scroll down here none of these say jump right so we'll go ahead and add that and we'll hit the little plus icon key we'll hit the space bar to say that that's our jump key go ahead and close that and now if we play it you'll see if i hit space the character can now jump which is cool see jump yay the only downside is if i just keep hammering w well the character can effectively jump forever right you see that so that's not great so let's go ahead and go back here and let's see why well we're just saying hey if this action is pressed go ahead and jump right and we're just saying go ahead and go up 2 000 um force units right well this isn't gonna work for our actual jump right we don't want that we want it so that the jump only happens when you're on the floor so if we hit if is on floor like this and we do this now when we play this we hit play and editor again you'll see that when we hit the spacebar only happens when we are on the ground so if i press this as many times as i want and it only happens when he's on the ground so now that we have that let's see if there's a way that we can make some friction and acceleration and what i mean by that is you don't want your character to just kinda walk around because if your character has perfect precision movement that's not realistic that doesn't feel good it just feels like you're controlling a computer character right somebody that's just perfect but that's not the case right that's not how um a lot of games do things everything in the world has friction everything in the world has acceleration so let's go ahead and add in some friction acceleration variables so let's say private int friction is equal to and let's say point zero or point one we'll say point one for now and we'll actually do it as a float because it needs to be a float to be a point value and then private float uh acceleration is equal to about i don't know 0.25 f and actually i don't really need those zero it's fine all right so now what this means is the character is going to try to accelerate by .25 speed units per delta and same thing with the friction if you slow down it's based off of those zero one or a point one friction units so we're gonna need some refactoring here because we wanna be doing what's called lerping and lerping allows us to linearly move between two different values so what we're going to do is we'll say okay let's make a direct uh direction so let's go let's create a direction variable so let's go int direction is equal to zero and then we'll say left is direction one plus equals one and then we'll say right is direction minus equals one and we'll go ahead and get rid of our two velocities here we don't need them anymore and then we'll say okay so now that we've got this let's say hey if your direction does not equal zero right and i keep forgetting i'm not doing gd script anymore i'm doing c sharps i gotta translate that in my mind here um velocity dot x is equal to lerp all right is equal to math f dot lerp open parentheses and it's going to say hey what do you want us to learn between so you can see here this little uh syntax here tells us this little pop-up here tells us what it's trying to do so it's going to linearly interpolate between two values by a normalized value so float from to float to float weight so what does that mean well what we're going to do is we're going to say hey we want to float from our velocity dot x comma and then we want to go to our speed so der times speed comma and then we want to say by how much so do it by our acceleration and now we're going to say hey if they don't um press a button we want you to do velocity dot x is equal to math f dot lerp open parenthesis velocity dot x comma 0 comma friction and what that's going to do is it's going to give our character some feel like some um weighty feel to it so if we hit control s we save and we come over well if we just click on uh play an editor here you'll see when we press our arrow keys our character will have more feeling to it so if we open up our character controller and uh click on the arrow key you'll see how they speed up and slow down and there's just a little bit of a of a less jittery feel to it but you notice that it's backwards again because i like putting everything backwards for some reason so it's minus and plus and if we want to give it more feeling we can actually just say hey we want our acceleration to be point zero five and our friction to be point zero one and you can actually make it so they accelerate slower or decelerate slower in this case i'm doing both but it's just to show you the i guess to show you the point right you can see how they're slowly catching up to speed see that and slowly decelerating so that's basically what this is for is it's to linearly accelerate your character now in this case i want it to to stay where it's at and we can up and down our speed as much as we want so you know you can do some math here and do some adjustments and just get it to how you want it to feel because sometimes people like to do um different lerp types you can actually do like angle lerping and and do different uh algorithms and different uh curves to basically interpolate how you want your character to run but in this case i'm just gonna do a linear interpolation it's just a little easier um but you guys can do whatever you would like all right so now that we have a very basic character controller let's go ahead and add in some cool stuff just to make it more interesting so the first thing that we're going to attempt to do is create dashing so let's go ahead and come up here and let's add in some dashing let's come down here and say input dot is action pressed ui quote ui left then i want to go ahead and set my velocity dot x equals to i don't know let's say something like something crazy like uh 500 and let's say if well we'll go ahead and yeah we'll say if input dot is action pressed ui under our ui underscore right then we're going to say velocity dot x is equal to minus 500 so you can see again we're we're dealing with all these little numbers here that we don't like so let's pull these out right you can see how i'm doing this again so let's let's change this to dash speed because i got a habit of making code that isn't uh good and let's say jump jump height there we go we come up here we'll just say private int jump height is equal to [Music] i forgot what i said it to but let's just say 300 for now private int dash speed is equal to 500 now when i choose to do my dash speed it'll actually you know work but we don't want them to do it all the time you can see that we'll see how we're doing up here the same thing that we're doing here so we don't want it to do it all the time so what we want to do is we want to say hey if input dot is action just pressed then i uh is action just pressed and the action is dash then i want to allow for this little bit of code here so let's tab that in let's control s and then let's go back to our godot engine and go to our project settings and come into our input map and type dash add and then let's say our dash key is shift awesome so now if we hit play we run over like this we hit shift notice that well not much is going on here right i mean you can tell it's doing something but it doesn't seem like it's doing much so so we need to do is we need to take a look at our player controller here and i'm wondering first did i do it backwards again no yes i did because i'm dumb so let's switch those two and let's up our dash speed to something like well actually let's lower our running speed from 600 to 200 so that way we can see what's going on so you can see that it's not making a huge difference so let's make it a little bit more ridiculous so dash speed of i don't know a thousand let's double the distance that it is that's kind of what we wanted oops made it full screen but we don't really want the character to be able to um move and dash at the same time because it's going to interfere almost with the dash so what we need to do is we need to stop the user from being able to move their character when they're choosing to dash so we need to do is we need to wrap this whoops in a if is dashing then you are not going to be allowed to do any of this so we'll say oops tab tab if is not dashing don't do any of this right so we can say dash come up here is dashing is equal to true and i know that it like we haven't declared the variable yet but i'm gonna declare it about two seconds private bull is dashing is equal to false by default so now if we choose to dash it won't allow us to run around anymore but it looks like i made a mistake somewhere velocity is not defined so at this point i don't like having my velocity here so let's just drag this up to here there's no need to not have it up here so let's just go ahead and save that up there it's just better to have it as a private variable so that everyone can access it equally so we're not playing this game of oh it's in our scope or out of scope so now if we dash you'll see i can't move anymore so but you'll notice that i did my entire dash like that like what was expected so let's come over here and we'll need to make a dash timer okay so let's create a dash timer here and let's say our dash timer is equal to [Music] i don't know something like point two float and then we're gonna need to have a reset so let's do that as well all right so what that's gonna do is that's going to allow us to dash and lock everyone out until that timer's done so we're going to come down here and we're going to say is dashing is equal to true is dashing is equal to true which is great and then we'll say dash timer is equal to dash timer reset because we're going to need to reset that timer first and foremost and now what we're going to need to do is we're going to need to create kind of like some reset logic almost so we'll come over here and we'll say if is dashing i want to calculate our dashing timer so dash timer minus equals delta and if our dash timer is less than or equal to zero then i'll say is dashing is equal to false so i'm gonna go ahead and hit play in editor and we'll open it up and we will run and we'll hit shift and you'll see he dashes and now i can move but we don't want but we don't want the user to be able to fall like that right when they're dashing they should be able to dash and float in air almost so what we're going to do is we're going to look at where our gravity is being calculated which in this case is right here right well we don't want them to be able to calculate gravity while they're dashing so we'll say else now we know that they are in fact dashing right if it is dashing then they can do this right um else we'll throw this gravity delta in here and now their character when we hit play their character is going to be able to dash but not be able to um have gravity so if i hit shift oh let's see what did i do wrong but you'll notice that when we when we move our character our dash almost makes our character slide around too fast it's because we're not resetting our velocity so we need to do is we need to come in here and say velocity is equal to vector 2 zero comma zero and that will tell us to reset our velocity and we need to do a new vector two again c sharp versus good gd script is they're very much different between the two so now if i play this you'll see that it almost stops if you saw that for that split second i probably should make a little bit more uh runway here for my character to move around but um you at least can see you know if i move over here and i dash you see how it stops after you dash so that's perfect that's exactly what we want now we uh may or may not want the dash speed to be a thousand i put it at a thousand just for fun so let's put it down to like 500 um just to kind of make it a little easier to control now that we have that working what we need to do is we need to set up our other dash types if you remember celeste it allows you to dash up it allows you to dash diagonally and it lets you dash left and right so let's go ahead and copy and paste this and then i'll paste it one more time and we'll just get rid of that one because we don't need to dash down you can just fall right so we'll say ui up in this case and ui right and and ui up so we'll grab this paste and we'll do the same thing and and ui up now that we have this let's go ahead and set our y to minus dash speed and then we'll set our vector x actually we could probably just copy this so let's do this paste and paste and that should pretty much handle all of our dashing so if i go ahead and i run this you can see now we can dash up and we can now dash diagonally see perfect that's exactly what we wanted right but you'll see that now the player can dash as much as they want see which is not okay in celeste you can only dash once you've hit the ground so we need to stop them from dashing so since we don't want them to dash without hitting the floor at least once let's scroll up to the top and let's add a new boolean here we need to tell them that we can't dash without being on the floor right so is dash available and i think i spelled available wrong actually hold on let me double check because i i can't spell to save my life fail available i don't know let me go ahead and just double check that spelling yeah i can't spell available okay is dash available is equal to true by default you can dash by default right so now if we scroll down here and we say if action just pressed if dash available then you can go ahead and do this little bit here right so we'll scroll all this up and do that so now we're saying hey if you can dash then go ahead and allow you to dash but now we got to come down here and we need to find our if on floor section here right you can see here if the action jump and if you're on the floor well let's go ahead and just flip flop this here so if you're on the floor right and then if you press jump then you do that right and then now while we're here we can also say is dash available is equal to true so now that will allow you to dash or that will reset your dash if you're on the floor if you had it the other way around you'd have to push space and then your dash would become available because you were on the floor if that makes sense your operator would be the opposite of what you would expect so if we come over here and we say hey is dash available is equal to false now when we run this you'll see that when we dash we can only dash one time until we hit the ground so let's come over here and then if we jump oops click on it jump if we dash you'll see that we can't dash multiple times you can see i'm just hitting up and shift and it's only doing it the one time which is perfect because that means that we can't dash multiple times so that's perfect and if you're having problems with your gravity uh pulling your character down too much go ahead and take a look at like go ahead and take a look at your your jump strength and there we go now the character can jump better well in this case he can jump too too well um but go ahead and play with your values and you'll be able to get yourself a pretty cool little character here so now that we've got uh dashing working we need to go ahead and get our wall jumping to start working so what we're going to do is we'll come down here by our jumping area code and we're going to say hey if input dot so now we got dashing working what we're going to need to do is we're going to need to get our wall jumping to work so with wall jumping what we need to do is we need to detect which wall we're on and we need to detect which side it's on so that way we can kind of bounce off of that wall so if you think about it you got to take a character and have them jump and bounce off of the wall and then off of the wall right so we need to add some things to our kinematic 2d which in this case i'm going to rename the player anyway just it's just better to have it named as player if we right click and we click add child node and do recast 2d and we rotate our raycast 2d uh 90 90 degrees like this and then we duplicate it and we rotate it negative 90 degrees you'll see that we got ones pointing to the right and to the left so we'll call this raycast right and raycast left all right now let's go ahead and select both of them and enable them so that they are on and then we're going to go ahead and make them a little bit smaller so we'll look at our cast 2 and do it at i don't know about 10. i think 10 should be okay so what this is going to do is it's going to give us the ability to raycast to the left and raycast to the right to allow us to jump off of those surfaces so we're going to go ahead and save and we are going to open up our vs code here and we're going to say hey if input is action just pressed quote or parentheses quote jump because we want to make sure if they're jumping and and we're going to need to make sure that our raycast is colliding so we need to get node and we're going to need to say left raycast i'm pretty sure that's what i called it but let me double check real quick let me just drag that over a tiny bit raycast to the left all right but you'll notice something it says uh hey um this is not a boolean right so we need to have the is colliding right so dot is colliding except for you'll notice it doesn't come up and the reason why is because c sharp is a statically typed language so you can't do that you need to actually cast this as a raycast object so if you come into your get node and you do a open arrow and say that this is a raycast 2d now what you're doing is you're saying hey get this node it is a raid cast 2d here's the name of that node now when you hit dot is colliding it will actually come up so that's how you solve one of the big major issues with c sharp inside of godot is you got to make sure you cast your rake or will cast all of your nodes when you get them because they come back as generic objects because godot doesn't know what you're trying to um get it just assumes that you're just getting a thing it doesn't know what it is you have to explicitly tell it what it is i know that's a little bit weird coming from unity um you know i used to work in unity professionally for for years and this is one of the weird things that has taken me some time to get used to so now that we have that what we can do is we can say velocity dot y is equal to minus jump height and then velocity x is equal to jump height so what that should do is it should allow us to jump off of a wall and then launch ourselves away from that wall so now if we do else if in this case i'm going to do elsa if you could just do if you'd like but generally speaking this is useful if you're between two things that are really close to each other that way you're not picking both at the same time you're just picking one and we will do the exact same thing this paste raycast right is colliding and we will say velocity well actually i could literally just copy this can't i so let's just copy this now let's just go ahead and paste it and let's do minus so now if i go ahead and i play this you'll see it's going to pop up in a few seconds right here if i play this and i run down here and i hit spacebar you see that i jump off my wall which is great i mean i've got quite the heck of a jump here but that's because my jump height is probably too big so if we come up here let me go ahead and adjust a few of these things let's make this a hundred and then let's see what happens if we make the gravity uh 400 let's make the jump height a hundred let's see if that'll help a little bit i'm not a huge fan of how this is operating right off hand so i'm just kind of messing around with it and seeing if i can get a good result because i'm not happy with the way that this is right now so if i come over here and i jump it's a little bit better yeah that's more of what i would expect so you can see him jump away now you'll notice so you'll notice some things if i hit spacebar nothing seems to happen but sometimes it does happen i don't know if you guys have noticed that when i was messing around with it and you'll also notice that if we wall jump we can basically just wall jump up a wall so let's go ahead and investigate these two issues and let's uh you know let's go ahead and fix them so the first one if you notice when we're on the floor and we do our jumper minus equals right so we're just taking whatever our current velocity is and we're adding i guess you could say adding to the height a little bit but actually what we want to do is we want to make it equal to minus jump height that would make it more consistent and not dependent on your um delta time because if you look at this when we scroll down there's a section here or we're doing gravity right plus equals gravity times delta so there were times where this was getting messed up because we were minus equaling up there so now if we go ahead and hit play and we run this and we click space or hit space you'll see that it's consistent every single time so that was a mistake on my part but that's how you solve it now let's take a look as to why we can wall jump up walls like that right but what we need to do is we need to time our wall jumps and what do i mean by that well basically when you're wall ju jumping you can't allow uh people to do any kind of movement right so what we're gonna do is we'll say hey if this stuff then we want to um create a variable here that says hey you can't move so we'll come up here and we'll say private bool is wall jumping and we're going to equal that to false right off hand and if you remember much like how we did our dash stuff up here we're going to do the exact same thing down here so we're going to call it wall jump timer and then we're going to say wall jump timer reset right here so you'll put it like that and then you'll see if we scroll down here and we wrap this saying hey if we're not dashing and we're not wall jumping then we're going to allow them to move and now when we come down here we can say wall jumping is equal to true and then we can do the same thing here all right now that we have this let's go ahead and scroll down a little bit and we need to do our wall jump timer here right same thing like we did with this the exact same thing so if well or if uh dashing so if and actually we could probably just put it up here if is wall jumping then i need you to do a wall jump timer minus equals delta and we need to say if our wall jump timer is less than or equal to zero then we need to say is wall jumping is equal to false and that should about do it for us all right and if we wanted to we could also do this little vector 2 if we feel like um creating kind of a buffer area but what this is going to do is it's going to force the player to not be able to interact with their character while they're wall jumping now the reason why it's useful is because now when i well in this case it's not long enough so let's go and take a look at our length here so if we scroll up to our wall jump timer and let's set it to something like one second and our reset is to one second as well let's refresh here and let's try that again we'll come over here we'll jump and you can see in this case one second is well maybe not oh i know what's going on well we could probably just set it here wall jump timer z go to wall jump timer reset there we are and what that's going to do is it's just going to say hey um let's reset our timer we'll scroll up and let's change this to like 0.5 actually let's set it to 1.5 because i got a feeling that it's going to need to be 1.5 um and then we will test it right here so if i jump wall jump you can see that i can still do it so it looks like 1.5 is not a good number so let's try let's try 0.4 because we want to have a nice feeling um system here so let's yeah that's pretty good but i think you could still gain it looks like you could still gain height i'm not sure if i like that okay so we'll stick with 0.45 i guess we'll split the difference call it a day okay all right so this process is getting way too big so let's go ahead and uh refactor this a tiny bit because this is getting awful so let's come over here let's grab all of this let's cut this out so ctrl x and then say uh process well we'll do lowercase p process movement all right and what we're going to do is we're just going to create a function down here called private void process movement and we'll take in a i believe it's an integer delta and we'll paste in that code and that's just going to allow us to to have a nice little uh oh it's a float not an integer float delta and we'll pass in our delta here and the reason why i'm refactoring is because it's honestly getting too much so now let's take this and extract this out as well so we'll extract this out to private void process process wall jump and we'll say float delta as well i don't think i need delta to be in here at all actually i don't think delta oh this one delta does need it but i know that a lot of these i have stuff where it's just processing delta but i just want to pass it in just in case it needs it because i'm not going to mess with it too much and i believe here was where i was doing it so process wall jump delta all right and we'll do the same thing here with process dash and we'll pass in delta we're going to scroll down minimize uh this one and we'll enter tab process dash we'll pass in a float whoops delta and we're going to open that up and throw that in there so now at least we got this stuff a little bit more organized see what i mean see how much nicer that is because now we don't have to worry about dealing with all of that in our main code we could just kind of pull it out and we'll call this well i guess we'll keep this for right now because i'm not sure of an easier way to handle this all right so after that little bit of refactoring what do we have left well we have the ability to climb in celeste you're able to climb up walls only for a temporary period of time though and you can't climb unless you get reset and hit the floor right so how do we do that well it's pretty simple what we're gonna do is we're going to first have a boolean let's say can climb all right and we're going to say hey if you're on the floor you can climb right because in celeste when you land on flat surfaces you are allowed to climb and now we need to get our climb information going so if we say if can climb then i want you to process our climb so we'll say process in this case i'm actually going to do it properly i was just going to run everything in this this little process area but i think it's just best for me to refactor it right off the bat process climb and let's take in low delta just in case we need it all right so what we're going to say is if is action pressed input dot intersection pressed climb let's say climb then i want you to do this code here what we're going to do is we're going to say hey if can climb right we want to say if you can climb then i want you to check if they are pressing is action pressed if they're pressing ui up then i want you to say velocity dot y is equal to something right well just like everything else let's climb up to the top and type private int climb speed is equal to we'll say a hundred f that seems like a fair number and actually this is an integer so i don't need that so we'll say 100f and we'll say climb speed all right so now it's really easy to change it just like all of our other stuff what i'm going to also say is well i don't want them to be able to do both right we don't want you to be able to press up and down at the same time right so we're going to say else if input dot is action pressed you i underscore down then i want you to say velocity dot y is equal to minus actually i think i have these backwards hold on yeah they're backwards minus climb speed and climb speed there we go and finally well if they're doing nothing if they're just grabbing the wall we don't want them to go anywhere right so we can say if or else i should say velocity dot x is equal to new vector 2 0 0 and what that's going to do is it's going to just stationar station make them hit the wall and stop and be stationary and actually we don't want x we just want velocity awesome so what that's going to do is if we go ahead and run this but actually before we do that what we need to do is we need to come up here to our project project settings and go action client we need to add that because if we don't have the ability to climb it's not going to do anything and we'll say hey let's make that the c key and now we hit close and we refresh this we can run around we can jump and if we hold c our character just kind of locks in the air and they can run up and down so that's good that means it's doing what it's supposed to do you know if we were to like go up against the wall and then do this it would totally work right kind of weird they can you know go up forever but that's okay so what do we need to to do here right well what we need to do is we need to add some more raycasting to our projects we can determine where um basically where the player is so what we'll do is we'll duplicate these two and we're gonna pull these down a little bit so let's grab our y position and move these down to like the bottom of our character so that way we can determine yeah hey they're grabbing onto something we'll call these raycast left climb and raycast right climb because we don't want them to be able to climb whoops we don't want them to be able to climb unless they are actually up against a wall right so let's go ahead and open up our player controller and let's say hey if action pressed climb and if well actually i don't think we need to do an if actually we already have our wall jump code here so and and let's see and and this and and this actually or this and we'll throw these in braces like that and that'll just say if any of this happens if the if you are press the client button and either this hits or this hits right then we're good to go but we also need to say hey if raycast left climb or raycast right climb also hits so let's grab all of this control c and i'm gonna go ahead and just go um or or space enter paste so that way it just has that and we'll add climb and we will grab this paste it change this to right and change this to right so now in theory this should [Music] work in theory let's go ahead and try it it's a lot of theory for me let's see what happens so if i hit jump and i hit c nothing happens but if i come over here and i hit c now suddenly i can grab see but you'll notice that i'm being affected by gravity still so it's almost like i'm sliding i can also climb up and then once i get past a specific height the game won't let me climb which is good but again you'll see that i'm i'm still affected by gravity right which isn't great so let's go ahead and make some adjustments here so let's come over here and look at our gravity settings here we don't want gravity to happen if the person's climbing right we don't want them to be able to be affected by gravity so what we need to do is we need to say hey if you can climb and you pressed all of this stuff right and if you actually are climbing then we'll go ahead and set our we'll also go ahead and set a boolean here right so we can just say if you know like else if um can climb right oh we already have can climb so elsif is climbing right and we want to say hey if they're not climbing right well we got to come up here let's go ahead and add that i already have is climbing did i already add that well go ahead and add this bullion if it doesn't exist i must have left it in here by accident when i was messing around with something um let's go with is climbing instead of if climbing um is climbing and then we can say hey if you can climb we're going to go ahead and assume that you are climbing at this point right so is climbing is equal to true and if you can't climb else is climbing is equal to false and we're probably going to need to do the same thing and we'll go ahead and put a little parenthesis there we're probably going to do the same thing over here else is climbing is equal to false as well so what that's going to do is that's going to force the player to not be able to fall uh or it's going to force our gravity system to not run when a person's climbing so let's go ahead and try it let's see what it does so we hit and see that now we don't actually uh ball which is perfect it's exactly what we wanted and if we can now you can see that it's not actually grabbing here because the ray cast is so short and we can adjust our ray cast to allow our character to have a smaller ray cast or a longer ray cast or something like that now we do need to um potentially allow our character to jump away from our climb you can see how they're not actually you know moving away you have to press it multiple times for them to be able to move away from their uh climb so if we go ahead and take a look at that you can see hey if actions pressed climb do all this stuff if can climb blah blah blah none of that stuff is going on but what you can also say is and and is dashing or and and is not dashing there let's see if that does good for us let's see what that does or actually i think i was doing wall jumping wasn't i not dashing i'm sorry do i have something for wall jumping uh i do is well jumping all right so let's come down here and let's do our and and is his wall jumping so now if i refresh this it should in theory allow us to grab and then you can see here now that we're wall jumping we can wall jump while climbing so we can actually catch and uh wall jump which is perfect that's exactly what we want awesome so the last thing that we need to worry about for this little celeste controller at this point is uh when the um character is climbing and i'll actually first let's go ahead and format this so hit uh ctrl shift p whoops hit uh control shift p and hit format document and just format all of your code let it actually look good and then let's go ahead and close these because we're not looking at these right now all right so now that we have our climbing working let's go ahead and take a look at our let's go ahead and take a look at this and say hey um yeah let's go ahead and go here and let's say else if can clun or uh is climbing right and we're gonna say hey if you are in fact climbing then i need to um i guess technically i could just throw this as an else can't i so let's go ahead and do that let's let's make this a bit more efficient here else you must be climbing right at this point they're not dashing they're not they are climbing right so now we need to uh time their amount of climbing right so and i'm sorry i know that this tutorial is probably all over the place but this uh little thing is kind of a lot here so um let's go with climb do i have a climb timer i do not so let's climb up here and let's look what we have all right so i'll say private float climb timer is equal to um trying to think of a good time we'll say five seconds so you're allowed five seconds and then we'll say private float climb reset is equal to five seconds we'll scroll down here and we'll say hey climb timer minus equals delta and we'll say if climb timer is less than or equal to zero then i want to [Music] is climbing is equal to false and can climb is equal to false and what that's going to do is it's going to force them it's going to drop the character and stop them from being able to climb and then i want to reset the climb timer climb timer reset and what that's going to do is that's going to force the character to fall and they're not able to climb anymore now if we look at where can climb shows up it comes shows up here shows up here it shows up here but there's nowhere where it resets can climb so once this once they can't climb they can't climb anymore right it's just done oh i have it's reset here actually i already had it set up so you can see right here we're actually resetting it here i must have had the forethought so we have it set right here so it should allow us to hit play run over here grab onto the wall and then you'll notice after a few seconds it should drop and there we go so now the user can only climb for five seconds but you can make it whatever you would like it to be see so now they can't climb anymore i was hitting c and they can't climb anymore now we do have one small problem where it looks like when the user's up against a wall and they're on the ground you notice that they can jump and bounce off the wall here i'm not a fan of that so we'll fix this last little bug and then in the next video we'll go ahead and check out uh doing animations and things like that for this so we will uh go ahead and take a look at our wall jump here so if we scroll down here we look at our wall jump code and we say yeah we're not on the floor so we need to determine if we're on the floor here to determine if we can actually process our wall jump so let's come up to our wall jump code if not is on floor then you can wall jump that'll solve that problem right there let's see if we fixed our little wall jump issue and then i think we'll call it for this time and there you go so now you cannot wall jump until you've already jumped so you should be able to climb up wall jump up and dash and you can dash and climb and basically that's really all you need for a little celeste like controller all right so that's all i have for you guys today so we went through the process of creating a uh 2d character controller inside of godot c-sharp uh it's very celeste-like so you can dash you can wall jump you can climb and it all resets when you hit the ground so it really is a nice dynamic way of interacting we also talked about casting nodes we talked about creating um raycasts and things like that and we um talked about um you know how to create a good solid character controller so in the next video uh i'm gonna be looking at doing some animations and things like that and showing you guys kind of how to add that into your project and then i'm thinking after that we might discuss some 3d rendering or something like that but we'll see how that goes but anyway guys thank you so much for watching and if you guys like this video hit that like button if you dislike this video hit that dislike button because as always you know i make these tutorials off of your guys's suggestions and off of your guys's feedback so if you guys actually like it you know i'm going to keep trying to do this kind of content so anyway that's all i've got for you guys i'll see y'all next time thanks you
Info
Channel: FinePointCGI
Views: 2,368
Rating: undefined out of 5
Keywords: godot, godot engine, celeste, godot game engine, smooth character movement, celeste game, celeste in godot, character wall climbing in godot, godot player movement, godot movement, godot 2d movement, godot wasd movement, godot wasd 2d movement, celeste godot, godot player movement tutorial, godot movement tutorial, how to make a character that climb walls, godot 2d movement tutorial, C# Godot | Creating a Celeste Like Character Movement System, character Dash, wall jump
Id: yVY2vGz6rwE
Channel Id: undefined
Length: 77min 23sec (4643 seconds)
Published: Mon May 24 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.