Hey guys, I wonder what is the difference between yield return null and yield return new WaitForEndOfFrame(). For example if i used this in a coroutine like that.
They’re very similar, but return at different points in the frame.
Unity performs many operations once per frame, including:
Input processing
Main update (including Update())
Main coroutine updates (including yield return null)
Late update (including LateUpdate())
Scene rendering (quite a few steps)
Gizmo/UI rendering
End of frame (including WaitForEndOfFrame)
One returns just before rendering, the other returns just after (but just before the frame is displayed). When the difference isn’t important, I usually use and recommend yield return null, as it’s closer to the way other Update and coroutine functions work.
This is explained in more detail at the execution order manual page. Recently, they’ve added a handy chart:
Of course both of your examples will execute the Debug.Log line, however at different times. If you yield “null” (or any other value that isn’t recognised) Unity will schedule this coroutine the next frame right after Update is called. When you use WaitForEndOfFrame, The coroutine will be scheduled this frame once all cameras are rendered and the GUI is drawn. It will run right before the buffers are swapped and the frame is finished.
When you yield return WaitForEndOfFrame the coroutine will be resumed at the end of the current frame, after scene and ui rendering.
When you yield return null the coroutine will be resumed in the next frame right after the Update is completed.
WaitForEndOfFrame is useful when you want the coroutine to be resumed later this frame, while returning null will resume it after next frame’s Update, which is a very important difference sometimes.
This article is a bit old, maybe at that times the system worked different. But I’ve made an experiment resulting different from you have talked. here is the code:
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
public class CizgiCizKaydet : EventTrigger
{
public static bool allow = false;
public override void OnEndDrag(PointerEventData eventData)
{
StartCoroutine(AllowPrintForOneFrame());
}
IEnumerator AllowPrintForOneFrame()
{
allow = true;
yield return new WaitForEndOfFrame();
// yield return null;
allow = false;
}
private void Update()
{
if (allow )
print("Merhaba");
}
}
for the “yield return null;” version the print(“Merhaba”); is executed twice. for the “yield return new WaitForEndOfFrame();” version print(“Merhaba”); is executed once.