Attack only plays first frame when I use is_action_just_pressed()

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

I have no idea what’s causing this. I’m using state machines for idle, walking, running and falling. The animation Player will made a collisionbox solid as you’d expect.

I’ve tried giving each state its own function, doing away with state machines, a conditional loop, a boolean paired with a timer and none have worked. I’m absolutely stuck.

Here’s my relevant player code.

enum{ WALKING, IDLE,  JUMPING, FALLING, ATTACK1}

if is_on_floor() and velocity.x == 0 and not Input.is_action_pressed("Attack"):
	state = IDLE
elif is_on_floor() and Input.is_action_pressed("Left") or is_on_floor() and Input.is_action_pressed("Right") :
	state = WALKING
elif is_on_floor() and Input.is_action_just_pressed("Attack"):
	state = ATTACK1
elif !is_on_floor():
	if velocity.y < 0:
		 state = JUMPING
	elif velocity.y > 0:
		state = FALLING
match state:
	IDLE:
		$AnimationPlayer.play("PlayerIdle")
	WALKING:
		$AnimationPlayer.play("PlayerRunning")
	JUMPING:
		$AnimationPlayer.play("PlayerJumping")
	FALLING:
		$AnimationPlayer.play("PlayerFalling")
	ATTACK1:
		$AnimationPlayer.play("PlayerAttack1")

What happens after the first frame of the Attack Animation is played? Does it switch back to the idle animation? Do the other animations play all frames, or are they stuck on the first frame too?

archeron | 2021-02-16 01:36

Does the code check to see whether the animation is already playing?

Ertain | 2021-02-16 02:40

your attack animation will be overlapped by idle and walking

when you atack, if you are idle, the “just pressed” will be 1 frame and than you wont be atacking anymore, thus idle, and 1 frame of atack animation

when you attack, if you are walking, the “just pressed” will count 1 frame than you wont be atacking anymore, thus walking, and 1 frame of attack animation

you might want to YIELD you attack animation b4 returning to next animation in cycle
or you might want IS_PRESSED and the attack animation will continue as long as you hold the button

Surtarso | 2021-02-16 13:55

Hi, sorry for late response. It switches to the idle animation after 1 frame

BuddyGames | 2021-02-17 20:23

I do not think it does

BuddyGames | 2021-02-17 20:23

So, how would I implement the Yield? I don’t really want to make it that the player has to hold down click

BuddyGames | 2021-02-17 20:24

:bust_in_silhouette: Reply From: Surtarso

this is something I use on my game

$AnimationPlayer.play("weed_lighter")
yield($AnimationPlayer,"animation_finished")
$bong_hit.play()
$AnimationPlayer.play("warning_blink")

the $bong_hit.play() will only start playing after the "weed_lighter" animation finishes, than another animation will play

so, yield(what, "signal")

but in your case I think something like this should work

if not $animationplayer.is_playing(yourattackanimation) : 
$animationplayer.play(yourwalkanimation)

this will only play the walk animation if the attack animation is not playing

another close example from my game:

        #if the animation is already playing
		if icon_animation.is_playing(): 
            #stop and reset it
			icon_animation.stop(true) 
            #and start playing again
			icon_animation.play("coffee_gone") 
        #if not playing, play
		elif not icon_animation.is_playing(): icon_animation.play("coffee_gone")

this handles a single animation that can be called too fast and overlap, so if its called while already playing, it will start over (its just a blinking icon, so it works) but you get the idea…

you could probably get away with just a .is_playing(): check before any .play()

Hi! Thanks so much for the response, sorry for me only just seeing this, I never got the email. I tried:

if is_on_floor() and velocity.x == 0 and not $animationplayer.is_playing("PlayerAttack1"):
	state = IDLE

But that simply came up with this error message:

Attempt to call function ‘is_playing’ in base ‘null instance’ on a null instance.

Any ideas what’s wrong?

BuddyGames | 2021-02-22 20:34

try

if is_on_floor() and velocity.x == 0:
   yield($AnimationPlayer,"animation_finished")
   state = IDLE

or

if is_on_floor() and velocity.x == 0 and  not $AnimationPlayer.is_playing():
   state = IDLE

Surtarso | 2021-02-22 23:27