need help with signals still emitting from previous state after changing state

Godot Version

Godot Version 4.7

Question

Hi! I’m completely new to game dev and coding in general. I was following a few lessons and tutorial about state machine.

I am using node-based state machine and animation tree for my basic combo attack.

so, from idle, jog, and sprint_state, it can change to attack1_state when the “action” input is pressed then go back to one of the three states after the animation is finished.

my problem is that while in attack1_state, if I pressed the “action” input again, while it does change to attack2_state, the _on_animation_tree_animation_finished is still emitted so it goes back to idle/jog/sprint state before the attack2_state animation finished. any help would be greatly appreciated, thank you!

this is gdscript for attack1_state, gdscript for attack2_state is basically the same but it changes to attack3_state instead. and the process_input function is unhandled_input if that’s any help!

extends State

@export var idle_state: State
@export var jog_state: State
@export var sprint_state:State
@export var attack2_state: State

func enter() -> void:
	super()
	playback.travel("attack1")
	is_attacking = true

func process_input(_event: InputEvent) -> State:
	if Input.is_action_just_pressed("action") && is_attacking:
		return  attack2_state
		
	return null


func process_physics(_delta: float) -> State:
	direction = Input.get_vector("left", "right", "up", "down")
	if direction == Vector2.ZERO and not is_attacking:
		return idle_state
	elif direction and not is_attacking:
		return jog_state
	elif direction and Input.is_action_pressed("run") and not is_attacking:
		return sprint_state
		
	update_animation_parameter()
	return null


func _on_animation_tree_animation_finished(_anim_name: StringName) -> void:
	if is_attacking:
		is_attacking = false

An emitted signal will always be intercepted in the script its connected to as long as the script is running.

When you change state, the other states scripts are still running, the state machine just specifically choose which script it should call enter, process_input … On.

In summary, you need to disconnect the signal on state exit and reconnect it on entry for every state animation_tree_animation_finished is connected to.
Or you can check if the current state that intercepted the signal is the current state then proceed with doing whatever you want to do.