How to put a list of strings in a Text Unity 4.6 UI element

So i have this GUI.Label that has a list of strings to make my chat, but it doesn’t work when i try it with an Unity 4.6 Text UI element.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class ChatManager : MonoBehaviour {

	public static bool isChatOpen;
	List<string> chatEvents;
	int maxMessagesOnChat = 10;
	void Start ()
	{
		chatEvents = new List<string>();
	}

	public void AddChatEvent(string evt)
	{
		GetComponent<PhotonView>().RPC("AddChatEvent_RPC", PhotonTargets.All, evt);
	}
	
	[RPC]
	void AddChatEvent_RPC(string evt)
	{
		while(chatEvents.Count >= maxMessagesOnChat)
		{
			chatEvents.RemoveAt(0);
		}
		chatEvents.Add(evt);
	}

	void OnGUI()
	{
		GUI.contentColor = Color.black;
		GUILayout.BeginArea(new Rect(0, 0, Screen.width, Screen.height));
		GUILayout.BeginVertical();
		GUILayout.FlexibleSpace();
		foreach(string msg in chatEvents)
		{
			GUILayout.Label(msg);
		}
		GUILayout.FlexibleSpace();
		GUILayout.EndVertical ();
		GUILayout.EndArea();
	}
}

gjf is right, nothing in your script refferences the new GUI elements. Have a look here:

YouTube Search for unity 4.6 ui

EDIT:

That’s more like it :¬) I think your code is working. It’s even likely it’s displaying all messages just really really fast.

What you’re doing is asking the text to change to the next bit of text in your array overwritting the previous.

If you want it all to appear instantly you’ll need to set a string variable and add each line. I’m not near a computer with unity right now so can’t test this but:

private String myString;

then in your foreach…

myString = mySting.ToString() + msg.ToString() + "
";

once the loop finishes

ChatLabelManager.chatLabel.text = myString;

Like I said I can’t test it and you might not need the ToString() as I’m working from memory.

If you want the messages to appear one after another time wise you’ll need to set some delay, but not much point speculating on how you want it to display as it could be anyway.

Oh and the n should be backslash n but backslash seem to vanish.

EDIT 2:

Try

private String display = “”;

Not easy working on this without Unity to check I’m not giving you bad info but I think it’s just not happy with display being null.

EDIT 3:

Well the good news is I now have access to Unity, give me a couple of minutes and I’ll see if I can work out what’s going on. Has the Null Reference been fixed though?

Oh and is that message the last one in your array?

Finally can you post the latest code so we both have the same code to look at?

Thanks

EDIT 4:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

public class DisplayText : MonoBehaviour {

	public Canvas myCanvas;
	public Text myText;

	private string display = "";

	List<string> chatEvents;

	private bool callMe;



	// Use this for initialization
	void Start () {
		chatEvents = new List<string>();

		chatEvents.Add("this ");
		chatEvents.Add (" is ");
		chatEvents.Add (" a ");
		chatEvents.Add (" test ");
		chatEvents.Add (" for ");
		chatEvents.Add (" concatenating ");
		chatEvents.Add (" strings ");
		chatEvents.Add (" and ");
		chatEvents.Add (" displaying ");
		chatEvents.Add(" on ");
		chatEvents.Add(" the ");
		chatEvents.Add (" new ");
		chatEvents.Add (" GUI");

		callMe = true;

	}
	
	// Update is called once per frame
	void Update () {
		if(callMe)
		{
			AddText();
			callMe = false;
		}
	}

	void AddText()
	{
		foreach(string msg in chatEvents)
		{
			display = display.ToString () + msg.ToString() + "

";
}
myText.text = display;
}
}

This works for me, one of the issues is you’ve got the code in Update so it keeps doing it over and over. I took my code out of the update and forced up date to only call it once.

36728-dm-games.png

EDIT 5:

If you use one text area then you’ll get the full list of all messages. If you only want to show the 5 most recent then setup a panel on the canvas with 5 text areas.

When you get the 1st message put it in the first area. Then the second message in the second text area and on until all 5 are full.

When the next message arrives move the text in 2 to 1, 3 too 2, 4 to 3 and 5 to 4. Then put the new message in 5.

I hope that makes sense as I’m again away from a computer with Unity.

EDIT 6:

Well this is embarrassing! Can I work out how to do the smooth transitions on the new GUI. I’ll answer that myself, and the answer is no.

Well this is far more basic than intended but it works bar the logic of showing the last entry. That shouldn’t affect you as you’ll be calling it in a different way.

Basically it has 5 numbered “Buttons” empty gameObjects that are simply place holders.

Then we instantiate a prefab and set the transform to the first then second and so on. If the counter myNumber gets to 6 or more it moves the transform for each object and removes the lowest.

It works by holding a script on the prefab that just holds the prefab number and aligns it with the Button number.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

public class DisplayText : MonoBehaviour {

	public Canvas myCanvas;
	private GameObject myGo;
	private Text myText;
	public GameObject TextPrefab;

	private GameObject curText;
	private int messageNumber = 0;

	private string display = "";
	private string goString;

	List<string> chatEvents;

	private bool callMe;
	private float lastMessageTime;
	private float newMessageTime;

	private GameObject destination;

	public GameObject myPanel;



	// Use this for initialization
	void Start () {
		chatEvents = new List<string>();

		chatEvents.Add("this ");
		chatEvents.Add ("is ");
		chatEvents.Add ("a ");
		chatEvents.Add ("test ");
		chatEvents.Add ("for ");
		chatEvents.Add ("concatenating ");
		chatEvents.Add ("strings ");
		chatEvents.Add ("and ");
		chatEvents.Add ("displaying ");
		chatEvents.Add("on ");
		chatEvents.Add("the ");
		chatEvents.Add ("new ");
		chatEvents.Add ("GUI");

		callMe = true;

	}
	
	// Update is called once per frame
	void Update () {
		if(callMe)
		{
			messageNumber = messageNumber + 1;

			if((messageNumber - 1)<= chatEvents.Count)
			{
				AddText(messageNumber);
				callMe = false;
				lastMessageTime = Time.time;
				newMessageTime = Random.Range(1,4);
			}
		}

		if(Time.time > lastMessageTime + newMessageTime)
		{
			if(messageNumber <= chatEvents.Count - 2)
			{
				Debug.Log(messageNumber + "     " + chatEvents.Count);
				callMe = true;
			}
		}
	}

	void AddText(int myNumber)
	{
		display = chatEvents[myNumber];
		if (myNumber < 6)
		{
			goString = "Button" + myNumber.ToString();
			//Debug.Log (goString);
			curText = GameObject.Find (goString);
			myGo = (GameObject)Instantiate (TextPrefab);
			myGo.transform.SetParent (myPanel.transform);
			myGo.transform.position = curText.transform.position;
			myGo.GetComponent<MyNumber>().MyNo = myNumber;
		}
		else
		{
			for (int i = 1; i <= 5; i++)
			{
				if (i == 1)
				{
					destination = GameObject.Find ("ButtonDead");
					GameObject[] argo = GameObject.FindGameObjectsWithTag("TextPrefab");
					foreach (GameObject go in argo) 
					{
						if(go.GetComponent<MyNumber>().MyNo == 1)
						{
							myGo = go;
							myText = myGo.GetComponent<Text>();
							myText.GetComponent<MyNumber>().MyNo = (i - 1);
							Destroy(myGo);
						}
					}
				}

				if (i > 1)
				{
					GameObject[] argo = GameObject.FindGameObjectsWithTag("TextPrefab");
					foreach (GameObject go in argo) {

						if(go.GetComponent<MyNumber>().MyNo == i)
						{
							myGo = go;
							myText = myGo.GetComponent<Text>();
							Debug.Log (" myText = " + myText.text);
							goString = "Button" + (i - 1);
							destination = GameObject.Find (goString);
							myText.GetComponent<MyNumber>().MyNo = (i - 1);
							myText.transform.position = destination.transform.position;
						}

					}

				}

				if(i == 5)
				{
					curText = GameObject.Find ("Button5");
					myGo = (GameObject)Instantiate (TextPrefab);
					//myGo.transform.SetParent = curText.transform;
					myGo.transform.SetParent (myPanel.transform);
					myGo.transform.position = curText.transform.position;
					myGo.GetComponent<MyNumber>().MyNo = 5;
				}

			}

		}
		display = chatEvents[(myNumber - 1)];
		myText = myGo.GetComponent<Text>();
		myText.text = display;
	}
}

And this is a link to the package so you can see what’s going on:

DM-Games_messages

But as with everything web based virus scan file on download, didn’t have a virus when it left me but once on the web who knows.

Nice to see one of my tutorials made it to the front page of the search list! You can probably adapt my dynamic drop down menu for this purpose

For a scrolling set up I would suggest the following.

  • Create a canvas
  • Add a panel. Size the panel to match the size of your message display. Add a mask component.
  • Make a child panel. Set it as the content of your mask above. Add a scroll rect. Add sliders if you want them. Add a content fitter and a vertical layout group
  • Make a child text element. Add a layout group and size as you see fit. Make this a prefab, and delete it from the scene. (Sometimes it makes sense to give this element a panel and so forth as well).
  • As each message comes in Intantiate a prefab via script. Set its parent to the panel object above. The scrollrect, mask and layout elements will take care of everything else for you.

I recognize the code from Quili18 from the PUN FPS tutorial in the second post by OP. I’had the same need to convert the console text to ui 4.6. This works for me: Youcan test by adding a chat entry on keypress.

The _UIM is a call to a static script tha holds the ui text object.

variables:

	List <string> chatMessages;
	int maxChatMessages = 5;
	private string ChatLine;

	public void AddChatMessage (string m) {
		transform.GetComponent<PhotonView>().RPC ("AddChatMessage_RPC",PhotonTargets.All,m);
		//Component comp = overlayComponent;
	}
	
	[PunRPC]
	void AddChatMessage_RPC (string m) {

		while (chatMessages.Count >=maxChatMessages){//while there are more messages than we want remove oldest entry
			chatMessages.RemoveAt (0);
			_UIM.ui_Online_Console_text.GetComponent<Text>().text ="";//reset the printed text
		}
		chatMessages.Add (m);

		foreach(string msg in chatMessages) {//we print the text
			ChatLine = msg.ToString ()  + '

';
_UIM.ui_Online_Console_text.GetComponent().text += ChatLine;
}