Unity Text Shows Squares Instead of Characters: Font Fallback That Just Works
Last reviewed
Squares, boxes or blank spaces appear when the font asset a text uses has no glyph for a character and nothing in its fallback chain does either. In TextMesh Pro every language needs a font asset with that language's characters, added to a fallback list by hand; reaching operating-system fonts requires dynamic OS font assets set up in advance.
UniText falls back to the operating system's own fonts automatically. For each text run it asks the platform for a font that covers that run's language, so text in any language renders on desktop and mobile even when the project ships a single Latin font.
Why characters turn into squares
- The font has no glyph for the character, which is common for Chinese, Japanese, Korean, Thai, Arabic and Indic text in a game font designed for Latin.
- The character exists in the font but was not baked into a static atlas, which often happens with user names, chat and other text the game did not know in advance.
- The fallback chain does not include a font for that script, or the fonts are listed in an order that picks the wrong one first.
- The character is part of an emoji sequence or a combining mark that the text engine does not process as a unit.
TextMesh Pro looks for a glyph in a fixed order: the primary font asset, its fallback list, the sprite asset, the general fallback list in TMP Settings, the default sprite asset and the default font asset. When all of them miss, it draws the missing-glyph character, a □ by default. Operating-system fonts take part only as Dynamic OS font assets that someone creates and adds to a fallback list. Dynamic font assets avoid baking atlases, but their source fonts are included in builds.
Shipping a full font for every script fixes coverage at a price: a complete CJK font holds tens of thousands of glyphs and runs to many megabytes, and each language adds another file to the build and another entry to every fallback list.
How UniText avoids missing characters
- Automatic system fallback. Any character no font in the stack covers is rendered from an operating-system font, chosen by the platform's own font matcher for that run's language: DirectWrite on Windows, CoreText on Apple platforms, AFontMatcher on Android and fontconfig on Linux. It is on by default.
- Language-aware Han forms. The
Languageproperty or a<lang=zh-Hans>range selects Chinese, Japanese or Korean glyph shapes for the same code point through the OpenTypeloclfeature and a font family that prefers that language. - No baked atlases. Glyphs are rasterized the first time text displays them, so user-generated text never meets a character that was left out of an atlas.
- Smaller fonts when you do ship them. Font bytes are Zstd-compressed into the font asset, the Font Subsetter strips unused glyphs, and large font files are read from disk on demand through Font Memory Mapping instead of being loaded whole into memory.
WebGL is the exception: browsers do not give WebGL access to system fonts, so a WebGL build assigns font assets for the languages it shows, or supplies font bytes at runtime with UniTextFont.CreateFontAsset(byte[]).
Questions
Does system-font fallback work in the Editor and in builds?
Project Settings › LightSide › UniText › Fonts › Disable System Font Fallback for projects that must render only their own fonts.Can I still choose my own font for a language?
How do I keep CJK fonts out of the build?
Check it in your project
Run the browser demo, follow the setup guide, or compare the free version with the licenses.
Related problems
- Color Emoji in Unity: Flags, Skin Tones and ZWJ SequencesTextMesh Pro has no shaping engine, so emoji families, flags and skin tones often fall apart. UniText renders system color emoji with no setup and forms every Unicode emoji sequence as one glyph.
- Hindi and Indic Scripts in Unity: Fix Broken Conjuncts and Vowel SignsTextMesh Pro does no Indic shaping, so Devanagari, Tamil and Bengali render with broken conjuncts and misplaced vowel signs. UniText shapes every Indic script with HarfBuzz using the font’s own rules.
- TextMeshPro Alternative for Unity: UniText vs TMP vs UI ToolkitUniText replaces TextMesh Pro with a HarfBuzz-based text engine: shaping for Arabic and Indic scripts, Unicode BiDi, emoji sequences, variable fonts and system-font fallback on uGUI and in world space.
