I've just finished watching the tutorial and I didn't realise it was from such a small channel (not in a bad way) because of the quality, I genuinely thought the production was professional. Amazing video! You earned a new subscriber for sure!
Great tutorial! I love your style, it's easy to understand the code with your explanations if you don't have idea of coding. If you make a second part about character movement, can you please talk about double jumps and jump buffer? Subscribed!
I'm very interested in your dash logic using curves. I didn't realize curves were a resource in Godot and have been going down that rabbit hole ever since finishing this video. Do you have any good webpages/resources for better understanding of curves? I have read through Godot's documentation and read through a few websites about mathematical curves however, it seems to be such a vast topic I'm not sure how to find the basics of them. I want to implement an approach similar to your but with 8-way movement with Vector2s controlling the input-direction. I feel like this was taught to me in math class but I can't remember so any learning resources would be helpful. Either way tysm for uploading this video as I've been able to learn a lot of better info regarding player movement in general (even if this is godot) and how other games can make more satisfying movement mechanics. These are the type of videos people should save to come back to since there is just so much good info to unpack/research more into. Great friggen job!!
Thanks for the appreciation. I'm glad you liked it! As resources, I mostly learned curves, in a game development context, like tutorials made by Freya Holmér. Especially the ones on interpolation, splines, and Bézier Curves. She explains them great! I'll link a few for you to check out: Interpolation: ua-cam.com/video/-Ii3MrJFBkQ/v-deo.html Splines: ua-cam.com/video/jvPPXbo87ds/v-deo.html Beziér curves: ua-cam.com/video/aVwxzDHniEw/v-deo.html I hope this is of any value to you. Good luck!
Hi when I run the game during dashing I get the following error in debugger: Cannot call non-static function "sample()" on the class "Curve" directly. Make an instance instead. my code is same as your but ill paste it here- if is_dashing: var current_distance = abs(position.x - dash_start_position) if current_distance >= dash_max_distance or is_on_wall(): is_dashing = false else: velocity.x = dash_direction * dash_speed * dash_curve.sample(current_distance / dash_max_distance) velocity.y = 0 if dash_timer > 0: dash_timer -= delta Please help me with this, everything else is S tier and thanks in advance for putting this tutorial up.
Hey! Glad you like the tutorial! I might have a solution for your problem. The code you displayed here is fine, but I suspect you did something wrong with creating the variable dash_curve. Did you, by any chance, declare the variable like this: @export var dash_curve = Curve Because it should be: @export var dash_curve: Curve Hope that solves your problem :)
@@IcyEngine That was it, I see my mistake, I didnt know thats how you declared type of variables. My muscle memory typed it as var dash_curve = Curve. Thank you again for reaching out so quickly. I really appreciate it. Hope you have a great vacation. Looking forward to learning from your videos more soon.
i did everything in this vid but the camera doesnt follow the player idk what i did wrong edit: fixed it lol character was set to node2d instead of characterbody2d
I wouldn't say it's not compatible... you'd have to get creative. In programming there are thousands of ways to do a single thing, same goes for implementing an input buffer for jumping here. What input buffering essentially is, is queueing up an input and executing a command (jumping) when a state is reached (touching ground). Keeping in mind that I want the code tutorial to be simple and understandable, I would add a variable that is of type boolean that would be set to true if we press the jump button but we're in the air. Once we touch the ground AND that boolean is true, I would execute another jump and set that boolean to false again. It would look something like this: ## 1 line added under the variable declarations. var jump_buffer = false ## Replace the original jump code with jump buffer handling and then jump handling: # Handle jump buffer. if is_on_floor() and jump_buffer: jump_buffer = false velocity.y = jump_force # Handle jump. if Input.is_action_just_pressed("jump"): if (is_on_floor() or is_on_wall()): velocity.y = jump_force else: jump_buffer = true BUT... there's a tiny catch with this one. Games often have a set of frames where the buffer stays active so that you won't be punished by unintentional input buffering. What I mean is, that in the code above, pressing the jump button two times in quick succession, would cause the player to jump again upon landing on the ground. But this is my quick and dirty solution to your problem. Good luck!
Could you elaborate on the mechanic for a bit? Do you mean like increasing speed for a bit upon performing the jump like what happens in Minecraft when running and jumping?
@@IcyEngine currently you can sprint if you are pressing the key and are on the floor. I want the increased speed to carry on jumps. I can just get rid of the and is_on_floor() but then you can start sprinting mid air.
@@Tieslo a alright, like that. So what I get from this is that you added the is_on_floor() check yourself. This means that you won’t be able to turn around mid-air, but rather keep the momentum while being slowed down by the deceleration. What you could do is change the else to an “elif” (short for else-if) and also add a is_on_floor() check, or completely encapsulate the walk/run part in a floor check condition. I’m still not entirely sure if this is what you want since you won’t be able to control your character mid air anymore, that’s why in the code in the video, there is no floor check in the walk/run section. However, if you still want to be able to turn around mid air, but not being able to sprint mid-air, still remove the floor check you have, and above, next to the ‘Input.is_action_pressed(“run”)’, add “and is_on_floor()” so you will only be able to start running while being on the floor, but only change directions at normal speed in mid-air.
@@IcyEngine I just want to say thank you for taking the time to answer these noob questions. Even though you probably don't see it, you're helping more than just the person asking the question so thank you thank you thank you for doing so.
I did! Well… sort of… I made an video on how to add sprite animation and how to add lines of code to make it work. Second video of my channel. In the comment section of that video is also a pastebin link that contains the animations you saw at the end of this video.
Great tutorial man, but i can't move my chrarcter after one or two dashes. Do you have any idea why? I'll paste the code here: extends CharacterBody2D @export var run_speed = 480 @export var walk_speed = 300 @export var jump_force = -600 @export_range(0, 1)var decelaration = 0.08 @export_range(0, 1)var acceleration = 0.08 @export_range(0, 1)var decelerate_jump_on_release = 0.4 @export var dash_speed = 1000.0 @export var dash_max_distance = 300.0 @export var dash_curve : Curve @export var dash_cooldown = 1.0 var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") var is_dashing = false var dash_start_position = 0 var dash_direction = 0 var dash_timer = 0 func _physics_process(delta): if not is_on_floor(): velocity.y += gravity * delta if Input.is_action_just_pressed("jump") and (is_on_floor() or is_on_wall()): velocity.y = jump_force if Input.is_action_just_released("jump") and velocity.y < 0: velocity.y *= decelerate_jump_on_release var speed if Input.is_action_pressed("run"): speed = run_speed else: speed = walk_speed var direction = Input.get_axis("move_left", "move_right") if direction: velocity.x = move_toward(velocity.x, direction * speed, speed * acceleration) else: velocity.x = move_toward(velocity.x, 0, walk_speed * decelaration) if Input.is_action_just_pressed("Dash") and direction and not is_dashing and dash_timer = dash_max_distance or is_on_wall(): is_dashing = false else: velocity.x = dash_direction * dash_speed * dash_curve.sample(current_distance / dash_max_distance) velocity.y = 0 if dash_timer > 0: dash_timer -= delta move_and_slide()
Ahh I see... your code is well written, so nothing wrong with that. I'm assuming that the curve you have to set in the inspector hits 0 at some point. I didn't think of this at the time, but if your curve reaches 0 at some point, then the line where you calculate the x velocity will always be 0 (cuz you know something * something * 0 = 0)... And if the x velocity is 0, your character won't move forward, the current distance won't increase as you're not moving forward anymore and the condition of finishing the dash will always be false. So, an easy way to fix this, is to let your curve never hit 0, at 17:25 you see me configuring the curve, and notice how my curve never hits 0. Another way to fix this is by adding another condition, I'll add the changed code below: if is_dashing: var current_distance = abs(position.x - dash_start_position) if current_distance >= dash_max_distance or is_on_wall(): is_dashing = false else: velocity.x = dash_direction * dash_speed * dash_curve.sample(current_distance / dash_max_distance) if velocity.x == 0: is_dashing = false velocity.y = 0 This way, that if your curve does reach 0, it will just stop the dash. But make sure your curve doesn't start at 0, otherwise this won't work either! I hope you understand it and good luck! Lmk if you need anything else.
Ah yes, so you should look up how to make animations for now since I’m not planning on making a tutorial for those right away (I just left for vacation since I’m still a student). In my video I only have a idl, walk and a jump animation right? What you want is the following: 1. Replace the Sprite2D with a AnimatedSprite2D. Then create animation for it with animation names. 2. Create a variable to couple that AnimatedSprite2D to the PlayerController script (@onready var animated_sprite = $AnimatedSprite2D) 3. Then using that variable you want to start playing it on the right places using animated_sprite.play(“animation_name_here”). 4. In the script, I swapped the jump and walk/run section, otherwise it started playing waling animations in the air. 5. Then the walking code should look something like this: if direction: velocity.x = move_toward(… acceleration …) animated_sprite.flip_h = direction == -1 if is_on_floor() animated_sprite.play(“walk”) else: velocity.x = move_toward(… deceleration …) if is_on_floor() animated_sprite.play(“idle”) 6. Then the jump part is really easy, just add an animated_sprite.play(“jump”) right under the line where you set the velocity.y to jump. Make sure the jumping animation is not looping in the spriteframes. The Godot Docs on 2D animation is pretty easy to follow: docs.godotengine.org/en/stable/tutorials/2d/2d_sprite_animation.html
No that’s fair, the code is to give an idea into how to build mechanics, if I were to implement animations I would work with state machines, but they can get much more complicated then this.
very underrated tutorial
Man, you saved my life, this tutorial is amazing and I'm offended it has so few views
Awesome base tutorial. Much better then many as it covvers most things ya want to get started instead of focusing on all the animations etc.
I've just finished watching the tutorial and I didn't realise it was from such a small channel (not in a bad way) because of the quality, I genuinely thought the production was professional. Amazing video! You earned a new subscriber for sure!
Great job. Nice pace and clear explanations. I'd like to see a part 2 where you show us how you added the animations to this.
I can’t believe how few views this video has. Wonderful tutorial
Wish you luck in making videos. It`s really great tutorial especially for ones who started learn smth about game dev (me). Thank you mate
As a teacher, I approve this very well explained video. Good job!
10:32 im having trouble with this, godot says “speed” is not declared in the script
edit: nevermind! fixed it! forgot to remove an indent
amazing quality of video and edits. would be very interested on seeing a video of you adding more features to this like ledge grabbing. cheers
Incredible tutorial! Explains everything well, provides assets, code if needed, and works great! Thank you very much
Very good explained tutorial and very good video!!
Thank you, Icy Engine. I was able to incorporate some of these features like the dash without an issue, with the Godot Engine 4.3.
I liked this. Straight to the point, very informative, and great for beginners! :]
Great stuff! would love to see more tutorials. subscription earned :)
Thank you so much, this video cleared up a lot of things for me. You just got your 100th sub :)
You explained this so good! I just had to subscribe. I want to be a game dev youtuber aswell, but I have like 0 knowledge xD
amazing work bro. i love you video
Damn such a good ass tutorial bro
Great tutorial! I love your style, it's easy to understand the code with your explanations if you don't have idea of coding. If you make a second part about character movement, can you please talk about double jumps and jump buffer? Subscribed!
Great turorial, thanks a lot!
amazing !
Very eazy to understand
I'm very interested in your dash logic using curves. I didn't realize curves were a resource in Godot and have been going down that rabbit hole ever since finishing this video. Do you have any good webpages/resources for better understanding of curves? I have read through Godot's documentation and read through a few websites about mathematical curves however, it seems to be such a vast topic I'm not sure how to find the basics of them. I want to implement an approach similar to your but with 8-way movement with Vector2s controlling the input-direction. I feel like this was taught to me in math class but I can't remember so any learning resources would be helpful. Either way tysm for uploading this video as I've been able to learn a lot of better info regarding player movement in general (even if this is godot) and how other games can make more satisfying movement mechanics. These are the type of videos people should save to come back to since there is just so much good info to unpack/research more into. Great friggen job!!
Thanks for the appreciation. I'm glad you liked it! As resources, I mostly learned curves, in a game development context, like tutorials made by Freya Holmér. Especially the ones on interpolation, splines, and Bézier Curves. She explains them great! I'll link a few for you to check out:
Interpolation: ua-cam.com/video/-Ii3MrJFBkQ/v-deo.html
Splines: ua-cam.com/video/jvPPXbo87ds/v-deo.html
Beziér curves: ua-cam.com/video/aVwxzDHniEw/v-deo.html
I hope this is of any value to you. Good luck!
@IcyEngine This is perfect and exactly what I was looking for!! Thank you man, fr this is super helpful
good tutorial
Hi when I run the game during dashing I get the following error in debugger: Cannot call non-static function "sample()" on the class "Curve" directly. Make an instance instead.
my code is same as your but ill paste it here-
if is_dashing:
var current_distance = abs(position.x - dash_start_position)
if current_distance >= dash_max_distance or is_on_wall():
is_dashing = false
else:
velocity.x = dash_direction * dash_speed * dash_curve.sample(current_distance / dash_max_distance)
velocity.y = 0
if dash_timer > 0:
dash_timer -= delta
Please help me with this, everything else is S tier and thanks in advance for putting this tutorial up.
Hey! Glad you like the tutorial! I might have a solution for your problem. The code you displayed here is fine, but I suspect you did something wrong with creating the variable dash_curve.
Did you, by any chance, declare the variable like this:
@export var dash_curve = Curve
Because it should be:
@export var dash_curve: Curve
Hope that solves your problem :)
@@IcyEngine That was it, I see my mistake, I didnt know thats how you declared type of variables. My muscle memory typed it as var dash_curve = Curve.
Thank you again for reaching out so quickly. I really appreciate it. Hope you have a great vacation. Looking forward to learning from your videos more soon.
@@IcyEngine I made the same mistake, thanks for the help!
i did everything in this vid but the camera doesnt follow the player
idk what i did wrong
edit: fixed it lol
character was set to node2d instead of characterbody2d
Haha happens, good thing you fixed it🔥
Very good tutorial, but don't forget about Coyote time. Thank you, subscribed
That’s a nice addition, hadn’t crossed my mind when I was thinking of basic moves.
How would I add buffer jump to this? it doesn't seem to be compatible with the buffer jump tutorials I'm finding
I wouldn't say it's not compatible... you'd have to get creative. In programming there are thousands of ways to do a single thing, same goes for implementing an input buffer for jumping here. What input buffering essentially is, is queueing up an input and executing a command (jumping) when a state is reached (touching ground). Keeping in mind that I want the code tutorial to be simple and understandable, I would add a variable that is of type boolean that would be set to true if we press the jump button but we're in the air. Once we touch the ground AND that boolean is true, I would execute another jump and set that boolean to false again.
It would look something like this:
## 1 line added under the variable declarations.
var jump_buffer = false
## Replace the original jump code with jump buffer handling and then jump handling:
# Handle jump buffer.
if is_on_floor() and jump_buffer:
jump_buffer = false
velocity.y = jump_force
# Handle jump.
if Input.is_action_just_pressed("jump"):
if (is_on_floor() or is_on_wall()):
velocity.y = jump_force
else:
jump_buffer = true
BUT... there's a tiny catch with this one. Games often have a set of frames where the buffer stays active so that you won't be punished by unintentional input buffering. What I mean is, that in the code above, pressing the jump button two times in quick succession, would cause the player to jump again upon landing on the ground. But this is my quick and dirty solution to your problem. Good luck!
Get famous please add animation tut on how to integrate animations
pls do it
how would you add sprint jumping to this?
Could you elaborate on the mechanic for a bit? Do you mean like increasing speed for a bit upon performing the jump like what happens in Minecraft when running and jumping?
@@IcyEngine currently you can sprint if you are pressing the key and are on the floor. I want the increased speed to carry on jumps. I can just get rid of the and is_on_floor() but then you can start sprinting mid air.
@@Tieslo a alright, like that. So what I get from this is that you added the is_on_floor() check yourself. This means that you won’t be able to turn around mid-air, but rather keep the momentum while being slowed down by the deceleration. What you could do is change the else to an “elif” (short for else-if) and also add a is_on_floor() check, or completely encapsulate the walk/run part in a floor check condition.
I’m still not entirely sure if this is what you want since you won’t be able to control your character mid air anymore, that’s why in the code in the video, there is no floor check in the walk/run section.
However, if you still want to be able to turn around mid air, but not being able to sprint mid-air, still remove the floor check you have, and above, next to the ‘Input.is_action_pressed(“run”)’, add “and is_on_floor()” so you will only be able to start running while being on the floor, but only change directions at normal speed in mid-air.
@@IcyEngine I just want to say thank you for taking the time to answer these noob questions.
Even though you probably don't see it, you're helping more than just the person asking the question so thank you thank you thank you for doing so.
Thanks! That means a lot to me. Nothing wrong with noob questions right? Everyone has to begin somewhere. Just glad I could help🫶
Can you make how to add animation to this project?
I did! Well… sort of… I made an video on how to add sprite animation and how to add lines of code to make it work. Second video of my channel. In the comment section of that video is also a pastebin link that contains the animations you saw at the end of this video.
@IcyEngine thanks!
Great tutorial man, but i can't move my chrarcter after one or two dashes. Do you have any idea why? I'll paste the code here: extends CharacterBody2D
@export var run_speed = 480
@export var walk_speed = 300
@export var jump_force = -600
@export_range(0, 1)var decelaration = 0.08
@export_range(0, 1)var acceleration = 0.08
@export_range(0, 1)var decelerate_jump_on_release = 0.4
@export var dash_speed = 1000.0
@export var dash_max_distance = 300.0
@export var dash_curve : Curve
@export var dash_cooldown = 1.0
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var is_dashing = false
var dash_start_position = 0
var dash_direction = 0
var dash_timer = 0
func _physics_process(delta):
if not is_on_floor():
velocity.y += gravity * delta
if Input.is_action_just_pressed("jump") and (is_on_floor() or is_on_wall()):
velocity.y = jump_force
if Input.is_action_just_released("jump") and velocity.y < 0:
velocity.y *= decelerate_jump_on_release
var speed
if Input.is_action_pressed("run"):
speed = run_speed
else:
speed = walk_speed
var direction = Input.get_axis("move_left", "move_right")
if direction:
velocity.x = move_toward(velocity.x, direction * speed, speed * acceleration)
else:
velocity.x = move_toward(velocity.x, 0, walk_speed * decelaration)
if Input.is_action_just_pressed("Dash") and direction and not is_dashing and dash_timer = dash_max_distance or is_on_wall():
is_dashing = false
else:
velocity.x = dash_direction * dash_speed * dash_curve.sample(current_distance / dash_max_distance)
velocity.y = 0
if dash_timer > 0:
dash_timer -= delta
move_and_slide()
Ahh I see... your code is well written, so nothing wrong with that. I'm assuming that the curve you have to set in the inspector hits 0 at some point. I didn't think of this at the time, but if your curve reaches 0 at some point, then the line where you calculate the x velocity will always be 0 (cuz you know something * something * 0 = 0)... And if the x velocity is 0, your character won't move forward, the current distance won't increase as you're not moving forward anymore and the condition of finishing the dash will always be false. So, an easy way to fix this, is to let your curve never hit 0, at 17:25 you see me configuring the curve, and notice how my curve never hits 0.
Another way to fix this is by adding another condition, I'll add the changed code below:
if is_dashing:
var current_distance = abs(position.x - dash_start_position)
if current_distance >= dash_max_distance or is_on_wall():
is_dashing = false
else:
velocity.x = dash_direction * dash_speed * dash_curve.sample(current_distance / dash_max_distance)
if velocity.x == 0:
is_dashing = false
velocity.y = 0
This way, that if your curve does reach 0, it will just stop the dash. But make sure your curve doesn't start at 0, otherwise this won't work either! I hope you understand it and good luck! Lmk if you need anything else.
Thanks man, but i think my game actually crashes💀Anyways thanks for responding me dude appreciate it
❤❤❤❤❤❤❤
how did you do the animation
Ah yes, so you should look up how to make animations for now since I’m not planning on making a tutorial for those right away (I just left for vacation since I’m still a student).
In my video I only have a idl, walk and a jump animation right? What you want is the following:
1. Replace the Sprite2D with a AnimatedSprite2D. Then create animation for it with animation names.
2. Create a variable to couple that AnimatedSprite2D to the PlayerController script (@onready var animated_sprite = $AnimatedSprite2D)
3. Then using that variable you want to start playing it on the right places using animated_sprite.play(“animation_name_here”).
4. In the script, I swapped the jump and walk/run section, otherwise it started playing waling animations in the air.
5. Then the walking code should look something like this:
if direction:
velocity.x = move_toward(… acceleration …)
animated_sprite.flip_h = direction == -1
if is_on_floor()
animated_sprite.play(“walk”)
else:
velocity.x = move_toward(… deceleration …)
if is_on_floor()
animated_sprite.play(“idle”)
6. Then the jump part is really easy, just add an animated_sprite.play(“jump”) right under the line where you set the velocity.y to jump. Make sure the jumping animation is not looping in the spriteframes.
The Godot Docs on 2D animation is pretty easy to follow: docs.godotengine.org/en/stable/tutorials/2d/2d_sprite_animation.html
@@IcyEngine np I know how to do the animation and did it just was a bit confused with it on this code.
No that’s fair, the code is to give an idea into how to build mechanics, if I were to implement animations I would work with state machines, but they can get much more complicated then this.
@@IcyEngine everyones telling me