"duck" animation switches back to "idle" for one frame and then back

Godot Version

4.2.1

Question

Hi! Thank you for checking this topic. I am VERY new making videogames and coding in general. Any help is well recieved.

so! Im trying to set up my Main character animations. For each animation (idle, duck, sprint, jump, etc) I drew each frame by hand, set each animation up using the AnimatedSprite2D, which then I imported into the AnimationPlayer using an add-on plug in, and its all being controlled with an AnimationTree with some conditions attached for each animation.

and them Im calling them on my script to match whatever input is coming from my controller.

func update_animation_parameters():

#to control the orientation of Mandy:
if Input.is_action_just_pressed("RIGHT"):
	animated_sprite_2d.flip_h = false
	
if Input.is_action_just_pressed("LEFT"):
	animated_sprite_2d.flip_h = true
	

#define Idle	
if velocity == Vector2(0, 0) and is_on_floor(): 
	animation_tree ["parameters/conditions/idle"] = true
else:
	animation_tree ["parameters/conditions/idle"] = false

#Ducking
if Input.is_action_pressed("DOWNPAD"):	
		state_machine.travel("duck")
		animation_tree ["parameters/conditions/duck"] = true
		animation_tree ["parameters/conditions/idle"] = false
	
if Input.is_action_just_released("DOWNPAD"):
		state_machine.travel("idle")
		animation_tree ["parameters/conditions/duck"] = false

this works pretty well for what I need. when I press the downpad, my character ducks, and when I release, she goes back to Idle animation. exactly what I intended.

THE PROBLEM is that whenever shes in the duck animation, she will flicker back to Idle for what it seems one frame (it is REALLY REALLY fast) and then she goes back to duck. she will do this indifinitely, for as long as shes ducking down.
the flickering sometimes seems to be ciclycal, but most of the time it almost seems at random:
my character will duck for 2 seconds, flicker back to idle for one frame once, go back to duck, stay 6 seconds ducking, flicker again, go back to duck, 10 seconds this time, flicker again, go back for one second, flicker again. etc.
each instance is different.

I am running my “func update_animation_parameters():” inside func _physics_process(delta):

Ive tried also running it inside func process(delta) with no success

I think its worth mentioning that I looked at the remote to see what was going on inside the animation tree and the condition “idle” is still OFF when that flickering frame happens. “Duck” condition stays ON the whole time

I have entirely run out of ideas, and since im too new at this, im having a lot of trouble properly articulating my problem online to find a solution.

Thank you for your time!

1 Like

Change the action release as else branch for action pressed.
Insted of this:

#Ducking
if Input.is_action_pressed("DOWNPAD"):	
		state_machine.travel("duck")
		animation_tree ["parameters/conditions/duck"] = true
		animation_tree ["parameters/conditions/idle"] = false
	
if Input.is_action_just_released("DOWNPAD"):
		state_machine.travel("idle")
		animation_tree ["parameters/conditions/duck"] = false

Use this:


#Ducking
if Input.is_action_pressed("DOWNPAD"):	
		state_machine.travel("duck")
		animation_tree ["parameters/conditions/duck"] = true
		animation_tree ["parameters/conditions/idle"] = false
	
else:
		state_machine.travel("idle")
		animation_tree ["parameters/conditions/duck"] = false

This should fix the peoblem.

Thank you so much for replying!
Gave it a try and sadly it is still doing the same thing.

Try this.

var is_duck = false

func _input(event):
    if Input.is_action_just_pressed("DOWNPAD"):
        is_duck = true
    
    if Input.is_action_just_released("DOWNPAD"):
        is_duck = true

func _physics_process(delta):
    #...
    
    if is_duck:
        # place your duck animation here
    else:
        # place your idle animation here

Thank you again for your assistance!

I managed to find a solution for my problem:
in the inspector of the animationplayer I had to change the callback mode process to manual. (physics and idle would make my problem appear)
Im still too new to understand exactly why this worked. but it did.

Don’t use Input methods in _input, use the event directly, see here