Falling animation plays when going down slopes

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By buntudu

enter image description here

When my player walks down slopes, the falling animation plays. I believe this is due to the game checking if the player is not on the floor to play the jump animation, and the slope causes it to play. My goal is to have the animation play only when the jump button is pressed, so when falling without pressing space it just continues the previous animation.

Thank you.
I’ve been encountering a lot of problems on here, sorry for so many questions.

How do you control your animations?

Kirito | 2023-03-11 22:41

I haven’t been using version 4.0 of the engine, so I don’t know how I can help. Do you depend on something like is_on_floor() to detect when the character is colliding with the floor? Have you also tried raycasts for checking for floor collision?

Ertain | 2023-03-11 22:42

Dont know how, but i forgot to link the code. Here it is:

extends CharacterBody2D

# Variables
@onready var timer = $Timer
@onready var sprite = $AnimatedSprite2D

var SPEED = 100
var JUMP_VELOCITY = -400.0
var timer_started = false
var running = false
var jumping = true
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _physics_process(_delta):
	# Handle gravity and jumping
	if not is_on_floor():
#		sprite.play("Jump")
		print("Not on ground")
		velocity.y += 25 #gravity * delta
	else:
		print("On ground")
		if velocity.x == 0:
			sprite.play("Jump")
		else:
			if running == true:
				sprite.play("Run")
			else:
				sprite.play("Walk")

	# Handle jumping input
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY
		sprite.play("Jump")
	# If the player is not on the ground, and not jumping, set their animation to "Jump"
	elif not is_on_floor():
		sprite.play("Jump")

	# Handle movement input
	var direction = Input.get_axis("ui_left", "ui_right")

	if direction:
		velocity.x = direction * SPEED

		if velocity.x < 0:
			sprite.flip_h = true
		elif velocity.x > 0:
			sprite.flip_h = false

		# Start the timer and play the "Walk" animation
		if not timer_started:
			running = false
			sprite.play("Walk")
			if not is_on_floor():
				sprite.play("Jump")
			else:
				sprite.play("Walk")
			timer.start()
			timer_started = true
	else:
		# Stop the timer and play the "Idle" animation
		if not is_on_floor():
			sprite.play("Jump")
		else:
			sprite.play("Idle")
		running = false
		velocity.x = move_toward(velocity.x, 0, SPEED)
		SPEED = 100
		timer.stop()
		timer_started = false

	move_and_slide()

func _on_timer_timeout():
	timer.stop()
	sprite.play("Run")
	running = true
	print("Timer has timed out!")
	SPEED = 200

buntudu | 2023-03-12 16:31

Basically for every player event (jumping, running, walking) I check to see if the player is on the floor or not to play the jumping animation walking animation or running animation

buntudu | 2023-03-12 16:43

Have you tried using move_and_slide_with_snap() ? i read that it works for precisely that, to “glue” movement to the slopes, haven’t tried it myself but the documentation could help. Also i believe the syntax has changed for godot 4.

Edit: Apparently in godot 4 that function is gone and now you just need to set the snap value floor_snap_length , source: https://forum.godotengine.org/137825/move_and_slide_with_snap-in-godot-4

JCJL | 2023-03-12 17:11

:bust_in_silhouette: Reply From: buntudu

I believe the problem has to do with 4.0 and it causes this snapping problem as shown in my example.

A pull request was merged a week ago so I will have to wait until a fix releases.

:bust_in_silhouette: Reply From: aidave

You can add one or more RayCast2Ds to your character scene, then use those to detect if on a floor instead, to behave more precisely how you want.