ReadPixels not inside Drawing Frame

I get this error:

ReadPixels was called to read pixels
from system frame buffer, while not
inside drawing frame.
UnityEngine.Texture2D:ReadPixels(Rect,
Int32, Int32, Boolean)

Every time I try and take a screenshot of my application via code. Now, I used to get this error because I wasn’t calling the function within a ‘OnPostRender’.

But what I’m doing now is this:

function TakeScreenShot(){

   //custom function to check when OnPostRender is okay
   yield WaitForOnPostRender();

   //do screen grab
   img.ReadPixels(new Rect(rect), 0, 0, true); 

}

function WaitForOnPostRender(){

	grab = true;

	while(onPostRender == false)
		yield;

	onPostRender = false;
	return;
}

var onPostRender : boolean = false;
function OnPostRender(){

	if(grab){

		onPostRender = true;
		grab = false;
	}
}

So why is it still throwing an error/warning?

This doesn’t work as coroutines what “yield null” are resumed right after Update is called.

Have a look at this flowchart. Rendering starts after the game logic. If you set your "onPostRender " variable to true inside “OnPostRender” doesn’t help much since your coroutine is resumed the next frame after update where it “sees” that the variable has turned true.

If you want to take a screenshot you have to take it after the rendering has finished. There are two possibilities:

  • Attach your script to the camera and use OnPostRender to actually grab the image.
  • When you want to use a coroutine, simply use yield WaitForEndOfFrame();. This will resume your coroutine right at the end of the current frame when all rendering has finished.