private IEnumerator Attack(WeaponClass.AbilityIndex index)
        {
            if (currentAbilityIndex != index)
            {
                // NotificationSystem.Instance.Log("Ability Change. Resetting.");
                ResetAllCooldown();
                currentAbilityIndex = index;
            }

            if (abilities[(int)index].Length <= 0)
            {
                yield return(null);
            }

            if (combo >= abilities[(int)index].Length)
            {
                // NotificationSystem.Instance.Error("Combo out of bounds, resetting to safer state");
                ResetAllCooldown();
            }

            AbilityBase ability = abilities[(int)index][combo];

            if (ability == null)
            {
                yield return(null);
            }

            _uiManager.HudElements.SetAbilityUiCoolDown(index, ability.CoolDown);
            actionCoolDown = Time.time + ability.CoolDown;

            yield return(animator.PlayAttackAnimation(ability.AttackAnimationName));

            yield return(new WaitForSeconds(animator.GetAnimationLength));

            if (ability.IsProjectile)
            {
                if (ability.ProjectilePreFab == null)
                {
                    yield return(null);
                }

                GameObject projectileObj = Instantiate(ability.ProjectilePreFab, CombatUtils.GetAttackDirection(ability, transform, playerEntity.Stats.GetCenterPos, animator.CurrentDirection), quaternion.identity);

                if (!projectileObj.TryGetComponent(out ProjectileEntity projectile))
                {
                    yield return(null);
                }

                projectile.Direction = animator.CurrentDirection;
                projectile.Caster    = playerEntity;

                yield return(null);
            }

            // todo: allow for weapons to affect damage calculations.
            if (!ability.Execute(playerEntity, CombatUtils.GetHitList(ability, transform, playerEntity.Stats.GetCenterPos, animator.CurrentDirection)))
            {
                yield return(null);
            }

            combo++;
            if (combo >= abilities[(int)index].Length)
            {
                ResetCooldown(index);
            }

            comboCoolDown = Time.time + 5f;
            isComboActive = true;

            _uiManager.HudElements.SetAbilityUiComboIndex(index, combo);
        }