/// <summary>
    /// Performs the action of the attacker against their targets.
    /// </summary>
    /// <returns>The action.</returns>
    /// <param name="attacker">Attacker.</param>
    protected IEnumerator PerformAbilityAction(Unit attacker)
    {
        if (attacker.Action.Item != null)
        {
            // Lower music so you can hear ability SFX
            yield return(StartCoroutine(controller.MusicController.LowerCombatMusic()));

            // Show name of ability being used
            attacker.TileHighlighter.RemoveHighlightedTiles();
            Item item = attacker.Action.Item;
            controller.ActionController.Activate(item.Name);
            yield return(new WaitForSeconds(0.5f));

            // Spawn VFX on all targets
            List <Unit>       targets        = attacker.Action.Targets;
            List <GameObject> vfxGameObjects = ApplyVFXToTargets(item.VFXPath, targets);

            // Iterate over all effects, apply them, and if there is something to display, show it
            PopupTextController.Initialize(attacker.GetCanvas());
            List <Effect> effects = ConsumableEffectCalculator.GetConsumableEffects(item);
            yield return(StartCoroutine(ApplyEffects(targets, effects)));

            attacker.UpdateHealthbar();

            // Show XP floaty text
            ShowXPFloatyText(new ExperienceManager().AwardConsumableExperience(attacker), attacker);
            yield return(new WaitForSeconds(1.0f));

            // Destroy VFX's
            DestroyVFX(vfxGameObjects);

            // Remove name of used ability
            controller.ActionController.Deactivate();

            // Bring music back up to normal volume
            yield return(StartCoroutine(controller.MusicController.RaiseCombatMusic()));

            controller.ChangeState <TurnOverState> ();
        }
        // If the ability takes more than x turns, defer the ability action
        else if (!attacker.HasDeferredAbility && attacker.Action.Ability.Turns > 1)
        {
            attacker.HasDeferredAbility = true;
            yield return(null);

            controller.ChangeState <TurnOverState> ();
        }
        else
        {
            // Reset bool flags depending on if a deferred attack is being executed
            if (attacker.HasDeferredAbility)
            {
                attacker.HasDeferredAbility         = false;
                attacker.HasExecutedDeferredAbility = true;
            }

            // Lower music so you can hear ability SFX
            yield return(StartCoroutine(controller.MusicController.LowerCombatMusic()));

            // Show name of ability being used
            attacker.TileHighlighter.RemoveHighlightedTiles();
            Ability ability = attacker.Action.Ability;
            controller.ActionController.Activate(ability.Name);
            yield return(new WaitForSeconds(0.5f));

            // Spawn VFX on all targets
            List <Unit>       targets        = attacker.Action.Targets;
            List <GameObject> vfxGameObjects = ApplyVFXToTargets(ability.VFXPath, targets);

            // Start Combat
            Combat combat = new Combat(controller.HighlightedUnit);
            combat.Begin();

            // Play weapon sound effect
            Ability.AbilityType abilityType = attacker.Action.Ability.Type;
            if (abilityType == Ability.AbilityType.ATTACK || abilityType == Ability.AbilityType.TALENT)
            {
                attacker.PlayWeaponSound();
            }

            // Show target(s) being damaged
            ShowDamagedColorOnTargets(true, targets);

            // Play animations
            yield return(StartCoroutine(PlayAttackAnimations(attacker, targets [0].Tile)));

            // Iterate over all effects, apply them, and if there is something to display, show it
            PopupTextController.Initialize(attacker.GetCanvas());
            yield return(StartCoroutine(ApplyEffectsByUnit(attacker.Action.GetEffectsByUnit())));

            yield return(new WaitForSeconds(1.0f));

            // Stop showing target(s) being damaged
            ShowDamagedColorOnTargets(false, targets);

            // Show XP floaty text
            ShowXPFloatyText(combat.GetAwardedExperience(), attacker);
            yield return(new WaitForSeconds(1.0f));

            // Destroy VFX's
            DestroyVFX(vfxGameObjects);

            // Remove name of used ability
            controller.ActionController.Deactivate();

            // Bring music back up to normal volume
            yield return(StartCoroutine(controller.MusicController.RaiseCombatMusic()));

            controller.ChangeState <TurnOverState> ();
        }
    }