Gravity stopped working with new code

Godot Version

Godot4

Question

I have been trying to find a way to use animations with movement like walk and idle, but now that i have been able to do so the gravity on the player is all messed up. I’m new to coding so I dont know much of what the errors or code do as I flavoured a code i found to match what i needed it to do.

extends CharacterBody2D


const SPEED = 100.0
const JUMP_VELOCITY = -100

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = 500
var state_machine
var run_speed = 80


@onready var knight = $Knight
@onready var animation_tree = $AnimationTree

func _ready():
	state_machine = $AnimationTree.get("parameters/playback")

func get_input():
	var current = state_machine.get_current_node()
	velocity = Vector2.ZERO
	if Input.is_action_just_pressed("attack"):
		state_machine.travel("swoosh")
		return
	if Input.is_action_pressed("move_right"):
		velocity.x += 1
		$Knight.scale.x = 1
	if Input.is_action_pressed("move_left"):
		velocity.x -= 1
		$Knight.scale.x = -1
	velocity = velocity.normalized() * run_speed
	if velocity.length() != 0:
		state_machine.travel("run")
	if velocity.length() == 0:
		state_machine.travel("idle")

func _physics_process(delta):
	get_input()
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity * delta
	
	# Handle jump.
	if Input.is_action_just_pressed("jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY
	move_and_slide()

Because you call the get_input function every (physics frame) and every frame the velocity = Vector2.Zero

I’m also kinda new to coding. i would maybe delete the line or try something like this

func get_input():
	var current = state_machine.get_current_node()
	velocity.x  = 0 
	if Input.is_action_just_pressed("attack"):
		state_machine.travel("swoosh")

only set the velocity.x to Zero

1 Like

Unfortunately that just makes me fly when i try to jump, and when I fall off a platform the gravity gets even heavier than it was before, and deleting the line makes it so I slide forever when I start walking

with velocity.x = 0
Mhhh… so if you jump, you jump forever or just very high/long?

Forever

I’m sorry, but with my little knowledge, i don’t get where the problem is. in my understanding: You press “Jump” the Jump_velocity push the player up. And then he is not on floor anymore and the gravity should kick in. haha
Maybe put a print line inside. to see whats going on

print( "Velocity: " + str(velocity.y))
if not is_on_floor():
		velocity.y += gravity * delta
        print( "GRAVITY")

It just infinitely prints:
“Velocity: -71.6666641235352
GRAVITY”

I know its the bug is probably in the “get_input()” function since when i remove it the gravity works properly

I accidentally did it while the velocity was still set to 0, this is what happens with the previous code:

I strongly agree with @littleyumo setting to Vector2.ZERO must be where your velocity.y/gravity is failing. Is there anywhere else you are editing the velocity.y or velocity as a whole? Can you post your updated code?

func get_input():
	var current = state_machine.get_current_node()
	#velocity = Vector2.ZERO # this resets gravity, remove it
	if Input.is_action_just_pressed("attack"):
		state_machine.travel("swoosh")

The code is pratically the same, but deleting the “velocity = Vector2.zero” line makes it so my character slides infinitely unless he hits a wall, i can still change the direction of the sprite with A and D but the direction he’s going stays the same. Anyway here’s the code

extends CharacterBody2D


const SPEED = 100.0
const JUMP_VELOCITY = -100

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = 500
var state_machine
var run_speed = 80


@onready var knight = $Knight
@onready var animation_tree = $AnimationTree

func _ready():
	state_machine = $AnimationTree.get("parameters/playback")

func get_input():
	var current = state_machine.get_current_node()
	velocity = Vector2.ZERO
	if Input.is_action_just_pressed("attack"):
		state_machine.travel("swoosh")
		return
	if Input.is_action_pressed("move_right"):
		velocity.x += 1
		$Knight.scale.x = 1
	if Input.is_action_pressed("move_left"):
		velocity.x -= 1
		$Knight.scale.x = -1
	velocity = velocity.normalized() * run_speed
	if velocity.length() != 0:
		state_machine.travel("run")
	if velocity.length() == 0:
		state_machine.travel("idle")

func _physics_process(delta):
	get_input()
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity * delta
		print("GRAVITY")
	
	
	# Handle jump.
	if Input.is_action_just_pressed("jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY
	move_and_slide()
	
	print( "Velocity: " + str(velocity.y))

How about instead of velocity = Vector2.ZERO you only set velocity.x = 0 or better yet, make your movement inputs combined via get_axis?

I also notice you are normalizing your velocity, which is pretty crazy for a game with jumping, I think that is a dire mistake, any reason normalize is there? It seems like you pulled code from a top-down/RPG game.

func get_input():
	var current = state_machine.get_current_node()
	# deleted velocity = Vector2.ZERO
	if Input.is_action_just_pressed("attack"):
		state_machine.travel("swoosh")
		return

	velocity.x = Input.get_axis("move_left", "move_right")
	if velocity.x != 0:
		$Knight.scale.x = signf(velocity.x)

	# very strange normalize, not to be used in a platformer
	#velocity = velocity.normalized() * run_speed
	velocity.x *= run_speed
	if velocity.x != 0:
		state_machine.travel("run")
	if velocity.x == 0:
		state_machine.travel("idle")

I was trying to follow a tutorial and without realizing it does appear that i took code from a top-down game, as i said im new to coding but it still was rather dumb of me to do that.
Anyway the new code you sent appears to work perfectly, ill try to make sure i understand it well before moving onto something else.
Thank you for the help!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.