TextMeshPro does not evaluate unicode fallback font when setting dynamic text?

I’m using strings with unicode characters to show controller icons in tutorials. A string would be for example "Hold \U00100a47 to run.", where \U00100a47 maps to a character in a fallback font that represents for example the action button on a controller.

188489-hold-to-run-correct.png

This works fine when I paste the string into the TextMeshPro UGUI component it in the Inspector, however it does not work when I set the string dynamically at runtime via

myText.text = "Hold \U00100a47 to run.";

If I do that, then the text will appear just like the string, with the unicode sequence appearing as plain text.

188490-hold-to-run-broken.png

What do I need to do to make TMP update the mesh and evaluate the unicode correctly?

Ok, dug into TMPro’s code a bit and it turns out that if you enter a string via the inspector, some code parsing happens under the hood that does not happen when you set a string directly via tmpLabel.text = "..". If entered into the inspector, TMPro will actually convert the escape sequence to the specific UTF32 character and use that for rendering. It uses a bunch of private int array classes to represent the string, so it’s pretty hard to recreate the code from the outside.

!!

BUT

!!

It turns out that you can force the same parsing by calling the TMPro label’s OnValidate method after setting the string. Since that method is private too, I had to use reflections.

myTutorialLabel.text = GetTutorialString(); // set the string containing the escape sequence
 
// now call myTutorialLabel.OnValidate() via reflection
var onValidate = typeof(TextMeshProUGUI).GetMethod("OnValidate", 
    System.Reflection.BindingFlags.Instance 
    | System.Reflection.BindingFlags.NonPublic);
onValidate.Invoke(myTutorialLabel, null);

This is pretty hacky. It would be nice if TMPro allowed a simple use of their text parsing from the outside…