- Home /
TextMesh.renderer.bounds.extents not 100% accurate?
I've been looking for a better way of getting the size of a TextMesh object, but every answer I've found relies on using it's renderer.bounds.center/extents properties. This works in general, but fails to give as precise results as other object's bounds properties.
I was expecting that the bounds box would perfectly wrap around the quads that make up the TextMesh, but as you can see that is not the case. Also, I've noticed that modifying the LineSpacing property will change the box in unpredictable ways.
I'd hate to find another text solution because it otherwise works like I'd expect it to. Has anybody else noticed this and found a way to get accurate results or am I not understanding something about TextMesh?
Ideas to explore rather than a known solutions: you might take the $$anonymous$$esh.bounds and move it into global space and compare it to the one the renderer uses. It is possible the $$anonymous$$esh.bounds is more accurate. Another idea is to produce your own bounding box by evaluating the vertices. It is also possible the problem is unused vertices that you could prune from the mesh. I could see the Text$$anonymous$$esh code keeping a set of start vertices to use for the next character that never got used.
From what I can see and have read it seems that there is no way to get the mesh that makes up the Text$$anonymous$$esh, so mesh.bounds and looking at mesh vertices is out. Thanks for the reply, though.
Strange. I learned something. I wonder why they did not expose the mesh.
Answer by AlkisFortuneFish · Feb 04, 2014 at 07:07 PM
I know it's been a VERY long while since this question was asked, but I think I've just found the answer, after a two hour headache of fonts disappearing when partially off screen and vertical anchor settings being ignored...
The height of the renderer bounding box is set by the line spacing of the .fontsettings asset multiplied by the TextMesh character size and line spacing.
The TextMesh line spacing assumes space under each character, so if it is set to 1, your bounds will be twice the font line height, even if you only have one line of text.
Bounds height = 2*(Number of Lines)(Asset Line Spacing)(TextMesh Line Spacing)*(TextMesh Character Size)
Edit: That headache was worse than I thought... This should be:
The TextMesh line spacing assumes space under each character, so if it is set to 2, your bounds will be twice the font line height, even if you only have one line of text. If your asset's line spacing is wrong, it'll all be wrong.
Bounds height = (Number of Lines)(Asset Line Spacing)(TextMesh Line Spacing)*(TextMesh Character Size)
The asset line height should automatically be calculated for font assets generated by the TrueTypeFontImporter, while for custom fonts it should manually be set.
If you have a custom font, draw the renderer bounds, make sure that the text mesh line spacing is set to 1 and modify the font asset's line spacing until the bounding box perfectly covers the tallest letter in your font.
Oh, also, to get the asset line spacing for a font imported using the TrueTypeFontImporter, since it does not publicly expose this, or in fact to set it via script, you can grab it using serialized properties, as per here.
SerializedObject so = new SerializedObject(customFont); Debug.Log(so.FindProperty("m_LineSpacing").floatValue);
Hi Alkis - it has been some time since I've used Text$$anonymous$$esh, I've pretty much abandoned trying to find the answer I was looking for and moved on to other text solutions since. I appreciate your looking into it, but am a bit confused regarding your answer. I was looking for a way to get a bounding box that better represented the actual mesh of the Text$$anonymous$$esh, but it sounds like you're trying to reconstruct the way Unity calculates the bounding box - which is what gives flawed/confusing results. If you could arrive at a method that would result in a center, width, and height for a box that's more accurately wrapped around the Text$$anonymous$$esh quads then I'd consider this question answered.
Either way, I tried testing your approach to try and verify if the bounding box height is at least calculated the way you've outlined, but am not getting anywhere near the correct results (maybe I misunderstood something). If you'd like I could join you in the forums to discuss the details, just create a thread and post a link if you're interested (to keep this page more on-topic with the question). Cheers!
Answer by trul · May 17, 2015 at 08:07 PM
Hey, it looks like they have fixed this issue (in 4.6.4f1). The bound box is calculated good enough. The green filled rectangle is visualization for the calculated bounds. This is how it is calculated:
public void UpdateSize(Bounds bounds)
{
transform.position = bounds.center;
SpriteRenderer sr = GetComponent<SpriteRenderer>();
float sx = bounds.extents.x/sr.bounds.extents.x;
float sy = bounds.extents.y/sr.bounds.extents.y;
transform.localScale = new Vector3(transform.localScale.x*sx, transform.localScale.y*sy,1f);
}
BTW, are there better solution for displayed text in unity than TextMesh? UI text is not flexible enough for my purposes.
Thx! This helped me to place a backgroud behind a Text$$anonymous$$esh by code..