Godot Version
4.2.1
Question
my attack animation is stuck at first frame:
var attack4 = false
func animation():
if is_on_floor():
if Input.is_action_just_pressed("attack"):
attack4 = true
if attack4:
$AnimatedSprite2D.play('attack4')
if velocity.x < 0:
$AnimatedSprite2D.flip_h = true
$AnimatedSprite2D.play('run')
elif velocity.x > 0:
$AnimatedSprite2D.flip_h = false
$AnimatedSprite2D.play('run')
if is_on_floor() and velocity.x==0:
$AnimatedSprite2D.play('idle')
My guess it has to do with your second if statement at the same level that plays idle animation.
Have you trouble shot it with print statements?
Place a printstatement under your attack4 = true, and one by your animation.play(“idle”), see if they are both activating in the same func call.
Also, you set attack4 = true, but where do you set it false?
So, what happens is you call animation() if on floor and if you press attack, attack = true, now if attack play animation.
However, the next time animation() is called if your player is on floor it will automatically play attack animation since attack4 still == true.
With how you are using attack4 in what I can see it is unecessary, unless it is used in other code. You could just place your animation under input_pressed and eliminate the attack4.
However, you need to create a system that prevents your idle animation from overriding your attack animation as well.
var attack4 = false
func animation():
if is_on_floor():
if Input.is_action_just_pressed("attack"):
attack4 = true
$AnimatedSprite2D.play('attack4')
attack4 = false
if velocity.x < 0:
$AnimatedSprite2D.flip_h = true
$AnimatedSprite2D.play('run')
elif velocity.x > 0:
$AnimatedSprite2D.flip_h = false
$AnimatedSprite2D.play('run')
elif not attack4:
$AnimatedSprite2D.play('idle')
1 Like
Thanks, it’s working right now but i have to set attack4 false in _on_animation_finished()
signal instead of below the $AnimatedSprite2D.play('attack4')
otherwise it will set the attack4 to false before animation is finished.
Yeah that makes sense, otherwise your other animations would override it. Sounds good!
1 Like
one more problem, i’m trying to move player towards left/right until animation is finished when pressing both left/right key and attack key, but it doesn’t seem to work, it sets velocity.x to 0 but not to 900:
var speed = 500
func _physics_process(delta):
var axis = Input.get_axis('moveLeft', "moveRight")
velocity.x = speed*axis
animation()
func animation():
if is_on_floor():
if Input.is_action_just_pressed("attack"):
attack4 = true
$AnimatedSprite2D.play('attack4')
if velocity.x < 0 and not attack4:
$AnimatedSprite2D.flip_h = true
$AnimatedSprite2D.play('run')
elif velocity.x < 0 and attack4:
speed = 0
velocity.x = -900
elif velocity.x > 0 and not attack4:
$AnimatedSprite2D.flip_h = false
$AnimatedSprite2D.play('run')
elif velocity.x > 0 and attack4:
speed = 0
velocity.x = 900
elif not attack4:
$AnimatedSprite2D.play('idle')
print($AnimatedSprite2D.animation)
if velocity.y < 0:
$AnimatedSprite2D.play('jump')
elif velocity.y > 0:
$AnimatedSprite2D.play('fall')
func _on_animation_finished():
if attack4:
attack4 = false
speed = 500
I think your problem is that the physics_process is resetting your velocity. Physics is called 60 times per second. So, you set speed to 0 and velocity.x = -900, the animation starts playing, however 1/60th of a second later physics runs again and sets velocity.x = speed(0)*axis, effectively setting it to 0.
You can in physics try and add an if statement before setting velocity.x. if not attack4: velocity.x = something.
This also eliminates the million elif statements
var speed = 500
func _physics_process(delta):
var axis = Input.get_axis('moveLeft', "moveRight")
If not attack4:
velocity.x = speed*axis
animation()
func animation():
if is_on_floor():
if Input.is_action_just_pressed("attack"):
attack4 = true
$AnimatedSprite2D.play('attack4')
if not attack4:
if velocity.x < 0:
$AnimatedSprite2D.flip_h = true
$AnimatedSprite2D.play('run')
elif velocity.x > 0:
$AnimatedSprite2D.flip_h = false
$AnimatedSprite2D.play('run')
else:
$AnimatedSprite2D.play('idle')
else:
if velocity.x < 0:
velocity.x = -900
elif velocity.x > 0:
velocity.x = 900
print($AnimatedSprite2D.animation)
if velocity.y < 0:
$AnimatedSprite2D.play('jump')
elif velocity.y > 0:
$AnimatedSprite2D.play('fall')
func _on_animation_finished():
if attack4:
attack4 = false
Generally if you have a lot of if/elif statements checking same for same thing and another thing you can seperate them to make less checks.
1 Like