Search Unity

Running into problems with booleans and coroutines...

Discussion in 'Scripting' started by BoopitySchmooples, Jun 21, 2016.

  1. BoopitySchmooples

    BoopitySchmooples

    Joined:
    Jun 20, 2016
    Posts:
    20
    I am attempting to have the following behavior on my player character:

    • Gravity acting on the character (void ApplyGravity on line 69) when the player is not slashing/dashing (monitored with a boolean for slashing.
    • When the player presses the left mouse button, the character dashes at the designated target (coroutine Slash on line 111) with gravity being turned off (boolean disables gravity if the character is slashing on line 71)
    • Once the character has reached the target, the slash/dash coroutine is complete, and gravity returns.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class TP_Motor : MonoBehaviour
    5. {
    6.     public static TP_Motor Instance;
    7.  
    8.     public LayerMask collisionMask;
    9.  
    10.     public float MoveSpeed = 10f;
    11.     public float JumpSpeed = 6f;
    12.     public float Gravity = 21f;
    13.     public float TerminalVelocity = 20f;
    14.     public float SlideThreshold = 0.6f;
    15.     public float WalkableAngle = 0.6f;
    16.     public float MaxControllableSlideMagnitude = 0.4f;
    17.     public float rotSpeed = 800;
    18.     public float slashSpeed = 10f;
    19.  
    20.     private Vector3 slideDirection;
    21.     private Vector3 turnRotation;
    22.     private Vector3 slashDirection;
    23.     private Vector3 target;
    24.  
    25.     public Vector3 MoveVector { get; set; }
    26.     public float VerticalVelocity { get; set; }
    27.  
    28.     bool slash;
    29.  
    30.     void Awake ()
    31.     {
    32.         Instance = this;
    33.     }
    34.  
    35.     public void UpdateMotor ()
    36.     {
    37.         //SnapAlignCharacterWithCamera ();
    38.  
    39.         SnapAlignCharacterWithMoveDirection();
    40.  
    41.         ProcessMotion ();
    42.     }
    43.  
    44.     void ProcessMotion()
    45.     {
    46.         // Transform MoveVector to World Space
    47.         MoveVector = Camera.main.transform.TransformDirection (MoveVector);
    48.  
    49.         // Normalize MoveVector if Magnitude > 1
    50.         if (MoveVector.magnitude > 1)
    51.             MoveVector = Vector3.Normalize (MoveVector);
    52.  
    53.         // Apply sliding if applicable. THIS SYSTEM IS S*** AND NEEDS TO BE REPLACED!
    54.         ApplySlide();
    55.  
    56.         // Multiply MoveVector by MoveSpeed
    57.         MoveVector *= MoveSpeed;
    58.  
    59.         // Reapply VerticalVelocity MoveVector.y
    60.         MoveVector = new Vector3 (MoveVector.x, VerticalVelocity, MoveVector.z);
    61.  
    62.         // Apply gravity
    63.         ApplyGravity();
    64.  
    65.         // Move the Character in World Space
    66.         TP_Controller.CharacterController.Move(MoveVector* Time.deltaTime);
    67.     }
    68.  
    69.     void ApplyGravity()
    70.     {
    71.         if (slash != true)
    72.         {
    73.             if (MoveVector.y > -TerminalVelocity)
    74.                 MoveVector = new Vector3 (MoveVector.x, MoveVector.y - Gravity * Time.deltaTime, MoveVector.z);
    75.  
    76.             if (TP_Controller.CharacterController.isGrounded && MoveVector.y < -1)
    77.                 MoveVector = new Vector3 (MoveVector.x, -3.5f, MoveVector.z);
    78.         }
    79.     }
    80.  
    81.     void ApplySlide()
    82.     {
    83.         if (!TP_Controller.CharacterController.isGrounded)
    84.             return;
    85.  
    86.         slideDirection = Vector3.zero;
    87.  
    88.         RaycastHit hitInfo;
    89.  
    90.         if (Physics.Raycast (transform.position, Vector3.down, out hitInfo))
    91.         {
    92.             if (hitInfo.normal.y < SlideThreshold)
    93.                 slideDirection = new Vector3 (hitInfo.normal.x, -hitInfo.normal.y, hitInfo.normal.z);
    94.         }
    95.  
    96.         if (slideDirection.magnitude < MaxControllableSlideMagnitude)
    97.             MoveVector += slideDirection;
    98.         else
    99.         {
    100.             MoveVector = slideDirection;
    101.         }
    102.     }
    103.  
    104.     public void Jump()
    105.     {
    106.         if (TP_Controller.CharacterController.isGrounded)
    107.            
    108.             VerticalVelocity = JumpSpeed;
    109.     }
    110.  
    111.     public IEnumerator Slash()
    112.     {
    113.         slash = true;
    114.  
    115.         target = new Vector3 (0, 20, 10);
    116.         float distance = Vector3.Distance (transform.position, target);
    117.  
    118.         while (distance > 0.05f)
    119.         {
    120.             transform.position = Vector3.Lerp (transform.position, target, slashSpeed * Time.deltaTime);
    121.  
    122.             yield return null;
    123.         }
    124.  
    125.         slash = false;
    126.         StopCoroutine (TP_Motor.Instance.Slash());
    127.     }
    128.  
    129.     void SnapAlignCharacterWithCamera()
    130.     {
    131.         if (MoveVector.x != 0 || MoveVector.z != 0)
    132.         {
    133.             transform.rotation = Quaternion.Euler(transform.eulerAngles.x,
    134.                                                     Camera.main.transform.eulerAngles.y,
    135.                                                     transform.eulerAngles.z);
    136.         }
    137.     }
    138.  
    139.     void SnapAlignCharacterWithMoveDirection()
    140.     {
    141.         turnRotation = new Vector3 (TP_Controller.CharacterController.velocity.x, 0, TP_Controller.CharacterController.velocity.z);
    142.  
    143.         if (MoveVector.x != 0 || MoveVector.z != 0)
    144.         {
    145.             transform.rotation = Quaternion.LookRotation (turnRotation, Vector3.up);
    146.         }
    147.     }
    148. }
    149.  
    And here is the code where these functions are being called:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class TP_Controller : MonoBehaviour
    5. {
    6.     public static CharacterController CharacterController;
    7.     public static TP_Controller Instance;
    8.  
    9.     void Awake ()
    10.     {
    11.         CharacterController = GetComponent ("CharacterController") as CharacterController;
    12.         Instance = this;
    13.         TP_Camera.UseExistingOrCreateNewMainCamera ();
    14.     }
    15.  
    16.     void Update ()
    17.     {
    18.         if (Camera.main == null)
    19.             return;
    20.  
    21.         GetLocomotionInput ();
    22.  
    23.         HandleActionInput ();
    24.  
    25.         TP_Motor.Instance.UpdateMotor ();
    26.     }
    27.  
    28.     void GetLocomotionInput()
    29.     {
    30.         var deadZone = 0.1f;
    31.  
    32.         TP_Motor.Instance.VerticalVelocity = TP_Motor.Instance.MoveVector.y;
    33.         TP_Motor.Instance.MoveVector = Vector3.zero;
    34.  
    35.         if (Input.GetAxis ("Vertical") > deadZone || Input.GetAxis ("Vertical") < -deadZone)
    36.             TP_Motor.Instance.MoveVector += new Vector3 (0, 0, Input.GetAxis("Vertical"));
    37.  
    38.         if (Input.GetAxis ("Horizontal") > deadZone || Input.GetAxis ("Horizontal") < -deadZone)
    39.             TP_Motor.Instance.MoveVector += new Vector3 (Input.GetAxis("Horizontal"), 0, 0);
    40.     }
    41.  
    42.     void HandleActionInput()
    43.     {
    44.         if (Input.GetButtonDown ("Jump"))
    45.         {
    46.             Jump ();
    47.         }
    48.  
    49.         if (Input.GetButtonDown ("Fire1"))
    50.         {
    51.             StartCoroutine(TP_Motor.Instance.Slash());
    52.         }
    53.  
    54.     }
    55.  
    56.     void Jump()
    57.     {
    58.         TP_Motor.Instance.Jump();
    59.     }
    60.  
    61.     void Slash ()
    62.     {
    63.         TP_Motor.Instance.Slash();
    64.     }
    65. }
    The behavior I'm getting is a bit confusing. My character successfully dashes upwards towards the target, but doesn't reach it until I click a few more times. It seems that gravity might still be acting on the character during my coroutine when I am intended to cancel it altogether? Additionally, when my character reaches the target, it doesn't seems to exit the coroutine upon completion, remaining stuck in midair. It seems I'm missing some vital information regarding how my booleans and or coroutine are functioning.

    Thanks in advance for the help.
     
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You need to not start the coroutine at all when slash is true. As it stands now, every time you hit the Fire1 button you start a new Slash coroutine. So if you made slash a public boolean instead you'd do something like
    Code (csharp):
    1.  
    2. if (!TP_Motor.Instance.Slash && Input.GetButtonDown("Fire1"))
    3. {
    4.     StartCoroutine(TP_Motor.Instance.Slash());
    5. }
    6.  
    That being said - I'd rather have the motor handle everything itself. So I'd expose a void method and fire off the coroutine from there
    Code (csharp):
    1.  
    2. if (Input.GetButtonDown("Fire1"))
    3.     TP_Motor.Instance.Slash(this);
    4.  
    Code (csharp):
    1.  
    2. public void Slash(TP_Controller ctrl)
    3. {
    4.     if (!slash)
    5.         ctrl.StartCoroutine(DoSlash());
    6. }
    7.  
    8. IEnumerator DoSlash()
    9. {
    10.     slash = true;
    11.     // your slash stuff
    12.     slash = false;
    13. }
    14.  
     
  3. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    You also seem to have an infinite while loop inside your coroutine, which would be why you never see the coroutine turn off.

    Here's your code:
    Code (CSharp):
    1. float distance = Vector3.Distance (transform.position, target);
    2.  
    3. while (distance > 0.05f)
    4. {
    5.     transform.position = Vector3.Lerp (transform.position, target, slashSpeed * Time.deltaTime);
    6.     yield return null;
    7. }
    You're setting the "distance" variable to the slash distance before you start slashing, but then you never update that variable. You must recalculate the distance inside your while loop or it will always be the same number.
     
  4. sdviosx

    sdviosx

    Joined:
    Jan 4, 2015
    Posts:
    22
    Here are some side notes.
    In line 59 use sqr.magnitude its less expensive.
    Code (CSharp):
    1. if (MoveVector.magnitude > 1)
    2. //..
    Be careful when overcalling StartCoroutine(), unity implicitly allocates unity's Coroutine and an Enumerator. Where possible, limit your StartCoroutine() calls to avoid memory leaks.

    Also some might argue that Vector*.Distance is slow.
     
  5. BoopitySchmooples

    BoopitySchmooples

    Joined:
    Jun 20, 2016
    Posts:
    20
    Thanks for the help guys. If I don't initially implement your suggested changes, don't take that as me ignoring you, but rather me taking things on one piece at a time.

    So I've successfully barred starting the coroutine while slash is true as Kelso suggested.

    Additionally, I've (sort of) fixed the infinite loop that Gambit pointed out.

    Code (CSharp):
    1. public IEnumerator Slash()
    2.     {
    3.         slash = true;
    4.  
    5.         target = new Vector3 (0, 20, 10);
    6.         float distance = Vector3.Distance (transform.position, target);
    7.  
    8.         while (distance > 0.05f)
    9.         {
    10.             transform.position = Vector3.Lerp (transform.position, target, slashSpeed * Time.deltaTime);
    11.             distance = Vector3.Distance (transform.position, target);
    12.             yield return null;
    13.         }
    14.         slash = false;
    15.         print ("Slash is now finished.");
    16.     }
    The interesting thing is that, if I remove "* Time.deltaTime" in the transform, the character teleports to the target and gravity returns as desired. When I include "* Time.deltaTime" as desired, however, the character travels to the target location but it remains stuck after reaching the position and gravity never returns. The infinite while loop seems to be fixed, but perhaps this is a new, unrelated issue? I find it curious that the speed at which the character lerps doesn't change even if I change slashSpeed from 1 to 100... Again thanks for the patience and help.
     
  6. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    You definitely want Time.deltaTime there... but for some reason you must still be stuck inside the loop. Try running the game again and allow the character to get stuck, then go to your code and put a breakpoint on the "yield return null" line. With the debugger paused inside the coroutine, you'll be able to check what the distance is and see why "distance > 0.05f" keeps returning true.
     
  7. BoopitySchmooples

    BoopitySchmooples

    Joined:
    Jun 20, 2016
    Posts:
    20
    So I ran a debug that read me the distance, and something I'm doing in void ApplyGravity seems to be causing the issue. When I was running this if statement on line 71:

    Code (CSharp):
    1.  
    2.         if (slash != true)
    3.  
    the character controller would never get within 0.05 range of the target. It would get close, but just subtly hover outside of the range. I then changed the above if statement to the following:

    Code (CSharp):
    1.  
    2.         if (slash = false)
    3.  
    Now, the character DOES reach the destination (after a second or two) and the coroutine ends, BUT gravity does not return. I know that when my coroutine ends, my "slash" bool is then set to false, because I'm printing a line to the console indicating so, but gravity still does not return. Revised code for reference: (Slash coroutine on 111, gravity on 69).

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class TP_Motor : MonoBehaviour
    5. {
    6.     public static TP_Motor Instance;
    7.  
    8.     public LayerMask collisionMask;
    9.  
    10.     public float MoveSpeed = 10f;
    11.     public float JumpSpeed = 6f;
    12.     public float Gravity = 21f;
    13.     public float TerminalVelocity = 20f;
    14.     public float SlideThreshold = 0.6f;
    15.     public float WalkableAngle = 0.6f;
    16.     public float MaxControllableSlideMagnitude = 0.4f;
    17.     public float rotSpeed = 800;
    18.     public float slashSpeed = 1f;
    19.  
    20.     private Vector3 slideDirection;
    21.     private Vector3 turnRotation;
    22.     private Vector3 slashDirection;
    23.     private Vector3 target;
    24.  
    25.     public Vector3 MoveVector { get; set; }
    26.     public float VerticalVelocity { get; set; }
    27.  
    28.     public bool slash;
    29.  
    30.     void Awake ()
    31.     {
    32.         Instance = this;
    33.     }
    34.  
    35.     public void UpdateMotor ()
    36.     {
    37.         //SnapAlignCharacterWithCamera ();
    38.  
    39.         SnapAlignCharacterWithMoveDirection();
    40.  
    41.         ProcessMotion ();
    42.     }
    43.  
    44.     void ProcessMotion()
    45.     {
    46.         // Transform MoveVector to World Space
    47.         MoveVector = Camera.main.transform.TransformDirection (MoveVector);
    48.  
    49.         // Normalize MoveVector if Magnitude > 1
    50.         if (MoveVector.magnitude > 1)
    51.             MoveVector = Vector3.Normalize (MoveVector);
    52.  
    53.         // Apply sliding if applicable. THIS SYSTEM IS S*** AND NEEDS TO BE REPLACED!
    54.         ApplySlide();
    55.  
    56.         // Multiply MoveVector by MoveSpeed
    57.         MoveVector *= MoveSpeed;
    58.  
    59.         // Reapply VerticalVelocity MoveVector.y
    60.         MoveVector = new Vector3 (MoveVector.x, VerticalVelocity, MoveVector.z);
    61.  
    62.         // Apply gravity
    63.         ApplyGravity();
    64.  
    65.         // Move the Character in World Space
    66.         TP_Controller.CharacterController.Move(MoveVector* Time.deltaTime);
    67.     }
    68.  
    69.     void ApplyGravity()
    70.     {
    71.         if (slash = false)
    72.         {
    73.             if (MoveVector.y > -TerminalVelocity)
    74.                 MoveVector = new Vector3 (MoveVector.x, MoveVector.y - Gravity * Time.deltaTime, MoveVector.z);
    75.  
    76.             if (TP_Controller.CharacterController.isGrounded && MoveVector.y < -1)
    77.                 MoveVector = new Vector3 (MoveVector.x, -3.5f, MoveVector.z);
    78.         }
    79.     }
    80.  
    81.     void ApplySlide()
    82.     {
    83.         if (!TP_Controller.CharacterController.isGrounded)
    84.             return;
    85.  
    86.         slideDirection = Vector3.zero;
    87.  
    88.         RaycastHit hitInfo;
    89.  
    90.         if (Physics.Raycast (transform.position, Vector3.down, out hitInfo))
    91.         {
    92.             if (hitInfo.normal.y < SlideThreshold)
    93.                 slideDirection = new Vector3 (hitInfo.normal.x, -hitInfo.normal.y, hitInfo.normal.z);
    94.         }
    95.  
    96.         if (slideDirection.magnitude < MaxControllableSlideMagnitude)
    97.             MoveVector += slideDirection;
    98.         else
    99.         {
    100.             MoveVector = slideDirection;
    101.         }
    102.     }
    103.  
    104.     public void Jump()
    105.     {
    106.         if (TP_Controller.CharacterController.isGrounded)
    107.            
    108.             VerticalVelocity = JumpSpeed;
    109.     }
    110.  
    111.     public IEnumerator Slash()
    112.     {
    113.         slash = true;
    114.  
    115.         target = new Vector3 (0, 20, 10);
    116.         float distance = Vector3.Distance (transform.position, target);
    117.  
    118.         while (distance > 0.05f)
    119.         {
    120.             transform.position = Vector3.Lerp (transform.position, target, slashSpeed * Time.deltaTime);
    121.             distance = Vector3.Distance (transform.position, target);
    122.             Debug.Log (distance);
    123.             yield return null;
    124.         }
    125.         slash = false;
    126.         print ("Slash is now finished.");
    127.     }
    128.  
    129.     void SnapAlignCharacterWithCamera()
    130.     {
    131.         if (MoveVector.x != 0 || MoveVector.z != 0)
    132.         {
    133.             transform.rotation = Quaternion.Euler(transform.eulerAngles.x,
    134.                                                     Camera.main.transform.eulerAngles.y,
    135.                                                     transform.eulerAngles.z);
    136.         }
    137.     }
    138.  
    139.     void SnapAlignCharacterWithMoveDirection()
    140.     {
    141.         turnRotation = new Vector3 (TP_Controller.CharacterController.velocity.x, 0, TP_Controller.CharacterController.velocity.z);
    142.  
    143.         if (MoveVector.x != 0 || MoveVector.z != 0)
    144.         {
    145.             transform.rotation = Quaternion.LookRotation (turnRotation, Vector3.up);
    146.         }
    147.     }
    148. }
    149.  
     
  8. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    Careful with those single equals signs... that is literally setting your "slash" variable to false inside the if, and that if will never return true.

    EDIT: sorry, I had one more idea here I removed because I realized it wouldn't work. Maybe check against a value a little larger than 0.05f?
     
  9. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    Actually, maybe try: "while (distance > slashSpeed *Time.deltaTime)"
     
  10. BoopitySchmooples

    BoopitySchmooples

    Joined:
    Jun 20, 2016
    Posts:
    20
    I've tried both of your suggestions and for some bizarre reason, the character will lerp to roughly 3.5 units underneath the target and just hover there, never reaching it. It's almost like there's a force of gravity acting upon it or something. I don't see why gravity would be applying considering the coroutine sets my slash bool to true while executing and does not finish executing... My gravity function:

    Code (CSharp):
    1. void ApplyGravity()
    2.     {
    3.         if (slash != true)
    4.         {
    5.             if (MoveVector.y > -TerminalVelocity)
    6.                 MoveVector = new Vector3 (MoveVector.x, MoveVector.y - Gravity * Time.deltaTime, MoveVector.z);
    7.  
    8.             if (TP_Controller.CharacterController.isGrounded && MoveVector.y < -1)
    9.                 MoveVector = new Vector3 (MoveVector.x, -3.5f, MoveVector.z);
    10.         }
    11.     }
    EDIT: Okay, I just discovered that

    Code (CSharp):
    1. MoveVector = new Vector3 (MoveVector.x, -3.5f, MoveVector.z);
    is being applied while the coroutine is executing, which is preventing the player from reaching the target...I'll see if I can figure out a solution.
     
    Last edited: Jun 22, 2016
  11. BoopitySchmooples

    BoopitySchmooples

    Joined:
    Jun 20, 2016
    Posts:
    20
    Alright, I'm at a loss as to why gravity is being applied to my character controller. I've tried different syntax and am getting the same result. Despite the character not being grounded and slash being set to true, line 7 (or 75 in the entire code) of my gravity function is being executed.

    Code (CSharp):
    1. void ApplyGravity()
    2.     {
    3.             if (MoveVector.y > -TerminalVelocity && slash != true)
    4.                 MoveVector = new Vector3 (MoveVector.x, MoveVector.y - Gravity * Time.deltaTime, MoveVector.z);
    5.  
    6.             if (TP_Controller.CharacterController.isGrounded && MoveVector.y < -1 && slash != true)
    7.                 MoveVector = new Vector3 (MoveVector.x, -3.5f, MoveVector.z);
    8.     }
    And then the aspect of this that messes with my brain, is that, if I start the character above instead of below the target, the character will lerp correctly to the x and z coordinates but will remain above the target, seemingly indifferent to gravity... I'm incredibly confused.
     
    Last edited: Jun 22, 2016
  12. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    If you feel using coroutine is becoming too complicated to manage, you might be interested into Behaviour Tree as alternative. It's an appropriate tool to descibre complex behaviour over several frames.

    Have a look at Panda BT. Using this framework the BT controlling your slash attack would be:
    Code (CSharp):
    1. tree("SlashAttack")
    2.     sequence
    3.         IsAttackButtonPressed
    4.         SetGravity(false)
    5.         DoSlash
    6.         SetGravity(true)
    7.  
     
  13. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    I just did, and it looks really nice! A unique take on how to author behavior trees.

    Added to wish list.
     
  14. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Found one of your problems:

    You're never going to get to the target! Check out the "lerp like a pro" link in my sig, it's a better explanation of what you're doing wrong that anything I could ever write.
     
    Last edited: Jun 22, 2016
  15. BoopitySchmooples

    BoopitySchmooples

    Joined:
    Jun 20, 2016
    Posts:
    20
    Thanks guys. I'll give those behavior trees a look and read over the links you provided, Baste. My understanding of lerping and looping could be improved for sure.
     
  16. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    There is a free edition ;).

    @Papa Justice and @shaderop, if you have any question about Panda BT, I'd be glad to help. You're welcome on this thread.

    What you want to do is not lerping but "tweening" (which is basically lerping over time). I like to use DOTween for that. It does the job really well and in a simple way. Using DOTween, your slash animation could be done this way:
    Code (CSharp):
    1. transform.DOMove(target, slashDuration);
    (I am not affiliated with DOTween, I just like this tool).
     
    Last edited: Jun 22, 2016
  17. BoopitySchmooples

    BoopitySchmooples

    Joined:
    Jun 20, 2016
    Posts:
    20
    A little late, but I wanted to post my updated Slash coroutine code with the issue fixed. Thanks, Baste, that "Lerping Like a Pro" link cleared things up quite a bit. Thanks again for the help, everyone.

    Code (CSharp):
    1. public IEnumerator Slash()
    2.     {
    3.         slash = true;
    4.  
    5.         //endPos = new Vector3 (0, 20, 10);
    6.         float distance = Vector3.Distance (transform.position, endPos);
    7.         currentLerpTime = 0f;
    8.         lerpTime = 0.65f;
    9.  
    10.         Ray dashLine = new Ray(transform.position, Camera.main.transform.forward);
    11.         endPos = dashLine.GetPoint (30);
    12.  
    13.         while (distance > 0.1f)
    14.         {
    15.             currentLerpTime += Time.deltaTime;
    16.             if (currentLerpTime > lerpTime)
    17.             {
    18.                 currentLerpTime = lerpTime;
    19.             }
    20.  
    21.             float perc = currentLerpTime / lerpTime;
    22.  
    23.             transform.position = Vector3.Lerp (transform.position, endPos, perc);
    24.             distance = Vector3.Distance (transform.position, endPos);
    25.             Debug.Log (dashLine.GetPoint(10));
    26.             yield return null;
    27.         }
    28.    
    29.         slash = false;
    30.         //print ("Slash is now finished.");
    31.     }
     
  18. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    You could simplify your coroutine by considering not the distance but the lerpTime in the stop condition of the while loop:
    Code (CSharp):
    1. public IEnumerator Slash()
    2.     {
    3.         slash = true;
    4.         currentLerpTime = 0f;
    5.         lerpTime = 0.65f;
    6.         Ray dashLine = new Ray(transform.position, Camera.main.transform.forward);
    7.         endPos = dashLine.GetPoint (30);
    8.         while (currentLerpTime < lerpTime)
    9.         {
    10.             currentLerpTime += Time.deltaTime;
    11.             float perc = currentLerpTime / lerpTime;
    12.             transform.position = Vector3.Lerp (transform.position, endPos, perc);
    13.             yield return null;
    14.         }
    15.  
    16.         slash = false;
    17.         //print ("Slash is now finished.");
    18.     }