Hindi and Indic Scripts in Unity: Fix Broken Conjuncts and Vowel Signs

Last reviewed

Short answer

Hindi, Marathi, Nepali, Bengali, Tamil, Telugu, Gujarati, Kannada, Malayalam and Punjabi are not drawn one character per glyph. Consonants combine into conjuncts, some vowel signs are displayed before the consonant they follow in memory, and marks stack above and below. TextMesh Pro does no Indic shaping, so the text renders as a string of disconnected pieces with vowel signs in the wrong place.

UniText shapes every Indic script with HarfBuzz, using the rules stored in the font, so conjuncts, reordered vowel signs and mark positions come out as the font designer intended.

What goes wrong without shaping

Indic scripts store text in phonetic order and leave the visual arrangement to the shaping engine. Three things have to happen:

  • Conjuncts. A consonant followed by a virama (halant) and another consonant becomes one combined glyph: क्ष (kṣa) is k + virama + ṣa. Without shaping the virama stays visible and the consonants stand apart.
  • Reordering. The short-i vowel sign ि is stored after its consonant but drawn before it: कि is ka + i. Without reordering it appears on the wrong side.
  • Mark positioning. Anusvara, chandrabindu, nukta and other marks attach to specific points of the base glyph, defined by the font's positioning tables.

TextMesh Pro applies only four OpenType features: kerning, ligatures and two kinds of mark positioning. It does not move pre-base vowel signs, lacks the contextual features that form conjuncts, and positions marks only for a fixed list of Latin, Thai, Hebrew and Arabic marks, so Indic vowel signs and viramas are never placed. Unity's issue tracker has a report that Hindi renders distorted in TextMesh Pro and Legacy Text even with ligatures enabled, reproduced up to Unity 6.5. Baking more glyphs into the atlas does not help, because the problem is the missing shaping step, not missing glyphs.

In UI Toolkit, Unity's Advanced Text Generator shapes text with HarfBuzz. It is opt-in in Unity 6.0 to 6.4, Unity announced it as the default in 6.5, and Unity staff described its Indic support as not fully tested when it launched. It does not apply to uGUI canvases or TextMesh Pro components.

How UniText renders Indic scripts

Greetings across many writing systems with emoji, among them Arabic, Hebrew, Devanagari, Tamil, Thai and CJK, rendered by UniText.
  • HarfBuzz shapes each run with the font's OpenType tables, which define conjuncts, reordering and mark placement.
  • Line breaking, caret movement and selection treat each grapheme cluster as one unit, so the caret never lands between a consonant and its vowel sign.
  • On desktop and mobile, system fonts cover the Indic scripts installed with the operating system. For a consistent look, or for WebGL, add a font such as Noto Sans Devanagari to the font stack.
  • The Language property or a <lang> range selects language-specific forms through the OpenType locl feature, for example Marathi forms in Devanagari text.
csharp
using LightSide;
using UnityEngine;

public class Welcome : MonoBehaviour
{
    [SerializeField] UniText label;

    void Start()
    {
        label.Language = "hi";
        label.Text = "क्षमा कीजिए, स्तर पूरा हुआ!";
    }
}

Questions

Do I need a special font for Hindi?

Any OpenType font that supports Devanagari works, because UniText applies the font's own shaping tables. Fonts that only contain basic glyphs without OpenType rules cannot form conjuncts in any engine.

Does this also fix Tamil, Bengali and Telugu?

Yes. The same shaping step handles every Indic script, as well as Sinhala, Tibetan and the Southeast Asian scripts derived from Brahmi.

Can players type in Hindi?

Yes. Editable text and input fields shape the text while it is typed, and composition from the system keyboard or IME is delivered by the operating system.

Check it in your project

Run the browser demo, follow the setup guide, or compare the free version with the licenses.

Related problems