Search Unity

  1. Get the latest news, tutorials and offers directly to your inbox with our newsletters. Sign up now.
    Dismiss Notice

Problem with TextMeshProUGUI components in hierarchy

Discussion in 'UGUI & TextMesh Pro' started by PNordlund, Jun 3, 2018.

  1. PNordlund

    PNordlund

    Joined:
    Nov 20, 2013
    Posts:
    48
    This code in TMPro_UGUI_Private.cs seems to fail when there are multiple text components recursively in the hierarchy, i.e. I have one GameObject with TextMeshProUGUI component on it, and then other GameObjects as it's children - if they all have the TMP_SubMeshUI component somewhere, the code fails when there are more than 7 of them.

    protected TMP_SubMeshUI[] m_subTextObjects = new TMP_SubMeshUI[8];

    // Check to make sure Sub Text Objects are tracked correctly in the event a Prefab is used.
    TMP_SubMeshUI[] subTextObjects = GetComponentsInChildren<TMP_SubMeshUI>();
    if (subTextObjects.Length > 0)
    {
    for (int i = 0; i < subTextObjects.Length; i++)
    m_subTextObjects[i + 1] = subTextObjects;
    }
     
  2. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    5,684
    Can you post an image of this hierarchy so I can see the top parent, each of the text objects and sub text objects?
     
  3. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    144
    Encountered this issue today on a project, it was preventing builds. The hierarchy in question looks like the following:



    Upon examination of the problematic areas of the TextMeshPro code, you will notice a few things.

    Code (CSharp):
    1.  
    2. // Check to make sure Sub Text Objects are tracked correctly in the event a Prefab is used.
    3. TMP_SubMeshUI[] subTextObjects = GetComponentsInChildren<TMP_SubMeshUI>();
    4. if (subTextObjects.Length > 0)
    5. {
    6.     for (int i = 0; i < subTextObjects.Length; i++)
    7.         m_subTextObjects[i + 1] = subTextObjects[i];
    8. }
    1. The loop changes the value of m_subTextObjects[i +1]. This array has a size of 8, as seen earlier in the file.
    2. subTextObjects is retrieved with GetComponentsInChildren, which is also grabbing the components from ScoreText, causing the loop to cross 7 iterations, causing an array out of bounds exception.

    The solution? Only grab components from children with a depth of 1, and ensure the loop does not exceed 7 iterations. The code I used to solve the bug can be seen below.

    Code (CSharp):
    1.  
    2. // Check to make sure Sub Text Objects are tracked correctly in the event a Prefab is used.
    3. var subTextObjects = new List<TMP_SubMeshUI>();
    4. for (var i = 0; i < transform.childCount; i++)
    5. {
    6.     var component = transform.GetChild(i).GetComponent<TMP_SubMeshUI>();
    7.     if (component) subTextObjects.Add(component);
    8. }
    9.  
    10. if (subTextObjects.Count > 0)
    11. {
    12.     // todo: maybe make m_subTextObjects a dynamic array?
    13.     for (int i = 0; i < Math.Min(7, subTextObjects.Count); i++)
    14.         m_subTextObjects[i + 1] = subTextObjects[i];
    15. }
    16.  
     
unityunity