Coroutine takes too long to finish, what is wrong?

Hello!

I have written a coroutine to lerp the alpha of a Unity UI panel and then deactivate this panel after the lerp has finished.

The expected behaviour would be to reach the SetActive(false) at the end of the coroutine after the duration in seconds specified before the while loop has passed.
However, it takes significantly longer (about half a second longer) to reach the SetActive(false) statement, thus blocking interaction with my GUI because the fullscreen panel overlays my UI at this time.
What is wrong with this coroutine or while loop? Any ideas?

private IEnumerator LerpAlpha() {

	float currentAlpha = 0f,
	 startAlpha = 0f,
	 targetAlpha = 1f;

	float elapsedTime = 0f;
	float duration = .5f;
	float fraction = 0f;

	Color color = imageFullscreen.color;
		
	while (elapsedTime < duration) {
			
		fraction = elapsedTime / duration;
		fraction = animCurve.Evaluate(fraction.Remap(0f, duration, 0f, 1f));
			
		elapsedTime += Time.deltaTime;
			
		currentAlpha = Mathf.Lerp (startAlpha, targetAlpha, fraction);
		color = new Color(color.r, color.g, color.b, currentAlpha);
			
		imageFullscreen.color = color;
			
		yield return new WaitForEndOfFrame();
	}

	imageFullscreen.gameObject.SetActive(false);

}

Use yield return null instead of WaitForEndOfFrame.

see: link text Execution Order of Event Functions

Look at: Script Lifecycle Flowchart

WaitForEndOfFrame is called “later” then yield return null!

@monogon did you figure it out?
I’m having a similar problem.

Since the question got bumped already I’ll post an answer. The coroutine does not take any longer, however your lerp will finish in half the time of your duration. The reason is your use of your Remap method. You essentially remap your “fraction” variable two times.

First of all this already gives you a value between 0 and 1 since you divide by duration:

fraction = elapsedTime / duration;

However you then use this fraction.Remap(0f, duration, 0f, 1f). I guess that the Remap function is an extension method for the type float. It maps the incoming value fraction from the range 0 to duration to the range 0 ro 1. However since duration is 0.5 and your fraction variable is already mapped to a 0 to 1 range, fraction will be 0.5 after half your duration. Your Remap method would clamp any value greater than 0.5 to 1.

So what you see is that in the first half of your duration you see a linear increase from 0 to 1. In the second half of your duration your value would be clamped to 1. So it seems that it’s somehow takes longer than it is. Though the actual duration would still be just 0.5 seconds.