[SOLVED] How to batch the localized texts using TextMeshPro?

Hello everyone,

My game is in my native language (not english) and I use the texts localized with TextMeshPro. The problem is the game generates too many draw calls. I have around 32 objects TextMeshPro in the scene and it generates 89 batchs. Is there a way to reduce it?

Can you provide some detail / images showing the scene hierarchy which would enable me to see how many Material Presets and Fallback font assets these different text objects are using?

In theory, if you had 32 text objects all using the same font asset, you would get (1) draw call. However when using the Canvas system, sorting / batching is based on scene hierarchy so if some of these overlap or in between images, buttons, etc. that will affect how many draw calls you end up with.

To provide better insight, I need a clear understanding of the scene / hierarchy setup.

Hi Stephan_B,

My localized texts are generated by a prefab using TextMeshProUGui and canvas system. The prefab uses a Font Asset called Roboto-Regular SDF which is generated by TMP Font Asset Creator. The Material Preset is Roboto-Regular SDF Material.

The text content is populated at the moment instantiate the object from prefab.

I create the texts all in one for loop and execute this code just one time at the game initialization time.

I don’t have Fallback font asset.

I use one Canvas for the UI. The texts are generated at the lowest position in the hiearchy, at below some other UI elements.

If I disable the texts, the game has 10 batchs. If enable with texts, it increases to 89 batchs.

I attach 2 images, the first one is the prefab, the second one is the UI canvas hierachy. Please help me to revise.


Can you expand the CardText object so I can see the sub object and what its name is?

When you create these text objects, you simply instantiate new ones correct? Do you manually assign a font asset to them and material?

Hi Stephan_B

I don’t assign the font asset or the material manually.

The prefab expanded

CardText objects expanded at runtime

This is the code I use to create a text object. I call it in a for loop to create 32 objects.

   private void GetCardText(GameObject card, int index, UnityEngine.Object cardTextParentPrefab, GameObject uiCanvas)
    {
        // if these values then do nothing
        if (index == 1 || index == 8 || index == 19 || index == 26)
        {
            return;
        }

        // I create the text object
        GameObject obj = Instantiate(cardTextParentPrefab) as GameObject;
        obj.transform.SetParent(uiCanvas.transform, false);
        obj.transform.position = card.transform.position;

        // do some adjusments on the position and rotation
        if (index > 1 && index < 8)
        {
            obj.transform.position += new Vector3(0.0f, -0.2f, 0.0f);
        }
        else if (index > 8 && index < 19)
        {
            obj.transform.position += new Vector3(-0.2f, 0.0f, 0.0f);
            obj.transform.Find("CardText").transform.localRotation = Quaternion.Euler(Vector3.zero);
        }
        else if (index > 19 && index < 26)
        {
            obj.transform.position += new Vector3(0.0f, 0.2f, 0.0f);
        }
        else if (index > 26 && index <= 36)
        {
            obj.transform.position += new Vector3(0.2f, 0.0f, 0.0f);
            obj.transform.Find("CardText").transform.localRotation = Quaternion.Euler(Vector3.zero);
        }

        // do the localization here.
        LocalizeTM localizedTMText = obj.transform.Find("CardText").GetComponent<LocalizeTM>();
        localizedTMText.localizationKey = CARD_TITLE_PREFIX + (index);

        localizedTMText.UpdateLocale();
    }

I would like to take a closer look. Can you send me a Private Message with link to download or submit a bug report with the project so I can take a closer?

There are sub objects being used which means some characters are missing from the primary font asset resulting in some fallback being used, those should batch among themselves. With the project I would be able to provide better insight on this.

I have submitted a bug report or you can download the project in the link I sent in pm.

Thanks. I’ll try taking a look later tonight or tomorrow.

Once again thank you for providing me access to the project as this always makes it so much easier to identify the source of potential issues.

As it turns out, the behavior in this case is not a bug but rather how the Canvas system handles batching.

In your scene, you instantiate several objects that end up children of the Canvas but whose Z value is different. Since sorting in the Canvas system is based on scene hierarchy, having different Z values on objects in the middle of the hierarchy prevents all of them from batching. Changing their Z value to be the same will allow them to batch down to 15 draw calls vs. 89.

Also note that rotation of objects in the hierarchy will also break batches.

1 Like

I modified z value of the text objects to 0 and it resolves the problem. Thank you very much.