- Home /
Displaying HUD Feedback Messages, Is This Code Ok?
Hey all, I need to display feedback messages to the player when he achieves specific goals. I decided it was time to write a robust HUD Message class which handles all the messages I need to show the player during gameplay, instead of hacking together a few lines of code everytime I need to display messages!
I wasn't sure how to implement it (static, singleton etc...), and what I ended up doing is using a static function that initializes all the needed members, and showing the message in the class's Start() function. I need some feedback on my implementation because I am not sure this is the best way to do it, or even a decent way...what do you guys think?
Here's my code below:
using UnityEngine;
using System.Collections;
public class SRMessage : MonoBehaviour
{
#region Variables
private string _defaultName = "TempUIMessage";
private float _defaultTimer = 3.0f;
private Vector3 _defaultPos = Vector3.zero;
private GameObject _labelPrefab;
public static string s_MsgText;
public static float s_MsgTimer;
public static Vector3 s_MsgPos;
public static string s_MsgName;
#endregion
#region Properties (getters and setters)
#endregion
// =================================== START FUNCTION =================================== //
void Start ()
{
// Runs as soon as the script is added to a game object.
UILabel lbl = gameObject.GetComponentInChildren<UILabel>();
gameObject.name = s_MsgName;
lbl.transform.position = s_MsgPos;
lbl.MakePixelPerfect();
lbl.text = s_MsgText;
Invoke( "DestroyMessage", s_MsgTimer );
}
// =================================== CUSTOM FUNCTIONS =================================== //
// Call from anywhere to show a HUD message
public static void ShowMessage( string msgText, float msgTimer, Vector3 msgPos, string msgName )
{
GameObject hudPanel = Managers.HUDManager.StatsHUD.HudObject;
GameObject labelPrefab = null;
if( hudPanel )
{
// if HUD panel exist, use the LabelOnly prefab
labelPrefab = NGUITools.AddChild( hudPanel, Resources.Load( "LabelOnly", typeof( GameObject )) as GameObject );
}
else
{
// if HUD panel doesn't exist, we need a full hud hierarchy (HUDRoot->Camera->Panel->UILabel)
labelPrefab = Instantiate( Resources.Load( "UILabel", typeof( GameObject ))) as GameObject;
}
s_MsgText = msgText;
s_MsgTimer = msgTimer;
s_MsgPos = msgPos;
s_MsgName = msgName;
labelPrefab.AddComponent<SRMessage>();
}
private void DestroyMessage( )
{
NGUITools.Destroy( this.gameObject );
}
}
I should mention I use NGUI for all my UI/HUD stuff. What i did is create 2 Prefabs, 1 with only a GameObject with a UILabel component attached (use when main HUD is present), and 1 with a NGUI HUD hierarchy setup (which contains the Root, Camera, Panel etc...). I use one or the other depending on whether or not a main HUD hierarchy already exist.
Comments - good or bad - are very welcome! I'm trying to learn the better ways to do things in Unity so don't be afraid to hurt my feelings ;)
Thanks! Stephane
Thanks! The public static variables do bug me though, I would rather have them be non-static and set them with class functions/Properties, and be private. To me, the way I am doing it above is more prone do bugs down the road...but I might be wrong.
I do something similar without static vars, like this:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Q$$anonymous$$_ClientGUI : $$anonymous$$onoBehaviour {
// Globals
private int _maxLines = 8;
private Queue<string> _queue = new Queue<string>();
private string $$anonymous$$ytext = "";
// $$anonymous$$ethod
public void NewActivity(string activity) {
if (_queue.Count >= _maxLines)
_queue.Dequeue();
_queue.Enqueue(activity);
$$anonymous$$ytext = "";
foreach (string st in _queue)
$$anonymous$$ytext = $$anonymous$$ytext + st + "\n";
}
// OnGUI
// display playerLog
GUI.Label(new Rect(2, // x, left offset
(Screen.height - 150), // y, bottom offset
300f, // width
150f), $$anonymous$$ytext); // height, text, Skin features
and I have my other scripts access the public method and send something like qmclientgui.NewActivity("Congratulations, you are now level 8!")
Thanks for the example!
In order to use non-static variables, you need a reference to the script, and if the script is already present in your scene then getting a reference to it is easy.
I wanted to write my message class independent of the editor, so that I can call it at any time without having to make sure it already exists on a scene gameObject, but because of that I cannot get a reference to it right away, and need to call a static function ins$$anonymous$$d.
I guess I can always have the class reference itself and use that to access its non-static members. $$anonymous$$aybe that would be a better alternative to what I'm doing.
Thanks for your time!
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
What's best: Instantiate or LoadLevelAdditive? 2 Answers
GUI font size? 1 Answer
Can I assign a stroke and shadow at the same time to my Fonts using NGUI? 0 Answers
Can someone help me fix my Javascript for Flickering Light? 6 Answers