IEnumerator AttackRoutine(float beforeDelay, float activeDuration, float endDelay,
                              SFXOneShot sfx, GameObject collisionObject, string animationName)
    {
        // start animation before hit, in case there's windup
        _playerAnimator.PlayAnimation(animationName);
        MeleeAttackState = MeleeAttackState.BeforeAttack;
        yield return(new WaitForSeconds(beforeDelay));

        MeleeAttackState = MeleeAttackState.DuringAttack;
        AttackActivated?.Invoke(EquippedWeapon);
        //TODO: check/deal damage here
        CurrentWeaponCollision.SetActive(true);
        //_weaponAnimator.Play(animationName);
        sfx.PlayOneShot(transform.position);
        yield return(new WaitForSeconds(activeDuration));

        CurrentWeaponCollision.SetActive(false);
        AttackDeactivated?.Invoke();

        MeleeAttackState = MeleeAttackState.AfterAttack;
        //_weaponAnimator.Stop();
        //TODO: this could be a window for followup/combo attacks
        yield return(new WaitForSeconds(endDelay));

        MeleeAttackState = MeleeAttackState.NotAttacking;
        AttackCompleted?.Invoke();
    }
    public virtual void StopAttack()
    {
        if (_attackRoutine != null)
        {
            StopCoroutine(_attackRoutine);
        }

        CurrentWeaponCollision.SetActive(false);
        //_weaponAnimator.Stop();
        MeleeAttackState = MeleeAttackState.NotAttacking;
    }