Variable sets itself to false on every frame for some reason

I have spent more hours than I care to admit on this problem. Sigh.
I have this script attached to my root node (CharacterBody2D):

public partial class Player : CharacterBody2D
{
    [Export]
    public bool isAttacking = false;
    [Export]
    public bool hasQueuedAttack = false;
    // more stuff
}

And I have this method in a child node which is a Node2D called InputController:

public override void _Input(InputEvent @event)
{
	if (Input.IsActionPressed("Attack") && player.Can("Attack"))
	{
		if (player.isAttacking)
		{
			player.hasQueuedAttack = true;
		}
		else
		{
			player.isAttacking = true;
		}

		return;
	}
        // More stuff
}

I am running GD.Print(player.hasQueuedAttack) at the end of every call of _PhysicsProcess to see what’s happening, and I noticed that it becomes true on the frame where I press attack, but then it becomes false on the frame immediately after.
I swear to god this is the only place where hasQueuedAttack is being written (besides being initialized as false in the Player class), as shown in the picture attached:


I am using a state machine, but it only sets hasQueuedAttack in the RESET node, and the variable is being set to false long before that.
If you’re wondering about the player.Can method, here it is:

	public bool Can(string action)
	{
		if (isImpaired)
		{
			return false;
		}

		bool isAble = action switch
		{
			"Attack" => !isParrying && !isJumping && !isCasting && !isDashing,
			"Parry" => !isAttacking && !isJumping && !isCasting && !isDashing,
			"Jump" => !isAttacking && !isParrying && !isCasting && !isJumping && !isDashing,
			"Cast" => !isAttacking && !isParrying && !isJumping && !isDashing && !spellsAreOnCooldown,
			"Move" => !isAttacking && !isParrying && !isCasting && !isDashing,
			"Dash" => !isAttacking && !isParrying && !isCasting && !isDashing,
			_ => false
		};

		return action == "Move" ? isAble : isAble && IsOnFloor();
	}

I am out of ideas. I have triple checked everything and tried many things, nothing worked. At this point I desperately need an input (no pun intended).
Thanks in advance.

Hi,

I see that in Player.tscn, you have these info twice.

Are you sure that you don’t have two instances of the same script, that could interfere with each other? What I mean is, maybe the “false” print is coming from another instance of the script. Sounds like a very wild guess, but you seem to have checked the basic things, so why not haha.

1 Like

It appears twice because my state machine goes like this:
Idle transitions into Attacking1 when isAttacking becomes true, Attacking1 transitions to Attacking2 if hasQueuedAttack is true (priority 0), otherwise it transitions to AttackRecovery (priority 1), then Attacking2 transitions to either AttackRecovery or Attacking1 the same way

Looks like you have one or two animations that have a track pointing to that variable, make sure that you aren’t setting it to false in the animations.

1 Like

The way I tracked this in the past was instead of using a boolean, I just queried what animation was playing when the attack button was hit. If it’s attack 1 transition to 2 at the end, otherwise to 1.