Yield in OnCollisionEnter makes it work only once

Guys, I have a problem I couldn’t solve.

Environment:

In my application, I shoot a prefab Ball in some objects in the scene. When it hits it, I show a window with some information and close it in some time.

The problem is:

The first time I hit a object everything happens as expected, but when I hit the SAME object AFTER the window close, the function OnCollisionEnter it’s not reached.

I tried:

  • To call the yield inside and outside from OnCollisionEnter.
  • To use StartCoroutine.
  • To make all of this in OnCollisionExit.

But nothing made it works. When I remove the yield statement I have no problems, 'cause it shows and close the window immediately.

Relevant Code:

function OnCollisionEnter(collision : Collision) {

	//If a sphere collides with a prefab
	if(collision.gameObject.CompareTag("Ball")){
        showData = true;
        windowID++;	
        //yield WaitForSeconds(5); -- Tried
        //yield StartCoroutine("ClosePopUpAfterSeconds"); -- Tried
		ClosePopUpAfterSeconds(5f);
	}
}

/* -- Tried
function OnCollisionExit(collision : Collision) {
	if(collision.gameObject.CompareTag("Ball")){
		
		ClosePopUpAfterSeconds(5f);
	}
}
*/

function ClosePopUpAfterSeconds(time : float)
{
    yield WaitForSeconds(time);
    if(showData && !freezePopUp){
    	hit = false;
        showData = false;
        Destroy(this);
    }
}

function OnGUI() { 
 
    if(showData){
		windowRect = GUI.Window(windowID, windowRect, WindowData, "Some data stuff");
		GUI.BringWindowToFront(windowID);
	}
}

function WindowData (windowID : int) {
	
    // Showing window's buttons and their logic
    if (GUI.Button (Rect( ((Screen.width / 100f) * 21.8f) , ((Screen.height / 100f) * 0.6f), ((Screen.width / 100f) * 3.5f), ((Screen.height / 100f) * 5f) ), "||")){
		freezePopUp = true;
	}
		
    if (GUI.Button (Rect ( (Screen.width /100f) * 25.4f , (Screen.height /100f) * 0.6f, (Screen.width /100f) * 3.5f, (Screen.height /100f) * 5f), "X")){
        Destroy(this);
        showData = false;
        freezePopUp = false;
	}
    GUI.DragWindow (Rect (0,0,10000,10000));
}

I think it must be a logic error, but I still don’t see it.
I really appreciate your help.

Edit:
It seems entirely possible that while the second coroutine is yielding at yield WaitForSeconds(time); that the first coroutine would finish and set showData = false;. Which means that your second coroutine would finish yielding its 5 seconds and not show anything because showData is now false.

You might want to rework how the different pop-ups get queued up using some sort of container and showing the next available window.