string builder = "";
TextMesh.text = "";
float rowLimit = 1.9f; //find the sweet spot
string text = "This is some text we'll use to demonstrate word wrapping. It would be too easy if a proper wrapping was already implemented in Unity :)";
string[] parts = text.Split(' ');
for (int i = 0; i < parts.Length; i++)
{
Debug.Log(parts*);*
TextMesh.text += parts + " "; if (TextMesh.renderer.bounds.extents.x > rowLimit) { TextMesh.text = builder.TrimEnd() + System.Environment.NewLine + parts + " "; } builder = TextMesh.text; }
I liked Hudi’s answer so much I made it in to a reusable class. Just attach to any TextMesh, then set public properties:
UnwrappedText = Set this instead of TextMesh.Text.
MaxWidth = Max width you want to allow
NeedsLayout = Reset to true anytime you modify anything that requires a recalculation to be done (font size, UnwrappedText property, MaxWidth, etc)
ConvertNewLines = Just makes it so you can type
in the Unity editor to get a new line character.
Edit: I added the BreakPartIfNeeded code because the original version wasn’t breaking in the middle of a word if needed, and then it was also causing every word after that to cause a break because the mesh extents were too wide. You can bypass the BreakPartIfNeeded if you are positive you do not need, and you want the code to be more optimized.
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(TextMesh))]
public class SmartTextMesh : MonoBehaviour
{
TextMesh TheMesh;
public string UnwrappedText;
public float MaxWidth;
public bool NeedsLayout = true;
public bool ConvertNewLines = false;
void Start()
{
TheMesh = GetComponent<TextMesh>();
if (ConvertNewLines)
UnwrappedText = UnwrappedText.Replace("\
", System.Environment.NewLine);
}
string BreakPartIfNeeded(string part)
{
string saveText = TheMesh.text;
TheMesh.text = part;
if (TheMesh.renderer.bounds.extents.x > MaxWidth)
{
string remaining = part;
part = "";
while (true)
{
int len;
for (len = 2; len <= remaining.Length; len++)
{
TheMesh.text = remaining.Substring(0, len);
if (TheMesh.renderer.bounds.extents.x > MaxWidth)
{
len--;
break;
}
}
if (len >= remaining.Length)
{
part += remaining;
break;
}
part += remaining.Substring(0, len) + System.Environment.NewLine;
remaining = remaining.Substring(len);
}
part = part.TrimEnd();
}
TheMesh.text = saveText;
return part;
}
void Update()
{
if (!NeedsLayout)
return;
NeedsLayout = false;
if (MaxWidth == 0)
{
TheMesh.text = UnwrappedText;
return;
}
string builder = "";
string text = UnwrappedText;
TheMesh.text = "";
string[] parts = text.Split(' ');
for (int i = 0; i < parts.Length; i++)
{
string part = BreakPartIfNeeded(parts*);*
TheMesh.text += part + " "; if (TheMesh.renderer.bounds.extents.x > MaxWidth) { TheMesh.text = builder.TrimEnd() + System.Environment.NewLine + part + " "; } builder = TheMesh.text; } } }
You’ll need to encapsulate your text and determine your own line-length unfortunately. From there it’s pretty simple though, just insert
in your text and TextMesh will wrap the line. Each character is going to occupy a certain space in your screen space; and there are a lot of different ways you might measure or break the line. Might be easiest to delimit on the space character and wrap words greedily.