- Home /
Wrapping a Textmesh text
Hi,
How do I wrap a Textmesh text? For example, I want it not to be longer than 3 meters. Than I have a script which picks some text and I need it to automatically break it in more lines if it's longer than 3 meters.
Thanx!
Answer by jindave · Mar 28, 2012 at 06:24 PM
Hi here is my code:
// Wrap text by line height
private string ResolveTextSize(string input, int lineLength){
// Split string by char " "
string[] words = input.Split(" "[0]);
// Prepare result
string result = "";
// Temp line string
string line = "";
// for each all words
foreach(string s in words){
// Append current word into line
string temp = line + " " + s;
// If line length is bigger than lineLength
if(temp.Length > lineLength){
// Append current line into result
result += line + "\n";
// Remain word append into new line
line = s;
}
// Append current word into current line
else {
line = temp;
}
}
// Append last line into result
result += line;
// Remove first " " char
return result.Substring(1,result.Length-1);
}
This works well for unispace fonts, but does anyone have a similar solution for other fonts? I'm thinking about trying to use the bounds of the mesh and maybe splitting each line into a separate mesh at runtime, assu$$anonymous$$g that's not too expensive.
Answer by thienhaflash · Jun 18, 2012 at 04:54 PM
Basically there are no way to get an abitrary TextMesh's size without rendering it. I wrap the code that render and cache the characters dynamically to improve performance, so each character will be render only once when it is first used. One good thing is this approach will provide very accuracy result (100% correct). You can use my class below :
https://dl.dropbox.com/u/10796188/wp/unity/TextSize.cs
I don't have enough time to make a sample package so i put a sample inside the file itself, hope that it's clear enough for you (a bit too long to post the whole file here).
You can use the above method to get the size of any string, it's really cheap because all those chars' size are already cached.
That's...ingenius! I'm adding yoru code to my common stock! :D
This was incredibly useful, thanks a lot =] Added two functions to help wrap text.
First of all I cannot believe there is not built in less hacky way to do this as part of the Text$$anonymous$$esh features.
@thienhaflash I plugged in your script and it seems to work reasonably well thanks.
However I am running into problems with consistency and I think it has to do with the fact that this only works if the Text$$anonymous$$esh is not scaled or rotated. Oddly, though, the only change in scale or rotation that I use should not be affecting the x axis size in the world.
Sorry for necro-posting, but if I needed this answer, then others will too. I found what I believe to be the file that is linked above: https://github.com/$$anonymous$$ystfit/TeslaRift/blob/master/TeslaRift-Unity/Assets/Scripts/Visuals/TextSize.cs
Please correct me if this is the incorrect file.
Answer by masha · Dec 16, 2013 at 03:00 PM
Used thienhaflash's solution which works great and added the following two functions to the class, in order to make wrapping even easier.
public void FitToWidth(float wantedWidth) {
if(width <= wantedWidth) return;
string oldText = textMesh.text;
textMesh.text = "";
string[] lines = oldText.Split('\n');
foreach(string line in lines){
textMesh.text += wrapLine(line, wantedWidth);
textMesh.text += "\n";
}
}
private string wrapLine(string s, float w)
{
// need to check if smaller than maximum character length, really...
if(w == 0 || s.Length <= 0) return s;
char c;
char[] charList = s.ToCharArray();
float charWidth = 0;
float wordWidth = 0;
float currentWidth = 0;
string word = "";
string newText = "";
string oldText = textMesh.text;
for (int i=0; i<charList.Length; i++){
c = charList[i];
if (dict.ContainsKey(c)){
charWidth = (float)dict[c];
} else {
textMesh.text = ""+c;
charWidth = renderer.bounds.size.x;
dict.Add(c, charWidth);
//here check if max char length
}
if(c == ' ' || i == charList.Length - 1){
if(c != ' '){
word += c.ToString();
wordWidth += charWidth;
}
if(currentWidth + wordWidth < w){
currentWidth += wordWidth;
newText += word;
} else {
currentWidth = wordWidth;
newText += word.Replace(" ", "\n");
}
word = "";
wordWidth = 0;
}
word += c.ToString();
wordWidth += charWidth;
}
textMesh.text = oldText;
return newText;
}
Answer by AlfredDuler · Oct 08, 2013 at 07:58 AM
What happen if you're importing formated text from let's say a database, and there are already some line break in the text?
You got unwanted line break because de nbr of characs doesn't increase with line break.
This was my problem, so I used the function gave by jindave and came with this one.
note: I'm not a proffessional dev so it might be ugly code, but I think it could help some novices.
It's obviously in Javascript:
function ResolveTextSize( input : String, lineLength : int): String
{
var linesRetrieved : String[] = input.Split('\n'[0]);
var result : String= "";
for ( var actualLine : String in linesRetrieved )
{
var words : String[] = actualLine.Split(" "[0]);
var line : String = "";
for(var s : String in words)
{
var temp : String = line + " " + s;
if(temp.Length > lineLength)
{
result += line + "\n ";
line = s;
}
else
{
line = temp;
}
}
result += line + "\n";
}
return result;
}
Answer by Sun-Pengfei · Mar 02, 2017 at 06:40 AM
TextGenerator textGen = new TextGenerator();
TextGenerationSettings generationSettings = textCompo.GetGenerationSettings(textCompo.rectTransform.rect.size);
float width = textGen.GetPreferredWidth(text, generationSettings);
if (width > preferedWidthMax)
{
layoutElement.preferredWidth = preferedWidthMax;
}
This is the most elegant way I've found to this problem. Note that the text's parent has a content size fitter and a layout group components, and the text itself has a layout element.
Check the other related question:
https://forum.unity3d.com/threads/wrapping-child-text-with-content-size-fitter.315630/
http://answers.unity3d.com/questions/921726/how-to-get-the-size-of-a-unityengineuitext-for-whi.html
Your answer uses textCompo.rectTransform, but Text$$anonymous$$esh doesn't have a rectTransform.
The linked answers are for UnityEngine.UI.Text, but the question was for UnityEngine.Text$$anonymous$$esh.
Your answer
Follow this Question
Related Questions
How to calculate a TextMesh width without rendering it ? 2 Answers
I can't change the text mesh 1 Answer
Adjusting the transform width to match wrapped text (TextMeshPro) 0 Answers
Unity crashes at writing TextMesh? 0 Answers
Text Mesh to Mesh ? 2 Answers