Quick answer: TextMeshPro will not pull emoji from system fonts. You need a sprite asset that maps Unicode codepoints to atlas glyphs, registered either in TMP Settings as the default sprite asset or in the text component’s sprite asset fallback list.
Here is how to fix TextMeshPro emoji that render as empty boxes, missing-character squares, or simply nothing at all. You paste in 😀 and the text component shows a hollow rectangle. Or worse, the character disappears entirely and the text just continues without it. The fix involves understanding that TextMeshPro treats emoji as sprite atlas lookups, not font glyphs.
The Symptom
You drop emoji directly into the inspector text field of a TextMeshProUGUI component. In the editor, you see boxes, question marks, or blank space where the emoji should be. The console may print The character with Unicode value 0x1F600 was not found.
It works fine if you use the inline sprite tag <sprite=0> but breaks the moment you paste a real emoji character.
What Causes This
No sprite asset is mapped to the codepoint. TextMeshPro looks up emoji glyphs in a sprite asset, not in the font asset. Without a configured sprite asset, the codepoint has no corresponding glyph.
Sprite asset is not in the fallback chain. Even if you have an emoji sprite asset, it must be on the text component’s sprite asset list or the global TMP Settings default. Otherwise the lookup never finds it.
The sprite atlas was rebuilt and indices shifted. If your code uses <sprite index=N> tags, regenerating the atlas can change the indices. Use <sprite name="grin"> instead.
Shader missing in build. The TMP_Sprite shader can be stripped if no scene uses it at build time. The atlas exists, the indices are correct, but the sprite material has no shader to draw with.
The Fix
Step 1: Create a sprite asset from your emoji atlas. Import a PNG containing your emoji glyphs (you can download a free Unicode emoji sheet). In the Project window, right-click the texture and choose Create → TextMeshPro → Sprite Asset.
Step 2: Map Unicode codepoints to sprites. Open the sprite asset, expand the Sprite Character Table, and set each entry’s Unicode field to match the emoji it represents (for example, 1F600 for 😀).
Step 3: Register the sprite asset globally. Open Edit → Project Settings → TextMeshPro → Settings and drag your sprite asset into the Default Sprite Asset field. This makes every TMP component fall back to it when a glyph is missing from the font.
// Programmatic fallback at runtime if needed
using TMPro;
void SetupEmojiFallback(TextMeshProUGUI label, TMP_SpriteAsset emoji)
{
if (label.spriteAsset == null) label.spriteAsset = emoji;
TMP_Settings.defaultSpriteAsset = emoji;
label.ForceMeshUpdate();
}
Step 4: Force a refresh after changing the asset. TMP caches mesh data, so changes to the sprite asset list do not take effect until you call ForceMeshUpdate or re-set the text.
Step 5: Include the sprite shader in builds. Open Edit → Project Settings → Graphics → Always Included Shaders and add TMP_Sprite. Without this, sprite glyphs may render invisibly in builds.
// Verify the asset survived the build
void Start()
{
if (TMP_Settings.defaultSpriteAsset == null)
Debug.LogError("Default sprite asset missing in build");
}
Use Names Instead of Indices
Once your sprite asset is set up, prefer <sprite name="heart"> over <sprite=3>. Names survive atlas regeneration; indices do not. If you regenerate the atlas and a sprite is reordered, every <sprite=3> tag in your localization files now points to the wrong glyph.
“Emoji are sprites in TMP’s mental model. Map the Unicode codepoint to a sprite, register the asset globally, ship the shader.”
Related Issues
For missing standard glyphs, see TextMeshPro Font Asset Missing. For text that does not appear at all, see TextMeshPro Text Not Showing.
Sprite asset, codepoint mapping, default registration, shader included. All four or none work.