Need help with fall animation and jump animation

Godot Version 4.4.1

So as you already know from the title, i need help with making jump and fall animation, i am a new developer and i have tried to seek help on the internet but i couldn’t find any information on this, so here’s my code:
`extends CharacterBody2D

var pitch_cooldown := 0.0
const GRAVITY = 200.0
const WALK_SPEED = 200
@export var SonicPitch = int(0)
var sonic_sound_playing = false
var coyote_time := 0.15 # Time allowed after leaving ground to still jump
var coyote_timer := 0.0

func _physics_process(delta):
pitch_cooldown -= delta
velocity.y += delta * GRAVITY

if is_on_floor():
	coyote_timer = coyote_time
else:
	coyote_timer -= delta

# Sonic Pitch Controls
if pitch_cooldown <= 0.0:
	if Input.is_physical_key_pressed(KEY_S) and Input.is_physical_key_pressed(KEY_A) and not Input.is_key_pressed(KEY_X):
		SonicPitch = 0
		pitch_cooldown = 1.0
	elif Input.is_physical_key_pressed(KEY_A) and SonicPitch < 5 and not Input.is_key_pressed(KEY_X):
		SonicPitch += 1
		pitch_cooldown = 1.0
	elif Input.is_physical_key_pressed(KEY_S) and SonicPitch > -5 and not Input.is_key_pressed(KEY_X):
		SonicPitch -= 1
		pitch_cooldown = 1.0

# Sonic Screwdriver Sound Handling
if Input.is_key_pressed(KEY_X) and coyote_timer > 0.0:
	if SonicPitch == 0.0:
		if not $Sprite2D/sonicsound0.is_playing():
			$Sprite2D/sonicsound0.play()
			sonic_sound_playing = true
	elif SonicPitch == 1.0:
		if not $Sprite2D/sonicsound1.is_playing():
			$Sprite2D/sonicsound1.play()
			sonic_sound_playing = true
	elif SonicPitch == 2.0:
		if not $Sprite2D/sonicsound2.is_playing():	
			$Sprite2D/sonicsound2.play()
			sonic_sound_playing = true
	elif SonicPitch == 3.0:
		if not $Sprite2D/sonicsound3.is_playing():
			$Sprite2D/sonicsound3.play()
			sonic_sound_playing = true
	elif SonicPitch == 4.0:
		if not $Sprite2D/sonicsound4.is_playing():
			$Sprite2D/sonicsound4.play()
			sonic_sound_playing = true
	elif SonicPitch == 5.0:
		if not $Sprite2D/sonicsound5.is_playing():
			$Sprite2D/sonicsound5.play()
			sonic_sound_playing = true
	elif SonicPitch == -1.0:
		if not $Sprite2D/"sonicsound-1".is_playing():
			$"Sprite2D/sonicsound-1".play()
			sonic_sound_playing = true
	elif SonicPitch == -2:
		if not $"Sprite2D/sonicsound-2".is_playing():
			$"Sprite2D/sonicsound-2".play()
			sonic_sound_playing = true
	elif SonicPitch == -3:
		if not $"Sprite2D/sonicsound-3".is_playing():
			$"Sprite2D/sonicsound-3".play()
			sonic_sound_playing = true
	elif SonicPitch == -4:
		if not $"Sprite2D/sonicsound-4".is_playing():
			$"Sprite2D/sonicsound-4".play()
			sonic_sound_playing = true
	elif SonicPitch == -5:
		if not $"Sprite2D/sonicsound-5".is_playing():
			$"Sprite2D/sonicsound-5".play()
			sonic_sound_playing = true

	# Stop movement when sonic sound is active
	velocity.x = 0
	$Sprite2D/AnimationPlayer.play("ScrewDriverhold")

# Stop Sonic Sound when X is released
elif not Input.is_key_pressed(KEY_X) and sonic_sound_playing:
	if SonicPitch == 0:
		$Sprite2D/sonicsound0.stop()
	elif SonicPitch == 1:	
		$Sprite2D/sonicsound1.stop()
	elif SonicPitch == 2:	
		$Sprite2D/sonicsound2.stop()
	elif SonicPitch == 3:	
		$Sprite2D/sonicsound3.stop()
	elif SonicPitch == 4:	
		$Sprite2D/sonicsound4.stop()
	elif SonicPitch == 5:	
		$Sprite2D/sonicsound5.stop()
	elif SonicPitch == -1:
		$"Sprite2D/sonicsound-1".stop()
	elif SonicPitch == -2:
		$"Sprite2D/sonicsound-2".stop()
	elif SonicPitch == -3:
		$"Sprite2D/sonicsound-3".stop()
	elif SonicPitch == -4:
		$"Sprite2D/sonicsound-4".stop()
	elif SonicPitch == -5:	
		$"Sprite2D/sonicsound-5".stop()
	sonic_sound_playing = false

# Player Movement and Animation
elif Input.is_action_pressed("ui_left") and Input.is_physical_key_pressed(KEY_Z) and is_on_floor():
	if coyote_timer > 0.0:
		velocity.y = -GRAVITY
		velocity.x = -WALK_SPEED
		if $Sprite2D/AnimationPlayer.current_animation != "Jump_Animation":
			$Sprite2D/AnimationPlayer.play("Jump_Animation")
		
	else:
		pass

elif Input.is_action_pressed("ui_right") and Input.is_physical_key_pressed(KEY_Z) and is_on_floor():
	if coyote_timer > 0.0:
		velocity.y = -GRAVITY
		velocity.x = WALK_SPEED
		if $Sprite2D/AnimationPlayer.current_animation != "Jump_Animation":
			$Sprite2D/AnimationPlayer.play("Jump_Animation")
		
	else:
		pass

elif Input.is_action_pressed("ui_right") and Input.is_action_pressed("ui_left"):
	velocity.x = 0
	$Sprite2D/AnimationPlayer.play("Idle_Animation")

elif Input.is_action_pressed("ui_left"):
	velocity.x = -WALK_SPEED
	$Sprite2D/AnimationPlayer.play("Walk_Animation")
elif Input.is_action_pressed("ui_right"):
	velocity.x =  WALK_SPEED
	$Sprite2D/AnimationPlayer.play("Walk_Animation")
elif Input.is_key_pressed(KEY_Z) and is_on_floor():
	if coyote_timer > 0.0:
		if $Sprite2D/AnimationPlayer.current_animation != "Jump_Animation":
			$Sprite2D/AnimationPlayer.play("Jump_Animation")
		velocity.y = -GRAVITY
	else:
		pass

# Default Idle State
else:
	velocity.x = 0
	$Sprite2D/AnimationPlayer.play("Idle_Animation")

# Flip sprite direction based on velocity
if velocity.x:
	$Sprite2D.flip_h = velocity.x < 0
	$Sprite2D/Area2D/CollisionShape2D.position.x = absf($Sprite2D/Area2D/CollisionShape2D.position.x) * signf(velocity.x)

if not is_on_floor():
	if $Sprite2D/AnimationPlayer.current_animation != "Fall_Animation":
		$Sprite2D/AnimationPlayer.play("Fall_Animation")

# Move player
move_and_slide()

func _on_area_2d_body_entered(body: StaticBody2D) → void:
if body.is_in_group(“Mechanic”):
if body.SonicPitch_req == SonicPitch:
if body.has_method(“Breaking”):
body.Breaking()
else:
pass
else:
pass

and here’s the video of how it works for me:

If you post your code like this:

```gdscript
func your_code_here()
```

It will format nicely:

func your_code_here()

Beyond that, what help would you like? You’ve got code, which is good, but “I’d like help with the jump and fall animation” leaves a lot to interpretation. What isn’t it doing that you want it to do? What is it doing that you want it to stop doing?

I would like if you’ll give me a code example on how do i fix so that the jump animation will actually fully play when you press Z and won’t stop immediately, and also the fall animation doesn’t even play, i need it to override every other animation if the player is not on floor. (sorry for grammar, english isn’t my first language)

Well, looking at the code, you’ve got this bit:

#pseudocode
if not is_on_floor():
    if anim != falling:
        play(falling)

With that in the code, the moment your character is in the air jumping, the fall animation is going to take over and the jump animation will be overridden.

What you probably want to do is something like:

#pseudocode again...
if not is_on_floor() and velocity.y > 0.0: # in air, AND dropping
    if anim != falling: play(falling)

I may have the y test backwards; I can’t remember whether y increases up or down in 2d. The gist, though, is you probably want to start the fall animation once the character is past the apex of the jump and starts actually moving downwards again.

1 Like

You’ve got the y test spot on. y increases down in 2d.

So it kinda works, i also changed the jump code to this:

elif Input.is_key_pressed(KEY_Z):
		if coyote_timer > 0.0:
			if $Sprite2D/AnimationPlayer.current_animation != "Jump_Animation":
				$Sprite2D/AnimationPlayer.play("Jump_Animation")
			if is_on_floor():
				velocity.y = -GRAVITY

But i still need to hold the key for the animation to fully play, but i can also use the await command but i think it can launch me pretty high because all the jumps can register and return a sum of the -GRAVITY constant

I’d suggest is_key_just_pressed() rather than is_key_pressed(), at least for starting the jump animation. You can always check is_pressed() separately if you want to let the player control the jump power a bit.

So i think i solved this, thanks for the help though!
I’ll need to put something as a solution so i’ll put in my solution:
The fall animation code:

if not is_on_floor() and velocity.y > 0: # in air, AND dropping
		if $Sprite2D/AnimationPlayer.current_animation != "Fall_Animation":
			$Sprite2D/AnimationPlayer.play("Fall_Animation")

and here’s how i fixed the jump animation to play:

elif Input.is_key_pressed(KEY_Z):
		if coyote_timer > 0.0:
			if $Sprite2D/AnimationPlayer.current_animation != "Jump_Animation":
				$Sprite2D/AnimationPlayer.play("Jump_Animation")
			if is_on_floor():
				velocity.y = -GRAVITY
		else:
			pass
	elif not Input.is_key_pressed(KEY_Z) and $Sprite2D/AnimationPlayer.current_animation == "Jump_Animation":
		if coyote_timer > 0.0:
			if $Sprite2D/AnimationPlayer.current_animation != "Jump_Animation":
				$Sprite2D/AnimationPlayer.play("Jump_Animation")
		else:
			pass

Looking at your code, the reason you had to hold the button to get the animation to play is, the else at the end of that big decision tree is stomping the animation to "idle". So if you aren’t pressing the button, it falls through to the else block and ovewrites your jump/fall/whatever animation with the idle animation.

1 Like

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