Why gravity only working when i press left or right?

Godot Version

4

Question

With the help of a yt tutorial i made this lil platforming script. but the jumping mechanic seems to be glitching out. gravity is only working when i press left or right, and it just floats there otherwise.

I must be missing something, because the script looks fine.

My only suggestion to try and fix it is to simply apply gravity regardless of jump conditions. Just move velocity.y += grav out of jump() and add it at the end of _physics_process(). After all gravity applies regardless whether you’re jumping or not.

Also, I would change the call order a bit, so the end of _physics_process() looks like this:

    jump()
    velocity.y += grav
    player_movement()
2 Likes

yea its still weird. the jump only works if im holding left or right while jumping, otherwise it just kinda goes up and stays floating there. is it cos im missing a delta or somth somewhere? (lmao sorry im really new to gamedev)

heres the code agen (the animation thing is a placeholder rn)

extends CharacterBody2D

@onready var animated_sprite_2d = $AnimatedSprite2D

const speed = 200
const jump_power = -1000
const acc = 20
const fric = 30
const grav = 30

const max_jumps = 2
var current_jumps = 1

func _physics_process(delta):
	
	var direc: Vector2 = input()
	
	if direc != Vector2.ZERO:
		
		accelerate(direc)
		play_animation()
	
	else:
		
		add_friction()
		play_animation()
		
	player_movement()
	velocity.y += grav 
	jump()
	
func input() -> Vector2:
	
	var direc = Vector2.ZERO
	direc.x = Input.get_axis("move_left", "move_right")
	direc = direc.normalized()
	return direc
	
func accelerate(direction):
	
	velocity = velocity.move_toward(speed * direction, acc)
	
func add_friction():
	
	velocity = velocity.move_toward(Vector2.ZERO, fric)
	
func player_movement():
	
	move_and_slide()

func jump():
	
	if Input.is_action_just_pressed("jump"):
		
		if current_jumps < max_jumps:
			
			velocity.y = jump_power
			current_jumps += current_jumps
		
		else:
			
			pass
	
	if is_on_floor(): 
		
		current_jumps = 1
	
func play_animation():
	
	animated_sprite_2d.play("run")

Oh, I think I found it!

Because velocity is a property with a getter and a setter, you cannot += only one direction. You need to update the entire Vector2

Try this:
velocity += Vector2(0, grav);

also, yes, it’d be wise to apply delta, but I leave that detail to you.

1 Like

bro thnks for the help but it still aint workin :((((. judging by what i see, it seems to be weirdly connected to the acceleration in a way. like, if i jump and only tap the right arrow button, it starts coming down slowly, but if i hold it to let it accelerate and reach max speed, then the gravity starts to work. it also seems to fall faster the longer i hold an arrow key, yea idk whats happenin,

That’s because both accelerate and add_friction (and one of them will be run every frame) override the velocityincluding the y value! – completely.

This should fix it:

func accelerate(direction):
	velocity.x = move_toward(velocity.x, speed * direction.x, acc)
	
func add_friction():
	velocity.x = move_toward(velocity.x, 0, fric)

This is simply wrong.

1 Like