Keypress speeds up fade?

And another fading problem. I’m starting to find abrupt transitions very attractive.
I’m using this code to fade out to a game over screen. The problem is that if the player is still holding down the forward button (or any keyboard button, even those not assigned to any function) when the fade begins, it completes much faster than it should. Any ideas on why?

Here is the active code:

using UnityEngine;
using System;
 
public class CameraFade : MonoBehaviour
{   
	private static CameraFade mInstance = null;
 
	private static CameraFade instance
	{
		get
		{
			if( mInstance == null )
			{
				mInstance = GameObject.FindObjectOfType(typeof(CameraFade)) as CameraFade;
 
				if( mInstance == null )
				{
					mInstance = new GameObject("CameraFade").AddComponent<CameraFade>();
				}
			}
 
			return mInstance;
		}
	}
 
	void Awake()
	{
		if( mInstance == null )
		{
			mInstance = this as CameraFade;
			instance.init();
		}
	}
 
	public GUIStyle m_BackgroundStyle = new GUIStyle();						// Style for background tiling
	public Texture2D m_FadeTexture;											// 1x1 pixel texture used for fading
	public Color m_CurrentScreenOverlayColor = new Color(0,0,0,0);			// default starting color: black and fully transparrent
	public Color m_TargetScreenOverlayColor = new Color(0,0,0,0);			// default target color: black and fully transparrent
	public Color m_DeltaColor = new Color(0,0,0,0);							// the delta-color is basically the "speed / second" at which the current color should change
	public int m_FadeGUIDepth = -1000;										// make sure this texture is drawn on top of everything
 
	public float m_FadeDelay = 0;
	public Action m_OnFadeFinish = null;
 
	// Initialize the texture, background-style and initial color:
	public void init()
	{		
		instance.m_FadeTexture = new Texture2D(1, 1);        
        instance.m_BackgroundStyle.normal.background = instance.m_FadeTexture;
	}
 
	// Draw the texture and perform the fade:
	void OnGUI()
    {   
		// If delay is over...
		if( Time.time > instance.m_FadeDelay )
		{
			// If the current color of the screen is not equal to the desired color: keep fading!
			if (instance.m_CurrentScreenOverlayColor != instance.m_TargetScreenOverlayColor)
			{			
				// If the difference between the current alpha and the desired alpha is smaller than delta-alpha * deltaTime, then we're pretty much done fading:
				if (Mathf.Abs(instance.m_CurrentScreenOverlayColor.a - instance.m_TargetScreenOverlayColor.a) < Mathf.Abs(instance.m_DeltaColor.a) * Time.deltaTime)
				{
					instance.m_CurrentScreenOverlayColor = instance.m_TargetScreenOverlayColor;
					SetScreenOverlayColor(instance.m_CurrentScreenOverlayColor);
					instance.m_DeltaColor = new Color( 0,0,0,0 );
 
					if( instance.m_OnFadeFinish != null )
						instance.m_OnFadeFinish();
 
					Die();
				}
				else
				{
					// Fade!
					SetScreenOverlayColor(instance.m_CurrentScreenOverlayColor + instance.m_DeltaColor * Time.deltaTime);
				}
			}
		}
		// Only draw the texture when the alpha value is greater than 0:
		if (m_CurrentScreenOverlayColor.a > 0)
		{			
    		GUI.depth = instance.m_FadeGUIDepth;
    		GUI.Label(new Rect(-10, -10, Screen.width + 10, Screen.height + 10), instance.m_FadeTexture, instance.m_BackgroundStyle);
		}
    }
 
 
	/// <summary>
	/// Sets the color of the screen overlay instantly.  Useful to start a fade.
	/// </summary>
	/// <param name='newScreenOverlayColor'>
	/// New screen overlay color.
	/// </param>
	private static void SetScreenOverlayColor(Color newScreenOverlayColor)
	{
		instance.m_CurrentScreenOverlayColor = newScreenOverlayColor;
		instance.m_FadeTexture.SetPixel(0, 0, instance.m_CurrentScreenOverlayColor);
		instance.m_FadeTexture.Apply();
	}
 
 	/// <summary>
 	/// Starts the fade from color newScreenOverlayColor. If isFadeIn, start fully opaque, else start transparent.
 	/// </summary>
 	/// <param name='newScreenOverlayColor'>
 	/// Target screen overlay Color.
 	/// </param>
 	/// <param name='fadeDuration'>
 	/// Fade duration.
 	/// </param>
	public static void StartAlphaFade(Color newScreenOverlayColor, bool isFadeIn, float fadeDuration )
	{
		if (fadeDuration <= 0.0f)		
		{
			SetScreenOverlayColor(newScreenOverlayColor);
		}
		else					
		{
			if( isFadeIn )
			{
				instance.m_TargetScreenOverlayColor = new Color( newScreenOverlayColor.r, newScreenOverlayColor.g, newScreenOverlayColor.b, 0 );
				SetScreenOverlayColor( newScreenOverlayColor );
			} else {
				instance.m_TargetScreenOverlayColor = newScreenOverlayColor;
				SetScreenOverlayColor( new Color( newScreenOverlayColor.r, newScreenOverlayColor.g, newScreenOverlayColor.b, 0 ) );
			}
 
			instance.m_DeltaColor = (instance.m_TargetScreenOverlayColor - instance.m_CurrentScreenOverlayColor) / fadeDuration;	
		}
	}

	void Die()
	{
		mInstance = null;
		Destroy(gameObject);
	}
 
	void OnApplicationQuit()
	{
		mInstance = null;
	}
}

OnGUI() gets called multiple times per frame. Pressing keys, increases the number of events/calls per frame, so you fade faster. To better understand the number of calls/events, add this inside your OnGUI() code:

Debug.Log(Event.current.type);

To make your code consistent, I’d restrict it to running only when there is a Repaint event:

if (Event.current.type == EventType.Repaint) {
    // Your OnGUI code goes here  
}