Modifying TMPro Text Through Code Does Not Apply Unicode Fallback

I spent an evening creating an emoji setup but when I finished I noticed that if in my game’s chat messages players used an emoji’s name such as :thinking_face: it would grab the correct unicode value from my dictionary but just end up writing \U0001f914 into chat instead of replacing it with the emoji in the sprite sheet.

If I click pause while the chat message is up and I click anything in the inspector for the TextMeshProUGUI object, it immediately replaces the unicode value with the emoji. I thought maybe I was just missing some sort of parsing feature by directly modifying the .text member of the object in code so I used SetText instead and still no luck.

After that I tried SetAllDirty in hopes it would trigger an update and even tried triggering it a few frames later to see if that would have the same effect as clicking anything in the inspector (even “enable rtl editor” would cause the emoji to properly parse).

I’m assuming this is a bug of sorts or I’m missing some sort of “refresh text object” function that would replace unicode values written out with their actual characters.

Just to make sure I understand correctly. You are setting the text property of the text using something like

TMP_Text textComponent = GetComponent<TMP_Text>();
textComponent.text = "X\U0001F600X";

and instead of the correct sprite / emoji showing up, you get the unicode string instead?

Can you provide a simple script that I could add to a text object to reproduce the behavior you are reporting?

I just decided to use instead as I could not get unicode to work.

public static string GetEmojiUnicode(string emojiName)
    {
        if (!nameToEmojiUnicode.ContainsKey(emojiName))
            return emojiName;

        //return "<size=20><sprite name=\"" + nameToEmojiUnicode[emojiName] + "\"></size>";

        var unicode = nameToEmojiUnicode[emojiName];
        var zeroCount = 8 - unicode.Length;

        var sb = new StringBuilder(@"\U", 10);
        sb.Append('0', zeroCount);
        sb.Append(unicode);
     
        return "<size=20>" + sb.ToString() + "</size>";
    }

\U on its own gives an invalid escape character error, using \U instead of the string literal @ does not fix it either.

Using a string literal or “\U” results in C# processing the string as a literal instead of converting it to the correct UTF32 character.

“\U” or “\u” on their own is invalid as C# expects the “\U” to be followed by 4 hex pairs and “\u” by two hex pairs.

Your dictionary should contain / replace the emoji name by the full unicode which “\U0001F600” and not just the “0001F000”.

This bug is still present in Unity 2021.1 using TextMeshPro 3.0.6.

Setting a the text of a TextMeshProUGUI component in a script will not properly display unicode characters until the editor is interacted with.

Is there a work around for this?

3 Likes

+1

I have the same problem. No unicode formatting until I change the text in the inspector.

My setup is a script that displays an int, with a prefix and a suffix indicated in the inspector.

public class UIDisplayInt : UIDisplay<int>
{
    [SerializeField] private string _prefix;
    [SerializeField] private string _suffix;
    [SerializeField] private TMP_Text _text;

    protected override void OnRefresh(int value)
    {
        _text.SetText($"{_prefix}{value}{_suffix}");
    }
}

Did anybody find a solution for this? I am passing strings from a TextFile with Unicode included and it always shows the unicode in the TextMeshPro until I interact with it in the editor…
Is there a method to update the TestMeshPro in Script so that it Refreshes the text content to understand unicode?
Please help out!

Same issue here. Looking at the source for TMP_Text, unicode characters are intentionally only handled when the text is changed via the inspector. (I.e., only when the textmesh’s internal m_inputSource enum is set to TextInputBox.) Attempting to set the text through code changes m_inputSource to TextString which bypasses unicode handling.

A way around this is to manually unescape the unicode characters before assigning them to the textmesh:

string content = @"\uF4F5";
content = Regex.Unescape(content);
textMesh.text = content;

A downside to this approach is your now unescaped unicode characters may be invisible in the inspector text box, but they’ll render fine in-game. A formal fix to this problem would still be very appreciated!

11 Likes

Omg. This is unbelievable. I just spent 2 days troubleshooting why Font Awesome icons were not working through script, while working fine in the editor.

** @rscopic **, you are my hero. :heart:

How could this possibly not be fixed by now? ** @Stephan_B **, please look in to it.

Search tags for my fellow googlers:
“TMP_SubMeshUI using wrong font after text update through script”, “TextMeshPro reverting to default font”

Stephan doesn’t work on TMP anymore . You should submit a bug report instead.

1 Like

Thank f for that <3 works for me in (latest TMPro 3.0.6, unity 2022.3.8f1)

Issue still hasn’t been officially resolved in 2023

I have same issue but partly… If I apply some FA icons trought script they work but if I set them to \uf06a or \uf05a they apply as charachters?
Edit: It seems it work if you go tmp.text = “\uxxxx” or variable assign but only if variable is assigned on start and hardcoded u can’t edit variable in editor, if you do it displays chars.

1 Like

Same problem here, very annoying

just doing the Regex.Unescape partially work to get around the problem with unicode like this “\uE61F” but not for unicode like this “\U000F1901” with elements in UTF 32, i have tried to use other way to encode/decode but with no success :frowning:

This forum post from 2017 __ unicode value shows as string litera l__ has an answer from @Stephan_B at the bottom. Extracted the string conversion portion, added below. In my case I have a single unicode character, set via inspector. I didn’t test the UTF-32 portion, hopefully that works just as well.

// UTF 16
char.ConvertFromUtf32(int.Parse(unicodeCharacterString.Replace("\\u", ""), System.Globalization.NumberStyles.HexNumber));

// UTF 32
char.ConvertFromUtf32(int.Parse(unicodeCharacterString.Replace("\\U", ""), System.Globalization.NumberStyles.HexNumber));

I don’t know why nobody has mentioned this yet, but if you just need to make changes in your text while the game is running, try to call emojis by indexes instead of Unicodes by It works for me.

image