Yield WaitForSeconds in OnGUI?

Hi Everyone,

Is is possible to have yield WaitForSeconds in OnGUI? If not is there a way in having a delay between showing a series of images?

Here is an example of what I tried to do:

if (isIntroTutActive) {
		GUI.Label(Rect(Screen.width / 2 - 250,Screen.height / 2 - 75,500,150),tutMouseMoveFeedbackHUD);
		yield WaitForSeconds (5);
		GUI.Label(Rect(Screen.width / 2 - 250,Screen.height / 2 - 75,500,150),tutMoveFeedbackHUD);
		yield WaitForSeconds (5);
		GUI.Label(Rect(Screen.width / 2 - 250,Screen.height / 2 - 75,500,150),tutCharInteractionFeedbackHUD);
		yield WaitForSeconds (5);
		GUI.Label(Rect(Screen.width / 2 - 250,Screen.height / 2 - 75,500,150),tutGameMenuHUD);
		yield WaitForSeconds (5);
		isIntroTutActive = false;
	}

This is the error message I get once it hits the first yield WaitForSeconds(5):
ArgumentException: You can only call GUI functions from inside OnGUI.
UnityEngine.GUIUtility.CheckOnGUI ()

Thank you very much for any help :slight_smile:

This’ll need some adjusting, but it should point you in the right direction:

private var stage : int;
var displayThings : String = new String[]; // or whatever
var timeBetweenStages : float;
private var timeRemainingThisStage : float;

function Start() {
  timeRemainingThisStage = timeBetweenStages;
  stage = 0;
function OnGUI() {
  GUI.Function( Rect, displayThings[ stage ] );
  timeRemainingThisStage -= Time.deltaTime;
  if ( timeRemainingThisStage <= 0  stage < displayThings.length-1 ) {
    timeRemainingThisStage = timeBetweenStages;
    stage++;
  }
}

so you mean it is not possible?

I have another question. how could the reference show this example?
//-----------------------
using UnityEngine;
using System.Collections;
public class example : MonoBehaviour {
IEnumerator Awake() {
print(Time.time);
yield return new WaitForSeconds(5);
print(Time.time);
}
}

//---------------------

when clearly in the reference of awake, page , tell us this. ??

Awake cannot be a co-routine.

???

OnGUI always runs every single frame (at least twice), and can’t be interrupted or delayed in any way. You can set variables in coroutines, and use those variables in OnGUI to control what you want done. As for the example in the docs, it’s the result of the automatic JS-to-C# converter, and is incorrect. You can use the bug reporter to report documentation bugs.

That logic with Time.deltaTime in OnGUI won’t work, because of OnGUI running at least twice per frame. Only use GUI functions in OnGUI, and put controlling code in coroutines.

–Eric

Put whatever it is you want to delay inside another function, put the yield at the top of that function. Call that function anywhere in the OnGUI function and you’ll get what you want.

Nope - that’s still no good.

If I understand the goal correctly then you’ll want to have a separate function that manages what images are supposed to be shown. Whether you hold state in an enum, use bools, or add the images to an array is really up to you. Then OnGUI() simply draws whatever images it has available.

You really should avoid doing anything involving ‘Time’ in OnGUI at all.

OnGUI is called 2 times per frame minimum and also gets called for every keystroke ( down, up ), mouse move/drag, and any other ‘Event’.

So to answer the original question no you can not make OnGUI a coroutine.

Use either Start as a Coroutine ( IEnumerator ) or just plan old Update/LateUpdate to do the image switching code. And simply have your OnGUI function use the calculated data off your method.