How do I implement a falling animation to my sprite?

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

The game I’m working on is a 2D platformer. I’ve been trying to make it so an animatedsprite for falling happens either after the jump animation has ended, or when the player just falls from a platform. I did try to use the animation_finished() signal but that did not work at all.

I genuinely have no clue on how I would implement this. Everything else works perfectly. Anyone who would be able to help me, thanks in advance :slight_smile:

extends KinematicBody2D

func _physics_process(delta):
	#gravity
	if is_on_floor():
    	Global.velocity.y = 0
	else:
		Global.velocity.y += delta * Global.gravity
	get_input()
	move_and_slide(Global.velocity, Vector2.UP)

func get_input():
    #running right
    if Input.is_action_pressed("right"):
    	Global.velocity.x = Global.walkspeed
    	Global.direction == "Right"
    	$Body/Body.flip_h = false
    	$Body/Hair.flip_h = false
    	$Body/Skin.flip_h = false
    	$Body/Eyes.flip_h = false
    	$Body/Sword.flip_h = false
    	if is_on_floor():
    		$Body/Body.play("Run")
    		$Body/Hair.play("Run")
    		$Body/Skin.play("Run")
    		$Body/Eyes.play("Run")
   		$Body/Sword.play("Run")
    #running left
	elif Input.is_action_pressed("left"):
		Global.velocity.x = -Global.walkspeed
		Global.direction = "Left"
		$Body/Body.flip_h = true
		$Body/Hair.flip_h = true
		$Body/Skin.flip_h = true
		$Body/Eyes.flip_h = true
		$Body/Sword.flip_h = true
		if is_on_floor():
			$Body/Body.play("Run")
			$Body/Hair.play("Run")
			$Body/Skin.play("Run")
			$Body/Eyes.play("Run")
			$Body/Sword.play("Run")
	#other
	else:
		Global.velocity.x = lerp(Global.velocity.x, 0.0, 0.1)
		#idle
		if is_on_floor():
			Global.state = "Idle"
			$Body/Body.play("Idle")
			$Body/Hair.play("Idle")
			$Body/Skin.play("Idle")
			$Body/Eyes.play("Idle")
			$Body/Sword.play("Idle")
		#crouching
		if Input.is_action_pressed("Crouch") and Global.state == "Idle":
			Global.state = "Crouch"
			$Body/Body.play("Crouch")
			$Body/Hair.play("Crouch")
			$Body/Skin.play("Crouch")
			$Body/Eyes.play("Crouch")
			$Body/Sword.play("Crouch")
		elif Input.is_action_just_released("Crouch") and Global.state == "Crouch":
			Global.state = "Idle"
		
	
	#jumping
	if is_on_floor() and Input.is_action_pressed("jump"):
		Global.velocity.y = Global.jumpspeed
		Global.state = "Jump"
		$Body/Body.play("Jump")
		$Body/Hair.play("Jump")
		$Body/Skin.play("Jump")
		$Body/Eyes.play("Jump")
		$Body/Sword.play("Jump")

Here’s one suggestion: animate the falling animation in an AnimationPlayer for all of the parts of the character (that is, the eyes, hair, body, and the rest of it). Then all that needs to be done is to play that falling animation rather than keeping up with all of those sprites.

As for the whole falling implementation, try to determine when the player character is falling (usually when they’re not on the ground. Probably also involves keeping track of jumps or something). Hope that helps.

Ertain | 2023-02-06 06:39

:bust_in_silhouette: Reply From: Gluon

If you have a step in the process function which checks against a variable storing the last y condition the character had and if the y has increased it can call the animation player to play falling, e.g.

var Hold_Y_Data = vector2.zero

func process(delta):
    if not character.global_position.y > Hold_Y_Data.y:
        Hold_Y_Data.y = character.global_position.y
    else:
        $AnimationPlayer.play("Falling")
        Hold_Y_Data.y = character.global_position.y