public void Attack()
 {
     // If the attack is triggered, make sure that the grace period is set back to false since it is used.
     moIn.attackButtonActions.attackButtonTapInGrace = false;
     // Checks and adjusts the current attack chain. (Chaining attacks)
     atkChain.ChainAttacks();
     // Disallow weapon swapping.
     equippedWeapons.canSwapWeapon = false;
     // Stop the previous motion if needed.
     StopPreviousMotion();
     // Set the weapon back to its resting position and rotation. Usually the first attack chain's resting values.
     ResetWeaponLocalValues();
     // Allow character flip and the weapon to "look at" the mouse.
     ForceCharFlipAndWeaponLookAt();
     // If I want to check the weapon motion every attack. (attack chains can have different motions ex; stab, slash)
     //curWeaponMotion = weaponMotionController.CheckMotionList(weaponMotion);
     curWeaponMotion = weaponMotions[atkChain.curChain];
     // Start the attack.
     curWeaponMotion.WeaponMotionSetup(this, weaponTrans, weaponSpriteR);
     // Handles moving the player, slowing him down, etc., during the attack. (Player motion)
     atkPlyrMove.SetupPlayerAttackMotions(WeapAtkChain.sO_CharAtk_Motion);
     // Clear the character_attackFX list.
     atkFXsInUse.Clear();
     // Activate all this attack's FX's.
     foreach (SO_AttackFX sO_AttackFX in ChainAttackFXs)
     {
         // Request an attack FX from the attack FX pool, the attack FX contains a Sprite Renderer and a PolygonalCollider2D.
         atkFX = atkFXPool.RequestAttackFX();
         // Flip the attack FX Sprite if needed. (So far, for alternating Slash motions)
         // if (atkDirectionChanges) { atkFX.spriteR.flipX = atkFXFlip; } else { atkFX.spriteR.flipX = false; }
         // Try flipping the attack fx's local x scale instead.
         if (atkDirectionChanges)
         {
             atkFXFlipScale             = (atkFXFlip) ? -1 : 1;
             atkFX.transform.localScale = new Vector2(atkFXFlipScale, atkFX.transform.localScale.y);
         }
         else
         {
             atkFX.transform.localScale = new Vector2(1, atkFX.transform.localScale.y);
         }
         // The gameObject needs to be turned on before starting the coroutine on it.
         atkFX.gameObject.SetActive(true);
         // Moves the attack effect over the course of the attack.
         atkFX.StartCoroutine(atkMovement.AttackMovement(sO_AttackFX, atkFX.transform));
         // Enables and changes the attack effect over the course of the attack and dictates if the atkFX pool object is inUse then not.
         // Start the coroutine ON the pool object script, not the script holding the coroutine logic.
         atkFX.StartCoroutine(atkVisual.AttackAnimation(sO_AttackFX, atkFX, atkFollowPlayerOrientation));
         // Enables and disables the attack's collider during the "animation" and detects colliders it can hit, once, if it has one assigned.
         // Requires the sOWeapon because durability damage is general, if it was attack chain specific then just having the weaponAttackChain would be sufficient as it would hold the durability damage info.
         //print("Weapon one is active on attack trigger: "+equippedWeapons.weaponOneIsActive);
         if (sO_AttackFX.collider != null)
         {
             atkDetection.StartCoroutine(atkDetection.AttackCollider(equippedWeapons.weaponOneIsActive, weapon, WeapAtkChain, sO_AttackFX, atkFX.col, weaponOriginTrans));
         }
         // Turn the atk direction change back to false. This is done at the end because colliders will also be flipped by checking this variable. Now flipping the attack FX pool object's x scale instead of just the sprite.
         atkDirectionChanges        = false;
         atkFollowPlayerOrientation = false;
         // Player sripte to idle and stop animations
         // charMov.mySpriteAnim.Stop();
         // charMov.spriteRend.sprite = charMov.idleSprite;
         // Add the character_attackFXs used to a list to better keep track of them.
         atkFXsInUse.Add(atkFX);
     }
 }