'Action Cool Down behavior using coroutine not working

I have a character with a punch animation triggered when I press the space bar. I'm trying to make it so that the player can only punch 3 times before entering a 4 second cool down, but the player is still able to punch more than 3 times in rapid succession without any cool down. I've even made my state variables public so that I can observe them in the editor, and they behave as expected. What am I getting wrong here?

public int PunchCount;
public bool CanPunch;
public float waitCount;

protected Animator animator;

void Start()
{
    animator = GetComponent<Animator>();
    CanPunch = true;
}

void Update()
{
    if (Input.GetKey(KeyCode.Space))
    {
        DoPunch();
        return;
    }
}

void DoPunch()
{
    if (!CanPunch) return;
    CanPunch = false;

    PunchCount++;
    if (PunchCount > 3)
    {
        // cool down
        StartCoroutine("WaitSeconds", new Tuple<float, Action>(4.0f, () =>
        {
            PunchCount = 0;
            CanPunch = true;
        }));
        return;
    }

    animator.SetInteger("State", 3);
    StartCoroutine("WaitSeconds", new Tuple<float, Action>(1.3f, () =>
    {
        CanPunch = true;
    }));
}

IEnumerator WaitSeconds(object o)
{
    var t = o as Tuple<float, Action>;
    waitCount = t.Item1;
    Action a = t.Item2;

    yield return new WaitForSeconds(waitCount);
    a.Invoke();
}

In the inspector I can see PunchCount cycle between 0 and 4, and when it is 4, I can see waitCount change to 4 seconds and CanPunch becomes false, for 4 seconds, the CanPunch becomes true and PunchCount is reset to 0. When PunchCount is less than 4 I see the waitCount change to 1.3f, CanPunch becomes false for 1.3 seconds, then resets to true after the time is up. All of the variables are following the designed behavior, but the animator.SetInteger call seems to be called even though it absolutely should NOT be called when CanPunch is false. Is there some weird caching behaviour behind the scenes in the Unity Engine?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source