Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Coroutine Won't Yield

Discussion in 'Scripting' started by DRRosen3, Feb 21, 2015.

  1. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Pulling my hair out about this one. I have this code inside of a coroutine...

    Code (CSharp):
    1. Vector3 flatFwd = new Vector3(my_transform.forward.x, 0, my_transform.forward.z);
    2. Quaternion fwdRotation = Quaternion.LookRotation(flatFwd, Vector3.up);
    3. float angle = Quaternion.Angle(my_transform.rotation, fwdRotation);
    4. Debug.Log (angle);
    5. while(angle > 1.0f)
    6. {
    7.    my_transform.rotation = Quaternion.Slerp(my_transform.rotation, fwdRotation, Time.deltaTime * 2.0f);
    8.    angle = Quaternion.Angle(my_transform.rotation, fwdRotation);
    9.    yield return null;
    10. }
    ...but it won't yield there. It just goes right through it. What am I over-looking?
     
  2. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
  3. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Yep. Here's the majority of the code.

    Code (CSharp):
    1.  
    2.     private IEnumerator Capture(Collision col)
    3.     {
    4.         yield return StartCoroutine(Move(col));
    5.         rigidbody.WakeUp();
    6.         while(distance_to_ground > 0.2f)
    7.         {
    8.             yield return null;
    9.         }
    10.         rigidbody.isKinematic = true;
    11.         yield return StartCoroutine(Try(col));
    12.     }
    13.     private IEnumerator Move(Collision col)
    14.     {
    15.         Vector3 move_to = new Vector3(transform.position.x-1.5f, col.contacts[0].point.y+1.5f, transform.position.z-1.5f);
    16.         while(Vector3.Distance(transform.position, move_to) > 0.01f)
    17.         {
    18.             rigidbody.velocity = Vector3.zero;
    19.             rigidbody.angularVelocity = Vector3.zero;
    20.             rigidbody.Sleep();
    21.             transform.LookAt(col.transform.position);
    22.             transform.position = Vector3.Lerp(transform.position, move_to, 5f * Time.deltaTime);
    23.             yield return null;
    24.         }
    25.         animation["Open_Top"].speed = 5;
    26.         animation.Play("Open_Top");
    27.         GameObject orb = Instantiate(capture_orb_prefab, col.gameObject.GetComponentInChildren<Renderer>().renderer.bounds.center, Quaternion.identity) as GameObject;
    28.         col.gameObject.SetActive(false);
    29.         while(Vector3.Distance(my_transform.position, orb.transform.position) > 0.01f)
    30.         {
    31.             Vector3 orb_target = new Vector3(my_transform.position.x, my_transform.position.y, my_transform.position.z);
    32.             orb.transform.position = Vector3.Lerp(orb.transform.position, orb_target, 2.7f * Time.deltaTime);
    33.             yield return null;
    34.         }
    35.         orb.transform.parent = my_transform;
    36.         animation["Close_Top"].speed = -5f;
    37.         animation["Close_Top"].time = animation["Close_Top"].length;
    38.         animation.Play("Close_Top");
    39.         Vector3 flatFwd = new Vector3(my_transform.forward.x, 0, my_transform.forward.z);
    40.         Quaternion fwdRotation = Quaternion.LookRotation(flatFwd, Vector3.up);
    41.         float angle = Quaternion.Angle(my_transform.rotation, fwdRotation);
    42.         while(angle > 1.0f)
    43.         {
    44.             my_transform.rotation = Quaternion.Slerp(my_transform.rotation, fwdRotation, Time.deltaTime * 2.0f);
    45.             angle = Quaternion.Angle(my_transform.rotation, fwdRotation);
    46.             yield return null;
    47.         }
    48.         Destroy(orb);
    49.     }
     
  4. gamer_boy_81

    gamer_boy_81

    Joined:
    Jun 13, 2014
    Posts:
    169
    Whats the value of angle before the while loop ?
    If its > 1 in the begining, then you can print the values
    of angle within the while loop because I can see
    no other reason for the while loop to go false.
    I think you would've tried these already though.
     
  5. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    I did... I Debug.Log'd the value of angle...and it comes out to 44._ _ _ .
     
  6. gamer_boy_81

    gamer_boy_81

    Joined:
    Jun 13, 2014
    Posts:
    169
    So the while loop doesn't execute even once ? I mean, what values of
    angle do you get when you debug.log(angle) inside the loop ?
     
  7. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Haven't tried it inside the loop...but I would think I shouldn't even need to. Give then fact that as soon as the loop starts angle is already > 1.
     
  8. gamer_boy_81

    gamer_boy_81

    Joined:
    Jun 13, 2014
    Posts:
    169
    You never know..because I fail to see any other reason why the while loop will not execute !
     
  9. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Alright. I just debugged it inside the while loop...the while loop IS executing, but so is everything else after it.:mad:
     
  10. gamer_boy_81

    gamer_boy_81

    Joined:
    Jun 13, 2014
    Posts:
    169
    aah ok...So the while loop yields and while it is yielding, it executes the part
    after the loop too simultaneously ?
    Sometimes such are the issues that make me wanna take a new birth :p
     
  11. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Exactly! It's like Untiy decided to say, "I don't care about THAT yield statement, I'm going to keep going." o_O
     
  12. gamer_boy_81

    gamer_boy_81

    Joined:
    Jun 13, 2014
    Posts:
    169
    Hmm..
    I'm sure you must've
    Debug.log after that dreaded while loop to make sure that it is what is executing.
    I ask this because maybe that orb is getting destroyed elsewhere.
     
  13. gamer_boy_81

    gamer_boy_81

    Joined:
    Jun 13, 2014
    Posts:
    169
    oh yaa I just noticed that in line 35 you have orb.transform.parent= my_transform;
    which means it is changing its parent. Maybe this is why it appears to get
    destroyed while actually it is moving to a different parent.
     
  14. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Nah...that's not it. Even commenting out that line, still causes it to continue on past the while loop. During runtime I can see this happen frame by frame because
    Code (CSharp):
    1.     private IEnumerator Capture(Collision col)
    2.     {
    3.         yield return StartCoroutine(Move(col));
    4.         rigidbody.WakeUp(); // THIS LINE SHOULDN'T HAPPEN UNTIL THE WHILE LOOP IS
    5.                              //COMPLETE & THE ORB IS DESTROYED
    6.         while(distance_to_ground > 0.2f)
    7.         {
    8.             yield return null;
    9.         }
    10.         rigidbody.isKinematic = true;
    11.         yield return StartCoroutine(Try(col));
    12.     }
    ...during runtime I play it forward frame by frame, and before the rotation is done adjusting itself, the rigidbody is already falling to the ground.
     
  15. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    Seems like you've got some misunderstandings about how this is all being processed, to me...

    To clarify, are you thinking that doing yield return StartCoroutine() is going to pause execution until the coroutine has completed? Because it won't.
     
  16. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    Yes it will. Unity has an example of it here, and I use it very often.
     
  17. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    This is what happens when I wake up at 3 am and try to answer questions on my phone...
     
  18. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Hmmm...which makes my scenario even more mind boggling (to me).
     
  19. gamer_boy_81

    gamer_boy_81

    Joined:
    Jun 13, 2014
    Posts:
    169
    hmm strange..is it possible to extract out a test project with the problematic stuff
    and upload a zip here ?
     
  20. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    I figured it out...

    Code (CSharp):
    1.     Vector3 move_to = new Vector3(transform.position.x-1.5f, col.contacts[0].point.y+1.5f, transform.position.z-1.5f);
    2.     while(Vector3.Distance(transform.position, move_to) > 0.01f)
    3.     {
    4.         rigidbody.velocity = Vector3.zero;
    5.         rigidbody.angularVelocity = Vector3.zero;
    6.         rigidbody.Sleep();
    7.         transform.LookAt(col.transform.position);
    8.         transform.position = Vector3.Lerp(transform.position, move_to, 5f * Time.deltaTime);
    9.         yield return null;
    10.     }
    This while loop was causing the rigidbody to wake up and go to sleep everytime it looped. On its final iteration, the rigidbody was still awake, which caused the ball to drop before it should. Changed it to...

    Code (CSharp):
    1.   rigidbody.velocity = Vector3.zero;
    2.   rigidbody.angularVelocity = Vector3.zero;
    3.   rigidbody.Sleep();
    4.   Vector3 move_to = new Vector3(transform.position.x-1.5f, col.contacts[0].point.y+1.5f, transform.position.z-1.5f);
    5.   while(Vector3.Distance(transform.position, move_to) > 0.01f)
    6.   {
    7.    transform.LookAt(col.transform.position);
    8.    transform.position = Vector3.Lerp(transform.position, move_to, 5f * Time.deltaTime);
    9.    yield return null;
    10.   }
    Works flawlessly now.
     
  21. gamer_boy_81

    gamer_boy_81

    Joined:
    Jun 13, 2014
    Posts:
    169
    damn I had exactly thought earlier that the Sleep() is causing the issue but
    its good to know you fixed it..I know the feeling when a hard to trace issue
    is fixed :D