Problem:
Arabic auto-translation works correctly at the text level — the translated strings themselves are accurate — but when rendered in-game via TextMeshPro, Arabic text displays incorrectly in two ways:
Disconnected letters — each Arabic character renders in its isolated form instead of joining with adjacent letters, as proper Arabic script requires.
Reversed reading order — text displays left-to-right instead of right-to-left.
This is not a font issue. It reproduces identically across multiple fonts (default fallback, system Arial, and a manually added Noto Sans Arabic TTF). Assigning any of these as a Fallback font only changes glyph shapes — it does not fix the underlying layout problem.
Root cause:
TextMeshPro does not natively support two things Arabic script requires:
Contextual shaping — each Arabic letter has different visual forms (isolated/initial/medial/final) depending on its position in a word, and TMP always renders the isolated form.
Bidirectional (BiDi) reordering — RTL text needs to be visually reordered before rendering, and TMP lays text out left-to-right by default.
No font file, no matter how complete, can fix this — it requires text processing before the string reaches TMP.
Suggested fix:
Integrate an existing open-source shaping/BiDi library into the tool's rendering pipeline, applied conditionally when the target language is RTL (Arabic, Hebrew, Persian, Urdu, etc.):
RTLTMPro (free, open-source, MIT license) — github.com/mnarimani/RTLTMPro. Handles Arabic/Persian/Hebrew shaping + BiDi reordering, supports Rich Text tags, multiline, and auto-sizing.
Alternative: Qalam (paid, itch.io) — lighter integration, drop-in component.
Since UnityGameTranslator already intercepts and injects translated strings into TMP components at runtime, the same interception point would be the ideal place to run the string through a shaping+BiDi pass before assigning it to TMP_Text.text, only when the detected target language is RTL. This wouldn't require changes to the translation pipeline itself — just a conditional post-processing step before rendering.
This would also future-proof support for other RTL languages (Hebrew, Persian, Urdu), since they'd hit the exact same underlying TMP limitation.
Problem:
Arabic auto-translation works correctly at the text level — the translated strings themselves are accurate — but when rendered in-game via TextMeshPro, Arabic text displays incorrectly in two ways:
Disconnected letters — each Arabic character renders in its isolated form instead of joining with adjacent letters, as proper Arabic script requires.
Reversed reading order — text displays left-to-right instead of right-to-left.
This is not a font issue. It reproduces identically across multiple fonts (default fallback, system Arial, and a manually added Noto Sans Arabic TTF). Assigning any of these as a Fallback font only changes glyph shapes — it does not fix the underlying layout problem.
Root cause:
TextMeshPro does not natively support two things Arabic script requires:
Contextual shaping — each Arabic letter has different visual forms (isolated/initial/medial/final) depending on its position in a word, and TMP always renders the isolated form.
Bidirectional (BiDi) reordering — RTL text needs to be visually reordered before rendering, and TMP lays text out left-to-right by default.
No font file, no matter how complete, can fix this — it requires text processing before the string reaches TMP.
Suggested fix:
Integrate an existing open-source shaping/BiDi library into the tool's rendering pipeline, applied conditionally when the target language is RTL (Arabic, Hebrew, Persian, Urdu, etc.):
RTLTMPro (free, open-source, MIT license) — github.com/mnarimani/RTLTMPro. Handles Arabic/Persian/Hebrew shaping + BiDi reordering, supports Rich Text tags, multiline, and auto-sizing.
Alternative: Qalam (paid, itch.io) — lighter integration, drop-in component.
Since UnityGameTranslator already intercepts and injects translated strings into TMP components at runtime, the same interception point would be the ideal place to run the string through a shaping+BiDi pass before assigning it to TMP_Text.text, only when the detected target language is RTL. This wouldn't require changes to the translation pipeline itself — just a conditional post-processing step before rendering.
This would also future-proof support for other RTL languages (Hebrew, Persian, Urdu), since they'd hit the exact same underlying TMP limitation.