yield in for loop breaking render texture

My first snippet of code works correctly. It is a function with a for loop that runs 10 times. Each time the loop runs a camera is drawn to a render texture then put in a texture2d. Then there are two more for loops that look though every pixel of the texture2d looking for green pixels.

void FindBestSpot(){
		for (int i = 0; i < 10; i++) {
			FrameObject ();
			RenderTexture renderTexture = new RenderTexture (snapShotWidth / 4, snapShotHeight / 4, 24);
			cam.targetTexture = renderTexture;
			Texture2D snapShot = new Texture2D (snapShotWidth / 4, snapShotHeight / 4, TextureFormat.RGB24, false);
			cam.Render ();
			RenderTexture.active = renderTexture;
			snapShot.ReadPixels (new Rect (0, 0, snapShotWidth / 4, snapShotHeight / 4), 0, 0);
			cam.targetTexture = null;
			RenderTexture.active = null;
			Destroy (renderTexture);
			int totalPixels = 0;
			int greenPixels = 0;
			for (int x = 0; x < snapShot.width; x++) {
				for (int y = 0; y < snapShot.height; y++) {
					totalPixels++;
					if (snapShot.GetPixel (x, y) == Color.green) {
						greenPixels++;
					}
				}
			}
			float percentCoverage = (float)greenPixels / (float)totalPixels;
			snapShotSpots.Add (new SnapShotSpot (cam.transform.position, percentCoverage));
		}
		SnapShotSpot bestSpot = snapShotSpots[0];
		float bestPercent = snapShotSpots[0].percentCoverage;
		foreach (SnapShotSpot spot in snapShotSpots) {
			if (spot.percentCoverage > bestPercent) {
				bestSpot = spot;
				bestPercent = spot.percentCoverage;
			}
		}
		foreach (Uid uid in cloneUids) {
			DestroyImmediate (uid.gameObject);
		}
		cloneUids.Clear ();
		bestCamSpot = bestSpot;
	}

The only problem with this code is that it takes too long to perform smoothly in one frame. So I tried to make the function a coroutine and add a yield at the end of the for loop.

IEnumerator FindBestSpot(){
		for (int i = 0; i < 10; i++) {
			FrameObject ();
			RenderTexture renderTexture = new RenderTexture (snapShotWidth / 4, snapShotHeight / 4, 24);
			cam.targetTexture = renderTexture;
			Texture2D snapShot = new Texture2D (snapShotWidth / 4, snapShotHeight / 4, TextureFormat.RGB24, false);
			cam.Render ();
			RenderTexture.active = renderTexture;
			snapShot.ReadPixels (new Rect (0, 0, snapShotWidth / 4, snapShotHeight / 4), 0, 0);
			cam.targetTexture = null;
			RenderTexture.active = null;
			Destroy (renderTexture);
			int totalPixels = 0;
			int greenPixels = 0;
			for (int x = 0; x < snapShot.width; x++) {
				for (int y = 0; y < snapShot.height; y++) {
					totalPixels++;
					if (snapShot.GetPixel (x, y) == Color.green) {
						greenPixels++;
					}
				}
			}
			float percentCoverage = (float)greenPixels / (float)totalPixels;
			Debug.Log(greenPixels + "/" + totalPixels + "=" + percentCoverage);
			snapShotSpots.Add (new SnapShotSpot (cam.transform.position, percentCoverage));															
   			//yield return null;
			yield return new WaitForSeconds(0.1f);
		}
		SnapShotSpot bestSpot = snapShotSpots[0];
		float bestPercent = snapShotSpots[0].percentCoverage;
		foreach (SnapShotSpot spot in snapShotSpots) {
			if (spot.percentCoverage > bestPercent) {
				bestSpot = spot;
				bestPercent = spot.percentCoverage;
			}
		}
		foreach (Uid uid in cloneUids) {
			DestroyImmediate (uid.gameObject);
		}
		cloneUids.Clear ();
		bestCamSpot = bestSpot;
	}

I tried making the for loop yield for 1 frame as well as for a set amount of time and in both cases it stop functioning correctly. Anytime there is a yield in the for loop the function only works correctly the first time through and the other 9 times the debug statement return that there a 0 green pixels in the texture2d. It returns the correct amount of totalPixels every time. Even when I have the code write the images to files the image files appear to be correct. There are green pixels in the image file but the code still returns 0 green pixels every time except the first time through.

Is there a reason why this is happening? Why would the image file appear correct but the code still not find any green pixels in the texture2d? Why would this work correctly when the for loop runs 10 times in one frame but not work correctly when it runs once per frame? Is there any other way to spread this for loop over time so the game doesn’t freeze while this is happening? I’ve looked in to multi-threading possibly using Thread Ninja but almost everything that happens in the loop is using functions dependent on unity engine. From what I understand all of these lines need to happen in the main thread. Is there a way around this or a better way to accomplish what I’m trying to do?

Let me know if you need any more info.

Where do you originally call the method from? Any sort of rendering can only be done while the engine is internally in “render state”. Using just WaitForSeconds will resume the coroutine during the “update state”. It should work when you do this instead:

yield return new WaitForSeconds(0.1f);
yield return new WaitForEndOfFrame();

So first it waits for the desired time and when the time has passed it waits again for the end of the current frame.

Keep in mind that the time moves on while you wait for the coroutine to continue.