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

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?

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:

using UnityEngine;
using System.Collections;

public class WaitForEndTest : MonoBehaviour {

   private void Update () {
     float time = Time.realtimeSinceStartup;
     Debug.Log ("Update: " + time);
     StartCoroutine (WaitForEndOfFrameCoroutine (time));
   }
   
   private IEnumerator WaitForEndOfFrameCoroutine (float time) {
     yield return (new WaitForEndOfFrame ());
     Debug.Log ("End of frame: " + time);
   }
}

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:

int counter = 0;
bool running = false;
  void Update()
  {
  counter++;
  UnityEngine.Debug.Log("Update in the frame: " + Time.frameCount);
  if (!running)
  {
    StartCoroutine(WhenICalled());
    running = true;
  }
 
  }
 
  IEnumerator WhenICalled()
  {
  UnityEngine.Debug.Log("I am called before yield in frame: "+ counter);// + Time.frameCount);
  yield return new WaitForEndOfFrame();
  UnityEngine.Debug.Log("I am called after yield in frame: " + counter);//Time.frameCount);
  }

And I found after yield return new WaitForEndOfFrame(), it will wait until next frame.

1 Like

And it doesn’t print sequential counter? (1 then 2, etc)

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.

I think I know what you mean:

using UnityEngine;
using System.Collections;

public class WaitForEndTest : MonoBehaviour {
  
   private int counter = 0;
  
   private void Update () {
     counter = counter + 1;
    
     Debug.Log ("Update: " + counter);
     StartCoroutine (WaitForEndOfFrameCoroutine (counter));
   }
  
   private IEnumerator WaitForEndOfFrameCoroutine (int counter) {
     Debug.Log ("Before end of frame: " + counter);
     yield return (new WaitForEndOfFrame ());
     Debug.Log ("After end of frame: " + counter);
   }
}

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.

1 Like

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.