Skip to content

Instantly share code, notes, and snippets.

@tomkail
Created September 7, 2022 09:02
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save tomkail/277b355cb2115fedb159a2387acdb9b6 to your computer and use it in GitHub Desktop.
Better GetRenderedValues for TextMeshPro that doesn't return NaN/other invalid values and allows you to test with custom text
// Gets the tightest bounds for the text by updating the text and using GetRenderedValues
// Note this uses sizeDelta for sizing so won't work when using anchors.
// This is wayyyy more reliable than the actual GetRenderedValues because it won't return stupid values, as GetRenderedValues is prone to doing.
public static Vector2 GetRenderedValues (this TMP_Text textMeshPro, string text, float maxWidth = Mathf.Infinity, float maxHeight = Mathf.Infinity, bool onlyVisibleCharacters = true) {
if(string.IsNullOrEmpty(text)) return Vector2.zero;
var originalRenderMode = textMeshPro.renderMode;
var originalText = textMeshPro.text;
var originalDeltaSize = textMeshPro.rectTransform.sizeDelta;
textMeshPro.renderMode = TextRenderFlags.DontRender;
textMeshPro.text = text;
textMeshPro.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, maxWidth);
textMeshPro.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, maxHeight);
textMeshPro.ForceMeshUpdate(true);
if(text.Length == 0) return Vector2.zero;
// This doesn't work if the component is disabled - but it's better! I'm not even sure this function works while disabled...
// if(textMeshPro.textInfo.characterCount == 0) return Vector2.zero;
// If width/height is Infinity/<0 renderedSize can be NaN. In that case, use preferredValues
var renderedSize = textMeshPro.GetRenderedValues(onlyVisibleCharacters);
if(IsInvalidFloat(renderedSize.x) || IsInvalidFloat(renderedSize.y)) {
var preferredSize = textMeshPro.GetPreferredValues(text, maxWidth, maxHeight);
// I've seen this come out as -4294967000.00 when the string has only a zero-width space (\u200B) with onlyVisibleCharacters true. In any case it makes no sense for the size to be < 0.
preferredSize = new Vector2(Mathf.Max(preferredSize.x, 0), Mathf.Max(preferredSize.y, 0));
if(IsInvalidFloat(renderedSize.x)) renderedSize.x = preferredSize.x;
if(IsInvalidFloat(renderedSize.y)) renderedSize.y = preferredSize.y;
}
bool IsInvalidFloat (float f) {return float.IsNaN(f) || f == Mathf.Infinity || f < 0;}
textMeshPro.renderMode = originalRenderMode;
textMeshPro.text = originalText;
textMeshPro.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, originalDeltaSize.x);
textMeshPro.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, originalDeltaSize.y);
textMeshPro.ForceMeshUpdate(true);
return renderedSize;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment