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

yield return WaitEndOfFrame will wait until end of the same frame or the next frame?

Discussion in 'Scripting' started by xiaoqiangliang, Nov 25, 2014.

  1. xiaoqiangliang

    xiaoqiangliang

    Joined:
    Sep 12, 2014
    Posts:
    5
    In the documentation, WaitEndOfFrame is "Waits until the end of the frame after all cameras and GUI is rendered, just before displaying the frame on screen."

    It used in yield return for Coroutine. My question is that it will wait until end of the same frame or the next frame?

    From what I tested, it wait until end of the next frame, is that correct?

    Is there a way to wait until end of the same frame?
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It should wait until the end of this frame and I haven't experienced anything else so far. This quick test here also behaves as expected:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class WaitForEndTest : MonoBehaviour {
    5.  
    6.    private void Update () {
    7.      float time = Time.realtimeSinceStartup;
    8.      Debug.Log ("Update: " + time);
    9.      StartCoroutine (WaitForEndOfFrameCoroutine (time));
    10.    }
    11.    
    12.    private IEnumerator WaitForEndOfFrameCoroutine (float time) {
    13.      yield return (new WaitForEndOfFrame ());
    14.      Debug.Log ("End of frame: " + time);
    15.    }
    16. }
     
  3. xiaoqiangliang

    xiaoqiangliang

    Joined:
    Sep 12, 2014
    Posts:
    5
    Dantus,

    I think the example is not what you want.

    It will call StartCoroutine (WaitForEndOfFrameCoroutine (time)) in every frame, is that correct?

    Here is my code:

    Code (csharp):
    1.  
    2. int counter = 0;
    3. bool running = false;
    4.   void Update()
    5.   {
    6.   counter++;
    7.   UnityEngine.Debug.Log("Update in the frame: " + Time.frameCount);
    8.   if (!running)
    9.   {
    10.     StartCoroutine(WhenICalled());
    11.     running = true;
    12.   }
    13.  
    14.   }
    15.  
    16.   IEnumerator WhenICalled()
    17.   {
    18.   UnityEngine.Debug.Log("I am called before yield in frame: "+ counter);// + Time.frameCount);
    19.   yield return new WaitForEndOfFrame();
    20.   UnityEngine.Debug.Log("I am called after yield in frame: " + counter);//Time.frameCount);
    21.   }
    22.  
    And I found after yield return new WaitForEndOfFrame(), it will wait until next frame.
     
    MarkTension likes this.
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    And it doesn't print sequential counter? (1 then 2, etc)
     
  5. xiaoqiangliang

    xiaoqiangliang

    Joined:
    Sep 12, 2014
    Posts:
    5
    Yes.

    That means the WaitForEndOfFrame() wait until end of next frame. If it wait until end of the same frame, the counter should not be changed.

    If you run the code, you will see the debug output sequential.
     
  6. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I think I know what you mean:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class WaitForEndTest : MonoBehaviour {
    5.  
    6.    private int counter = 0;
    7.  
    8.    private void Update () {
    9.      counter = counter + 1;
    10.    
    11.      Debug.Log ("Update: " + counter);
    12.      StartCoroutine (WaitForEndOfFrameCoroutine (counter));
    13.    }
    14.  
    15.    private IEnumerator WaitForEndOfFrameCoroutine (int counter) {
    16.      Debug.Log ("Before end of frame: " + counter);
    17.      yield return (new WaitForEndOfFrame ());
    18.      Debug.Log ("After end of frame: " + counter);
    19.    }
    20. }
    This gives e.g.
    which is correct.

    But it is wrong in the first frame:
    After that, you will get exactly the expected result.

    This is clearly a bug. I just remembered that Unity has quite some issues in the first frame. You may e.g. try to call Time.realTimeSinceStartup in the first frame. This will usually not return 0, but something that is completely wrong.
     
  7. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
  8. xiaoqiangliang

    xiaoqiangliang

    Joined:
    Sep 12, 2014
    Posts:
    5
    Dantus,

    Thank you for the help and I can run my example to get the same result. So, after the first frame, it will work as the expect.