Chinese, Japanese and Korean Text in Unity Without Huge Font Files
Last reviewed
Chinese, Japanese and Korean fonts contain tens of thousands of glyphs, so in TextMesh Pro they either fill large static atlases or ship the source font for dynamic atlases, often once per language. The same code points also need different glyph shapes for Chinese, Japanese and Korean, and TextMesh Pro picks glyphs by code point only, not by language.
On desktop and mobile UniText renders CJK from the operating system's fonts, so the build carries no CJK font and no baked atlas. When you do ship a font, it is compressed, can be subset, and is read from disk on demand, and the text's language selects the right Chinese, Japanese or Korean glyph forms.
The usual options
- The size of the fonts. A full CJK font is large: Noto Sans CJK Simplified Chinese Regular is about 16 MB per weight, Source Han Sans about the same, and even the regional subsets run from about 4.5 to 8.4 MB.
- TextMesh Pro static atlases. Thousands of characters are baked into Alpha8 textures, about 1 MB at 1024² and 4 MB at 2048², split across a main asset and fallbacks, from character lists the project has to maintain.
- TextMesh Pro dynamic atlases. Dynamic font assets add glyphs at runtime but include their source font in the build. Dynamic OS font assets read a system font instead and are the way to avoid shipping one; they are added to fallback lists by hand.
- One shape for all three languages. TextMesh Pro looks glyphs up by code point only and has no language setting, so the regional form depends on which font asset in the fallback chain holds the character. Users report Chinese text drawn with Japanese glyph shapes, and the usual workaround swaps font assets per locale.
- Line breaking. TextMesh Pro breaks CJK text between characters, guided by the leading and following character lists in its settings, rather than the Unicode line-breaking algorithm.
How UniText handles CJK

- System fonts first. Characters no font in the stack covers come from the operating system's font for that run's language, through DirectWrite, CoreText, AFontMatcher or fontconfig. Nothing ships for CJK on desktop and mobile.
- Right glyphs for the language. The
Languageproperty or<lang=ja>,<lang=zh-Hans>,<lang=ko>ranges turn on the OpenTypeloclfeature and prefer a font family declared for that language, so the same code point is drawn the Japanese, Chinese or Korean way. - No baked atlas. Glyphs are rasterized when text first shows them, so only the characters actually displayed take atlas space, and player names or chat never meet a missing glyph.
- Smaller shipped fonts. Font bytes are Zstd-compressed into the font asset, the Font Subsetter keeps only the characters a text corpus or character set needs, and Font Memory Mapping reads large files on demand instead of loading them whole.
- CJK line breaking. Chinese and Japanese break between characters by the Unicode rules; an optional CJK dictionary adds word selection and word-by-word animation.
WebGL has no access to system fonts, so a WebGL build assigns CJK fonts, ideally subset, or downloads font bytes at runtime with UniTextFont.CreateFontAsset(byte[]).
Questions
Which system fonts are used?
Can I use my own CJK font for a consistent look?
Check it in your project
Run the browser demo, follow the setup guide, or compare the free version with the licenses.
Related problems
- Unity Text Shows Squares Instead of Characters: Font Fallback That Just WorksSquares appear when no font in the fallback chain has the character. UniText falls back to the operating system’s fonts per language automatically, so any language renders without shipping a font for it.
- Thai, Lao, Khmer and Myanmar Line Breaking in UnityThese scripts have no spaces between words, so lines can only break by dictionary. UniText ships word-segmentation dictionaries for Thai, Lao, Khmer and Myanmar and shapes their stacked marks with HarfBuzz.
- Variable Fonts in Unity: Any Weight and Width From One FileTextMesh Pro and UI Toolkit do not expose variable font axes, so every weight needs its own asset. UniText sets and animates weight, width, slant and optical size from one variable font file.
