Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by DM-Games · Dec 09, 2014 at 08:47 AM · uiliststringchat

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();
     }
 }
 
Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image gjf · Dec 09, 2014 at 10:13 AM 0
Share

where's your code for the new UI? OnGUI() is the legacy stuff...

avatar image DM-Games · Dec 09, 2014 at 03:13 PM 0
Share

Ok i think i found an answer myself

avatar image DM-Games · Dec 09, 2014 at 03:23 PM 0
Share

So i tried it like this but it didn't show a list of messages it showed only the latest message in the list

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine.UI;
 
 public class Chat$$anonymous$$anager : $$anonymous$$onoBehaviour {
 
     public static bool isChatOpen;
     List<string> chatEvents;
     int max$$anonymous$$essagesOnChat = 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 >= max$$anonymous$$essagesOnChat)
         {
             chatEvents.RemoveAt(0);
         }
         chatEvents.Add(evt);
     }
 
     void Update()
     {
         foreach(string msg in chatEvents)
         {
             ChatLabel$$anonymous$$anager.chatLabel.text = msg;
         }
     }
 }
 

3 Replies

· Add your reply
  • Sort: 
avatar image
4

Answer by Mmmpies · Dec 09, 2014 at 12:02 PM

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() + "\n";

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() + "\n";
         }
         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.

alt text

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.


dm-games.png (24.9 kB)
Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DM-Games · Dec 09, 2014 at 04:48 PM 0
Share

Ok, thanks i'll try that

avatar image DM-Games · Dec 09, 2014 at 04:54 PM 0
Share

Ok i tried your answer:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine.UI;
 
 public class Chat$$anonymous$$anager : $$anonymous$$onoBehaviour {
 
     public static bool isChatOpen;
     List<string> chatEvents;
     int max$$anonymous$$essagesOnChat = 10;
     private string display;
     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 >= max$$anonymous$$essagesOnChat)
         {
             chatEvents.RemoveAt(0);
         }
         chatEvents.Add(evt);
     }
 
     void Update()
     {
         foreach(string msg in chatEvents)
         {
             display = display.ToString() + msg.ToString() + "n";
             ChatLabel$$anonymous$$anager.chatLabel.text = display;
         }
     }
 }


But it gave me an error:NullReferenceException: Object reference not set to an instance of an object Chat$$anonymous$$anager.Update () (at Assets/Scripts/Chat$$anonymous$$anager.cs:36)

avatar image DM-Games · Dec 09, 2014 at 05:22 PM 0
Share

It doesn't work still it just spams the chat with the messages

Screenshot:

alt text

chaterror.png (312.8 kB)
avatar image DM-Games · Dec 11, 2014 at 02:29 PM 0
Share

That kind of works but it doesn't still show properly... When i add a new message it does show the old messages again for some reason.

Code:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine.UI;
 
 public class Chat$$anonymous$$anager : $$anonymous$$onoBehaviour {
 
     public static bool isChatOpen;
     List<string> chatEvents;
     int max$$anonymous$$essagesOnChat = 10;
     private string display = "";
     private bool newEvent = false;
     private 
     void Start ()
     {
         chatEvents = new List<string>();
     }
 
     public void AddChatEvent(string evt)
     {
         GetComponent<PhotonView>().RPC("AddChatEvent_RPC", PhotonTargets.All, evt);
         newEvent = true;
     }
     
     [RPC]
     void AddChatEvent_RPC(string evt)
     {
         while(chatEvents.Count >= max$$anonymous$$essagesOnChat)
         {
             chatEvents.RemoveAt(0);
         }
         chatEvents.Add(evt);
     }
 
     void Update()
     {
         if(newEvent == true)
         {
             UpdateChat();
             newEvent = false;
         }
     }
 
     void UpdateChat()
     {
         foreach(string msg in chatEvents)
         {
             display = display.ToString() + msg.ToString() + "\n";
             ChatLabel$$anonymous$$anager.chatLabel.text = display;
         }
     }
 }


Screenshot: alt text

chaterror2.png (8.3 kB)
avatar image Mmmpies · Dec 11, 2014 at 08:12 PM 0
Share

Now I've got access to Unity for a couple of hours (before bed anyway!). There are lots of ways of achieving the kind of thing you want but the method you want to use will dictate how the text appears.

Any method I'd recommend using the new GUI because it's faster and far more professional.

So what do you want to do with your text? Do you want to be able to scroll back through all items or just have 5 (or any other number) on screen at any one time? Do you want the text just to pop into place and move the previous messages upwards as I suggested? Or do you want fancy pants text scrolling smoothly up with the earliest message fading out whilst the latest message flashes into place with a subtle combination of color and size changes?

There are some fairly easy ways to implement any of these but depending what you want you'd have to take a different approach to the setup.

To scroll back through all time you'd need a scroll panel, for the method I mentioned earlier for 5 messages you just need 5 Text components stacked on top of one another like floors in a skyscraper. For the fancy pants you'd create a new Text object for the bottom most and alter the RectTransform of the buttons above so they scroll upwards. Fading out the top one then destroying it.

Really if you're still having trouble let me know how you want your text to appear/vanish and what lifespan you need (for the text - not you!) and I'll try to find a workable solution.

If you think you're O$$anonymous$$ just mark this as answered. I'd still get email updates if you marked it as answered and then updated if you run into trouble.

Show more comments
avatar image
0

Answer by Kiwasi · Dec 13, 2014 at 07:15 AM

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.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DM-Games · Dec 13, 2014 at 10:06 AM 0
Share

Sorry, but i think i am gonna go with the legacy gui... Cause this is just too much work

avatar image Mmmpies · Dec 13, 2014 at 11:21 AM 0
Share

O$$anonymous$$ @D$$anonymous$$-Games, I'm going to post a script later to show you how to do this on the new GUI, some of it ties in with what I'll need anyway so I might as well post it. Just gonna take an hour or so.

avatar image DM-Games · Dec 13, 2014 at 02:26 PM 0
Share

Unity should probably implement an chat component to their new gui system

avatar image Kiwasi · Dec 13, 2014 at 06:53 PM 0
Share

@D$$anonymous$$-Games You are not likely to see a Unity implemented chat components. A chat system can be implemented too many different ways for Unity to try make a single component. But you may see various chat systems turn up on the asset store.

avatar image
0

Answer by TooManySugar · Jun 06, 2016 at 05:11 AM

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 ()  + '\n';
             _UIM.ui_Online_Console_text.GetComponent<Text>().text += ChatLine;
         }


Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Doctor_Uair · Sep 29, 2016 at 08:58 AM 0
Share

Just curious, what did you put in the _UI$$anonymous$$ script? I'm trying what you put with some alteration to fit the missing script but without that script I keep running into an issue where messages repeat every time I press the send button.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

A node in a childnode? 1 Answer

Update List<> in editor 0 Answers

Is it possible to name a list by a string variable? 2 Answers

How do I make a list of lists? 2 Answers

Cannot convert string to int. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges