public void SetupPlayerAttackMotions(SO_CharAtk_Motion sOCharAtkMotion)
 {
     if (curSlow != 0f)
     {
         charMov.ReduceSpeed(-curSlow);
     }
     // Get references from the Scriptable Object.
     durations              = sOCharAtkMotion.durations;
     distances              = sOCharAtkMotion.distances;
     lockInputMovement      = sOCharAtkMotion.lockInputMovement;
     lockCharacterAndWeapon = sOCharAtkMotion.lockCharacterAndWeapon;
     slowDownRunSpeed       = sOCharAtkMotion.slowDownRunSpeed;
     //chargeAttack = sOCharAtkMotion.chargeAttack;
     loopMotions = sOCharAtkMotion.loopMotion;
     //loopFinalMotion = sOCharAtkMotion.loopFinalMotion;
     // Assign the current values for the first motion.
     // *Could run SetupNextMotionNow with a few changes?
     curMotion    = 0;
     curDistance  = distances[curMotion];
     curDuration  = durations[curMotion];
     curDirection = weapOrigTrans.up;
     curSpeed     = Mathf.Abs(curDistance / curDuration);
     if (curDistance < 0)
     {
         curDirection *= -1;
     }
     curPosition = weapOrigTrans.position;
     curSlow     = slowDownRunSpeed[curMotion];
     // Set initial locks and slowdown.
     // Locks the player movement input.
     if (lockInputMovement[curMotion])
     {
         charMov.StopInputMove();
     }
     else
     {
         charMov.canInputMove = true;
     }
     // This locks the character sprite flip and weapon rotation. (Can be seperated)
     if (lockCharacterAndWeapon[curMotion])
     {
         charMov.charCanFlip = false; weaponLookAt.lookAtEnabled = false;
     }
     else
     {
         charMov.charCanFlip = true; weaponLookAt.lookAtEnabled = true;
     }
     // Applies a slow to the player input movement speed.
     charMov.ReduceSpeed(curSlow);
     finalMotion      = false;
     exitPlayerMotion = false;
     moveTimer        = 0f;
     if (curMotion < loopMotions.Length - 1 && loopMotions[curMotion])
     {
         finalMotion = true;
     }
     this.StopAllCoroutines();
     charAtkMotionOn = true;
     this.StartCoroutine(CharAttackMotionTimer());
 }
    public void SpecialAttack()
    {
        charAtk.ReadyToAttack(false);
        mainSpecialSO = charAtk.weapon;

        SO_WindupFX[0] = mainSpecialSO.specialAttack.sO_AttackFXWindup[0];
        SO_HoldFX[0]   = mainSpecialSO.specialAttack.sO_AttackFXHold[0];
        //print(mainSpecialSO.specialAttack.sO_AttackFXRelease.Length);
        SO_ReleaseFX.Clear();
        for (int i = 0; i < mainSpecialSO.specialAttack.sO_AttackFXRelease.Length; i++)
        {
            //print("HELLO");
            if (i >= SO_ReleaseFX.Count)
            {
                SO_ReleaseFX.Add(mainSpecialSO.specialAttack.sO_AttackFXRelease[i]);
            }
            else
            {
                SO_ReleaseFX[i] = mainSpecialSO.specialAttack.sO_AttackFXRelease[i];
            }
        }

        SO_WindupCharMo = mainSpecialSO.specialAttack.sO_CharAtk_Motion;
        sOWeapoMo       = mainSpecialSO.specialAttack.sO_Weapon_Motion;

        // Perform the special 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;
        // Disallow weapon swapping.
        charAtk.equippedWeapons.canSwapWeapon = false;
        // Stop the previous motion if needed.
        charAtk.StopPreviousMotion();
        // Set the weapon back to its resting position and rotation. Usually the first attack chain's resting values.
        charAtk.ResetWeaponLocalValues();
        // Allow character flip and the weapon to "look at" the mouse.
        charAtk.ForceCharFlipAndWeaponLookAt();
        weaponMotion = charAtk.weaponMotionController.CheckMotionList(sOWeapoMo.weapon_Motion);
        //windupFX = null;
        //holdFX = null;
        //releaseFX = null;
        releaseFX.Clear();
        windupFX[0]       = charAtk.atkFXPool.RequestAttackFX();
        windupFX[0].inUse = true;
        holdFX[0]         = charAtk.atkFXPool.RequestAttackFX();
        holdFX[0].inUse   = true;
        for (int i = 0; i < SO_ReleaseFX.Count; i++)
        {
            if (i >= releaseFX.Count)
            {
                releaseFX.Add(charAtk.atkFXPool.RequestAttackFX());
            }
            else
            {
                releaseFX[i] = charAtk.atkFXPool.RequestAttackFX();
            }
            releaseFX[i].inUse = true;
        }

        if (specialAtkCoroutine != null)
        {
            specialAtkCoroutine = null;
        }
        specialAtkCoroutine = StartCoroutine(InSpecialAttack());
    }