Enabling Right-to-Left (RTL) Text

In order to enable RTL support in ARwayKit SDK, please follow below steps

This guide will help you enable RTL (Right-to-Left) text support in your Unity project using the RTLTMPro library. RTLTMPro is an extension for TextMeshPro that adds support for RTL languages like Arabic, Persian, and Hebrew.

Prerequisites

  • Unity installed on your system.

  • TextMeshPro plugin installed via the Unity Package Manager.

Install RTLTMPro

GitHub Repository : https://github.com/pnarimani/RTLTMPro

Install from OpenUPM

In the Unity editor, add RTLTMPro as a scoped registry by selecting "Edit" in the top bar, the clicking "Project Settings" then open the "Package Manager" category on the left.

Then add OpenUPM as a scoped registry as shown below :

Copy the below to add as new scoped registry.

NAME:  OpenUPM
URL :  https://package.openupm.com
SCOPE: com.nosuchstudio.rtltmpro 

Click "Save" once you have added the Name, URL, and Scope(s).

Then in Package Manager window, from the Unity editor top bar Window -> Package Manager, change scope to Packages: My Registries by selecting the "Packages: Unity Registry" text on the top left of the window.

Select "RTL Text Mesh Pro" package and press Install on the top right.

The sample scenes and demo resources (fonts, shaders, etc.) are included in the package as a .unitypackage file. You need to import those into your Assets folder to use them. From the project window navigate to the package folder and double click "RTLTMPro-demo-resources" file to import these assets into your project.

Double click and import RTLTMPro-demo-resources:

Installation is successful here.

Update Font Assets for RTL Languages

  1. Ensure you have a font that supports your RTL language.

  2. Download and copy NotoSansArabic Font that supports RTL from here : https://fonts.google.com/noto/specimen/Noto+Sans+Arabic

  3. Create a new Font Asset for your RTL font if needed.

  4. Assign the Font Asset to your RTLTextMeshPro component if required.

  5. In order to Convert Text component string to RTL just need to update the Font file and for TextMeshPro need FontAsset.

How to Apply RTL support to existing Text and TextMeshPro components?

For existing project where all the Text and TextMeshPro components are Localized, RTL support can be added to it without changing whole component.

Copy NotoSansArabic font and NotoSansArabic Font Assets in a Resources directory.

Use the below RTLTextUpdater script to Update Text/TextMeshPro component string with RTL support. Create a new C# Script in Unity in the Project tab by right clicking the Assets folder directory and click Create -> C# Script and call it "RTLTextUpdater".

Copy

using TMPro;
using UnityEngine;
using UnityEngine.UI;
using RTLTMPro;
using System.Collections;

public class RTLTextUpdater : MonoBehaviour
{
    public Font newUIFont;
    public TMP_FontAsset newFontAsset;
    bool fontsImported = false;

    void OnEnable()
    {
        if (!fontsImported)
        {
            if (newUIFont == null)
            {
                newUIFont = Resources.Load<Font>("NotoSansArabic");
            }
            if (newFontAsset == null)
            {
                newFontAsset = Resources.Load<TMP_FontAsset>("NotoSansArabic SDF");
            }
            fontsImported = true;
        }

        StartCoroutine(UpdateRTLSupport());
    }

    IEnumerator UpdateRTLSupport()
    {
        yield return new WaitForSeconds(0.02f);
        
        Text uiText = GetComponent<Text>();
        if (uiText != null)
        {
            ApplyRTLToTextComponent(uiText);
        }

        TextMeshProUGUI textMeshProUGUI = GetComponent<TextMeshProUGUI>();
        if (textMeshProUGUI != null)
        {
            ApplyRTLToTMPComponent(textMeshProUGUI);
        }

        TextMeshPro textMeshPro = GetComponent<TextMeshPro>();
        if (textMeshPro != null)
        {
            ApplyRTLToTMPComponent(textMeshPro);
        }

    }


    void ApplyRTLToTextComponent(Text uiText)
    {
        uiText.font = newUIFont; 
        
        string originalText = uiText.text;
        FastStringBuilder fastStringBuilder = new FastStringBuilder(RTLSupport.DefaultBufferSize);
        RTLSupport.FixRTL(originalText, fastStringBuilder, true, true);
        uiText.text = fastStringBuilder.ToString();
    }

    void ApplyRTLToTMPComponent<T>(T tmpComponent) where T : TMP_Text
    {
        tmpComponent.font = newFontAsset; 
    
        string originalText = tmpComponent.text;
        FastStringBuilder fastStringBuilder = new FastStringBuilder(RTLSupport.DefaultBufferSize);
        RTLSupport.FixRTL(originalText, fastStringBuilder, true, true);
        tmpComponent.text = fastStringBuilder.ToString();
    }
}

This Script has to be applied on all the Text and TextMeshPro in whole scene. The RTL support happens at run time.

To automatically apply the above to every Text and TextMeshPro component in the scene, you can use the following editor script.

Create a new C# Script in Unity in the Project tab by right clicking the Assets folder directory and click Create -> C# Script and call it "AddRTLTextUpdater"

Copy the below into the newly created file:

using UnityEditor;
using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class AddRTLTextUpdater : EditorWindow
{
    [MenuItem("Tools/Add RTL Text Updater")]
    public static void ShowWindow()
    {
        GetWindow<AddRTLTextUpdater>("Add RTL Text Updater");
    }

    void OnGUI()
    {
        if (GUILayout.Button("Add RTLTextUpdater to all Text/TMP components"))
        {
            AddRTLUpdaterToAllTextComponents();
        }
    }

    private void AddRTLUpdaterToAllTextComponents()
    {
        Text[] allUITextComponents = Resources.FindObjectsOfTypeAll<Text>();
        foreach (Text uiText in allUITextComponents)
        {
            if (uiText.gameObject.activeInHierarchy || uiText.gameObject.scene.isLoaded)
            {
                if (uiText.GetComponent<RTLTextUpdater>() == null)
                {
                    uiText.gameObject.AddComponent<RTLTextUpdater>();
                }
            }
        }

        TextMeshProUGUI[] allTextMeshProUGUIComponents = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
        foreach (TextMeshProUGUI textMeshProUGUI in allTextMeshProUGUIComponents)
        {
            if (textMeshProUGUI.gameObject.activeInHierarchy || textMeshProUGUI.gameObject.scene.isLoaded)
            {
                if (textMeshProUGUI.GetComponent<RTLTextUpdater>() == null)
                {
                    textMeshProUGUI.gameObject.AddComponent<RTLTextUpdater>();
                }
            }
        }

        TextMeshPro[] allTextMeshProComponents = Resources.FindObjectsOfTypeAll<TextMeshPro>();
        foreach (TextMeshPro textMeshPro in allTextMeshProComponents)
        {
            if (textMeshPro.gameObject.activeInHierarchy || textMeshPro.gameObject.scene.isLoaded)
            {
                if (textMeshPro.GetComponent<RTLTextUpdater>() == null)
                {
                    textMeshPro.gameObject.AddComponent<RTLTextUpdater>();
                }
            }
        }
    }
}

To Run the RTLTextUpdater : Tools -> Add RTL Text Updater

By running the editor script, you ensure that all relevant text components in your scene will have the RTLTextUpdater component attached, and the RTL conversion logic will be applied whenever they are enabled.

It opens another Window with option to add RTLTextUpdater

After running clicking "Add RTLTextUpdater to all Text/TMP components" it adds RTLTextUpdater to all the Text and TextMeshPro components

As soon as component gets enabled, it will convert the normal string into RTL text.

Last updated