How to support any Unicode character in TMPro?

I am building an app for a client and a requirement is that users are able to choose a name that contains any Unicode character. I need to be able to render these names on mobile with a text stroke/outline while moving and resizing the text object every frame.

Obviously, building an SDF atlas that supports every Unicode character unfeasible.

Currently, I am using the built-in text system because I have been unable to make this work with TMP, however, it looks bad and performs worse.

I’m hoping I’ve missed something in my googling and that there’s a way for TMP to support this.

1 Like

Creating a dynamic font asset that can handle every single Unicode character contained in a font file takes less than 30 seconds. See the following post and linked videos for more information.

For best overall performance, it is still recommended that you use static font assets for all the known text in the project for any given language or groups of language and then to handle unknown characters typically coming from user input, create and use dynamic font assets assigned as fallback to those primary static font assets. Again this is explained in those videos linked above.

1 Like

Thanks for the response. The video has helped for sure.

From what I’m understanding after playing with the dynamic font asset system, the only way for me to support a very large number of Unicode characters from different languages would be for me to locate and bundle with my app a large number of font assets to cover different languages, symbols, etc.

Is there any way using TMP to fallback to searching installed system fonts for a valid glyph in the same way that the built-in Unity solution does?

Most languages can be covered by a few font files. For instance and as per those videos, to cover all Latin language + Cyrillic + CJK + Vietnamese, Thai is 3 font files from the NotoSans or NotoSerif font family. Again, selecting the right font file is the key. As shown in the video, you can find font files on Google/Fonts by language.

Yes. See the following post .

1 Like

Hi Stephan,
First, thanks so much for your timely responses. You’ve been an enormous help for me.

I used the method you outlined in your last post for my app, it worked great during initial development. The issue however is obviously the memory weight of loading every font on the system (especially considering I must store them in memory twice, once for UI texts and one for world texts). It’s simply not feasible for mobile devices.

I’ve spent a good amount of time trying to create a system that would search the fonts of the system for a font that contained a missing character that I am trying to display. The place where I have hit a roadblock is I have been unable to find a way to determine what fonts contain what glyphs without actually creating a FontAsset from them.

I am desperately looking for any insight on how to check what fonts contain what glyphs without having to load them into texture memory.

I have the exact same issue as my app is running out of memory now

@Stephan_B I am desperately looking for any insight on how to check what fonts contain what glyphs without having to load them into texture memory.

The only way to determine if a specific character (unicode) is present in a font file is to load that font file and to check if a glyph is assigned to the specific Unicode.

To do this, you could do the following:

FontEngine.LoadFontFace(fontFilePath);

// Get the index of the glyph for the given Unicode.
// If a glyph has been assigned to this Unicode, the index will be a value > 1. Otherwise, the glyph index will be 0 which is the missing glyph index.
uint glyphIndex = FontEngine.GetGlyphIndex(unicode);

Assuming you are trying to find a system / OS font that contains the specific Unicode character, you will need to load each font file and then try GetGlyphIndex().

This will result in loading each font file into memory but it will not create a font object.

Once you have located a font file with the specific characters you need, you should call FontEngine.DestroyFontEngine() to release these from memory and then create a font object using the path of the font file that contains the desired characters.