I’m making a console for my game and I recently faced one problem. I added lot’s of information to the string and then displayed that information inside UI text. The problem is that the string became too long for TextMeshGenerator. So I came up with some solution. To set maximum characters for each string and when the string reaches that maximum amount create new UI text. The issues is that how do I split / cut the string? For example I need to add 1000 characters to the string so I, add for example 800 of characters until the first string is full (reached max amount of characters) and I add the rest 200 of the characters to the new created string.
Can someone give me some tips on how to achieve this? Thank you!
Also how much characters UI text / string can contain, until it starts to give errors?
I am not aware of the limitations for text objects but what could help is to create a text object for each of your logs.
I am not aware of how your system works but by limiting by character count you will have a weird split and your text will be cut in the mid
dle of the sentence.
You could split your text by line and check if each line fits into your limit. Example:
int MaxLength = 1000;
string fulltext = "";
int count=0;
string[] lines = fulltext.Split('\n');
string output = "";
foreach (var line in lines)
{
if (count + line.Length >= MaxLength)
{
//Write line and resets next line
WriteLine(output);
count = line.Length;
output = line;
}
else
{
count += line.Length;//maybe +2 for \n ?
output += "\n" + line;
}
}
Thank you for the reply! I’m not really familiar with this, can you explain what that \n means?
Also this is the script that add’s the text to the console:
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.ImageEffects;
using System.Collections.Generic;
public class ConsoleManager : MonoBehaviour {
public static ConsoleManager instance;
ConsoleDataReciever info = new ConsoleDataReciever();
public bool useConsole;
[SerializeField] private InputField inputField;
[SerializeField] private RectTransform ConsoleMessage;
[TextArea (2,2)]
[SerializeField] private string lineBreak;
private string _ConsoleContent; // info
public int max = 65000; // Maximum length of the string
[SerializeField] private Text container;
[SerializeField] private RectTransform newContainer;
[SerializeField] private RectTransform holder;
void Awake ()
{
instance = this;
}
void Update ()
{
if(Input.GetKeyDown(KeyCode.KeypadEnter))
{
SubmitData();
}
}
public void SubmitData ()
{
ExecuteCommand.instance.SendMessage(inputField.text.ToString(), info, SendMessageOptions.DontRequireReceiver);
if (inputField.text != "")
if(!info.dataRecieved)
{
WriteConsoleMessage.instance.Log(inputField.text.ToString(), "", LogType.Log);
}
reset();
}
public void AddConsoleMessage (string data)
{
if (data == "") return; // Check if new message is not an empty string, if so return from this function.
string newMessage = lineBreak + data + lineBreak + "</color>"; // Create complete new message string.
_ConsoleContent += newMessage; // Add new text to content string.
container.text = _ConsoleContent; // Display in text.
}
}
\n means new line, so “text\nline” would look like this:
text
line
I see how you did that, creative See how I defined lineBreak, you can also simply hard code “\n”;
Btw the Text object has a limit due to vertex count. Each character is rendered as a quad and this is where the limit comes from. So there might be no specific answere, but I was able to get a bit more than 1200 Characters.
If you don’t have 1000 Log entries then you could simply create one Text Object for each log. Otherwise the method I used in the first example would reduce the amount of Text Objects. The downside is that you have to organize your Text objects. Either you hard code their position or you use a VerticalLayoutGroup object.
I changed your Text objects to a container. It might be optional for _ConsoleContent but it can help to sort things out. If you use string _ConsoleContent then the line lineBreak + data + lineBreak would be correct. You can setup the textPrefab so that it has the padding included.
private List<string> _ConsoleContent; // info
Hope that is not too confusing now, you should look more into UI objects, they are well suited for these kind of things.
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.ImageEffects;
using System.Collections.Generic;
public class ConsoleManager : MonoBehaviour
{
public static ConsoleManager instance;
ConsoleDataReciever info = new ConsoleDataReciever();
public bool useConsole;
[SerializeField] private InputField inputField;
[SerializeField] private RectTransform ConsoleMessage;
private const string lineBreak = "\n";
private List<string> _ConsoleContent; // info
[SerializeField] private Text textPrefab;
private List<Text> textContainer;
[SerializeField] private RectTransform newContainer;
[SerializeField] private RectTransform holder;
void Awake()
{
instance = this;
const int cap = 64; //Just some minor optimization, you don't have to add the capacity parameter
_ConsoleContent = new List<string>(cap);
textContainer = new List<Text>(cap);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.KeypadEnter))
{
SubmitData();
}
}
public void SubmitData()
{
ExecuteCommand.instance.SendMessage(inputField.text.ToString(), info, SendMessageOptions.DontRequireReceiver);
if (inputField.text != "")
if (!info.dataRecieved)
{
WriteConsoleMessage.instance.Log(inputField.text.ToString(), "", LogType.Log);
}
reset();
}
public void AddConsoleMessage(string data)
{
if (data == "") return; // Check if new message is not an empty string, if so return from this function.
string newMessage = data + "</color>"; // Create complete new message string.
_ConsoleContent.Add(newMessage); // Add new text to content string.
CreateNewTextObject(newMessage);
}
void CreateNewTextObject(string text)
{
//I assume that newContainer is where your text is placed
//It should be within a scroll rect object maybe and a vertical layout group
var obj = Instantiate(textPrefab, newContainer, false);
obj.text = text;
textContainer.Add(obj);
}
}
Thank you very much for your help!
I implemented some of the things you wrote and now everything works great! One problem occurred, but I think I fixed it. After adding/creating a lot of text, the console became laggy… I found the solution by adding ‘Rect Mask 2D’. I also implemented the clear console function. Before adding the message I check the entire length of the console and if necessary I clear the console by deleting everything. Now the console seems to be not laggy at all. Only except when there is a lot of text and I try to resize it. Then It’s quite laggy. But I 'm not sure what to do about it… I’m pretty sure I know why. I think it’s because when I resize the console the text also adapts to the size of the console.