Changing the value of a variable AFTER using GUI.Label to display the variable's value causes the label to display the new value. How can I stop this from happening?

I’m trying to make a simple tool to help me debug that displays a string variable and then clears the variable after it has been displayed. The problem is that if I change the variable to “”, the label still displays “”, even if I change it AFTER it gets displayed.

Here’s my code:

public class DebugGUI : MonoBehaviour{
	
	private static string messageToDisplay = "";
	
	void OnGUI(){
		
		//Display the message in a GUI label
		Debug.Log(messageToDisplay);
		GUI.Label(new Rect(0, 0, 1000, 1000), messageToDisplay);
		
		//Clear the message
		messageToDisplay = "";
	}
	
	public static void AddMessage(System.Object messageToAdd){
		//Adds a message
		
		messageToDisplay = messageToDisplay + messageToAdd.ToString() + " /n ";
	}

}

If I comment out the part that says “messageToDisplay = “”;”, then the label repeats the same message over and over. However, if I leave it in then the label is just blank; it’s as if the instructions are being executed out of order!

How can I make it so that it displays the contents of messageToDisplay and then clears it?

EDIT: I would like to add that, although OnGUI() is being called every frame, AddMessage() is also being called every frame; take another bit of code as an example:

float foo = 100;

void Update(){

//Count down from 100
foo -= 1 * Time.deltaTime;

//Display the amount of time left in the debug GUI
DebugGUI.AddMessage("There are " + foo + " seconds left.");
}

So OnGUI() being called constantly is not the problem here.

I’m guessing that it’s because you’re clearing it every time the function is called, so your message does get displayed, but it’s actually replaced immediately in the next frame by the now-cleared label, and this happens too fast for you to see it.

I think that not clearing the message will be a very good idea, given that your code in AddMessage() will work fine - you’re adding a newline after every message and you’re adding the new message to the old string, so I’m quite certain that you should remove the messageToDisplay = "";

However, you want the label to be cleared afterwards, right? My best bet would be to call a coroutine that waits for maybe a couple of seconds after the message is added, and then clears the contents of messageToDisplay. I’m sorry if I’ve misunderstood you and if I’m talking nonsense though. :slight_smile:

An OnGUI() call happens every frame, so the first frame, it probably displays the label correctly, but then you set the value of the static variable to “”, and the next time the OnGUI() method is called, it displays the label with the empty message. So the transition is so quick, it seems as if it’s not displayed to start with.

What you need to do, is count how long you want the label to display, save the start time in a variable, and only clear the message after it’s been displayed long enough.

This sample code will display a message for 10 seconds every time you call AddMessage():

public class DebugGUI : MonoBehaviour{
 
	private static string messageToDisplay = "";
	private static float messageDisplayStartTime = -999;
	
	private const float messageDisplayTime = 10; // display each message ten seconds
 
	void OnGUI(){
 
		//Display the message in a GUI label
		Debug.Log(messageToDisplay);
		GUI.Label(new Rect(0, 0, 1000, 1000), messageToDisplay);
 
		//Clear the message after some time
		if (Time.timeSinceLevelLoad > messageDisplayStartTime + messageDisplayTime)
			messageToDisplay = "";
	}
 
	public static void AddMessage(System.Object messageToAdd){
	   //Adds a message
 
	   messageToDisplay = messageToDisplay + messageToAdd.ToString() + " /n ";
	   messageDisplayStartTime = Time.timeSinceLevelLoad;
	}
}

Edit: The OnGUI() call can happen more than once a frame, so the first call displays the label correctly, but also resets the message variable. Subsequent calls display the empty message, hence your label appears empty. You must move the message resetting outside of the OnGUI() call or at least place a condition to do it after some time has passed.