Giving Players Feedback via guiTexture

So I am trying to flash a message to the player when they pickup and dropoff items, and I just want the GuiTexture to flash on the screen for a second.

Heres the code, but none of the methods I have found seem to work.

This is adapted from the code in Will Goldstones Book.

var alerttex : Texture2D ;
var deliverytex : Texture2D ;
var capacitytex : Texture2D ;
var wrongtex : Texture2D ;

static var alert : int = 0;

function Start ()
	{
		guiTexture.enabled = false;
		alert = 0;	
	}

function Update () {
		if (alert == 1) 
		{
			guiTexture.texture = alerttex;
			guiTexture.enabled = true;
		}
		else if (alert == 2)
		{
			
			guiTexture.texture = deliverytex;
			guiTexture.enabled = true;
			yield WaitForSeconds(0.5);
			guiTexture.enabled = false;	
		}
		else if (alert == 3)
		{
			guiTexture.texture = capacitytex;
			guiTexture.enabled = true;	
		}
		else if (alert == 4)
		{
			guiTexture.texture = wrongtex;
			guiTexture.enabled = true;
		} 
		else if (alert == 0)
		{
			guiTexture.enabled = false;
		}
}

Right now its throwing the error the Update() cannot be a coroutine, which I am sure is because of the yield. I don’t want to destroy the game object, because I want it to happen every time if it is not correct.

The alert var is changed from another script.

Update runs once every single frame, and can’t be interrupted or delayed. Therefore it’s not particularly suitable for scheduling events. Also, it’s a little wasteful to run Update every frame just to check the status of the alert variable, which presumably doesn’t actually change very often. Instead, it would be better to call a coroutine that sets the GUITexture based on the value you pass.

Further, the “alert” variable would be better off as an enum, because a series of magic numbers doesn’t really mean anything. Right now you might remember that 1 = Alert, 2 = Capacity, etc., but what happens when you look at the code months from now, or someone else does? Also there’s a greater capacity for bugs, like if you somehow accidentally used 5 or 7 or -1 or whatever. Whereas with an enum, it’s impossible to use anything other than what you’ve explicitly defined, because you immediately get a compilation error if you try.

So instead you can do something like this, and call the script GUIManager:

var messageTextures : Texture2D[];
static var use : GUIManager;

enum MessageType {Alert = 0, Delivery = 1, Capacity = 2, Wrong = 3, None = 4}

function Awake () {
	guiTexture.enabled = false;
	use = this;
}

function GUIMessage (message : MessageType) {
	if (message != MessageType.None) {
		guiTexture.texture = messageTextures[message];
		guiTexture.enabled = true;
		
		if (message == MessageType.Delivery) {
			yield WaitForSeconds(0.5);
			guiTexture.enabled = false;
		}
	}
	else {
		guiTexture.enabled = false;
	}
}

Then from any script you can do

GUIManager.use.GUIMessage (MessageType.Delivery);

to set the texture appropriately. Replace MessageType.Delivery with MessageType.Alert, MessageType.None, etc. as needed.

The only downside is that the textures are stored in an array instead of with individual names, so it’s not really possible to tell in the inspector which is which. However I think it’s likely that you would spend far more time looking at code rather than assigning variables in the inspector, so it’s more important for the code to be readable. It would be nifty if there was a way to make labels for array variables in the inspector (without having to write a custom inspector anyway). But still you just have to make sure the array textures are assigned in the same order they’re listed in the enum.

–Eric

Yes Update does not like to Yield. Why would you have to destroy your gameObject? Are you saying that you want it to repeat the enabling and disabling if alert==2 like a loop? Anyway you could use a couple of booleans and an Invoke to create a work around. (eg)

else if ((alert==2)(showTex==false)) {
showTex = true;
if((showTex)(alert==2)) {
guiTexture.texture = deliverytex;
guiTexture.enabled = true;
Invoke(“HideMyTex”,1.0);
}
}

//###################################################//

function HideMyTex() {
guiTexture.enabled = true;
showTex = false;
}

This is just an idea off the top of my head as i’m no code JEDI yet. The force may not be with me on this one LOL
InvokeRepeat is lots of fun too. Hope this helps.

I like this but I am not quite understanding where you store which textures you want to call, and when I copy the code it says

The name ‘GUIManager’ does not denote a valid type (‘not found’).

In the Debug Log.

I think I understand it otherwise!

Also, in my code, the Alert static var is changed when the player hits a trigger collision volume.

In the inspector, in the messageTextures array.

As I mentioned, you need to call the script GUIManager.

Instead of this:

WhateverYourScriptIsCalled.alert = x;

Use this:

GUIManager.use.GUIMessage(x);

Replace x with MessageType.Alert or whatever.

–Eric

Excellent, Its definitely working.

I assume I can use the GUIManager then to create more messages and such for other information I want to display to the player?

Yep, add to the enum as necessary (“None” should always be the last entry), and add code to the GUIMessage function as appropriate. You can add other functions, which would also be called by using GUIManager.use.MyCoolFunctionHere().

–Eric