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!

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 + "

";
// 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);
}

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.

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('

');

	foreach(string line in lines){
		textMesh.text += wrapLine(line, wantedWidth);
		textMesh.text += "

";
}
}

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*;*
  •  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(" ", "

");
}

			word = "";
			wordWidth = 0;
		} 
		
		word += c.ToString();
		wordWidth += charWidth;
	}
	
	textMesh.text = oldText;
	return newText;
}*

```

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('

'[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 + "

";
line = s;
}
else
{
line = temp;
}
}

		result += line + "

";

	}

	return result;
}

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/