Unity holding indefinitely when setting a specific text with overflow mode activated

Hello,

I am facing a serious blocking issue with TextMeshPro 3.2.0-pre.10 causing Unity to hold indefinitely.

It’s pretty simple to reproduce with an empty project :

  1. Create an empty project
  2. Import TMPro 3.2.0-pre.10 with essentials
  3. Create an empty scene
  4. Create a TMPro UI component
  5. Set the width of the component (recttransform) to 0
  6. Type the following text inside the quotes : “] --”
  7. Unity should enter an infinite loop
  8. Kill Unity with the Tasks Manager

image

The problem is not present in the version 3.0.9 of TMPro.

I ran a long debugging session and here’s my findings so far (the method is like 2924 lines, so quite hard to debug…)

  • The method incriminated is TextMeshProUGUI::GenerateTextMesh
  • It is the loop line 2664 that is ran endlessly (for (int i = 0; i < m_TextProcessingArray.Length && m_TextProcessingArray[i].unicode != 0; i++))
  • Calling the method RestoreWordWrappingState(ref m_SavedSoftLineBreakState) will case a restoration of a previous state of the variable i
  • Then the code is getting into the switch case statement at line 3701 (switch (m_overflowMode))
  • Inserting a new line a looping back to the previsouly new i value

To give aditional details, during the for loop, at the index 3 (i = 3), the method RestoreWordWrappingState is restoring the value 1, and I think it should be 2, but I might be wrong since the GenerateTextMesh method is not easy to fully understand. Or maybe there’s a missing call to the method SaveWordWrappingState that will update the stored values.

Is someone able to reproduce it? I can provide the sample project if needed.

Edit 1 :
Looks like it’s related to the combo “Whitespace followed by the character 0x2D”. Especially in presence of “Hyphen” where the hard line break is not set to true and therefore, not saved. Causing an endless loop.

In this case, we are not doing the test if (isFirstWordOfLine) below, and therefore, not appending a line break.

I propose the following dirty fix that it seems to work (but since I don’t really know the whole TMPro code architecture, this fix might be not working)

Add the content of the code

else if (isFirstWordOfLine)
{
    // Special handling for non-breaking space and soft line breaks
    if (isWhiteSpace && charCode != 0xA0 || (charCode == 0xAD && isSoftHyphenIgnored == false))
       shouldSaveSoftLineBreak = true;

    shouldSaveHardLineBreak = true;
}

Directly here :

if ((isWhiteSpace || charCode == 0x200B || charCode == 0x2D || charCode == 0xAD) && (!m_isNonBreakingSpace || ignoreNonBreakingSpace) && charCode != 0xA0 && charCode != 0x2007 && charCode != 0x2011 && charCode != 0x202F && charCode != 0x2060)
{
    // Ignore Hyphen (0x2D) when preceded by a whitespace
    if ((charCode == 0x2D && m_characterCount > 0 && char.IsWhiteSpace(m_textInfo.characterInfo[m_characterCount - 1].character)) == false)
    {
        isFirstWordOfLine = false;
        shouldSaveHardLineBreak = true;

        // Reset soft line breaking point since we now have a valid hard break point.
        m_SavedSoftLineBreakState.previous_WordBreak = -1;
    }
    else if (isFirstWordOfLine)
    {
        // Special handling for non-breaking space and soft line breaks
        if (isWhiteSpace && charCode != 0xA0 || (charCode == 0xAD && isSoftHyphenIgnored == false))
            shouldSaveSoftLineBreak = true;

        shouldSaveHardLineBreak = true;
    }
}

And now it works, but it’s an ugly copy and paste which is not correct from a programming point of view.

4 Likes

Bumping this, would like to get this checked out.
My text would be: W → T1 and it seems to be triggering for 0/very small width recttransform (which seems to be your case, and mine)

Little bump also : The issue is still present in Unity6 (6000.0.27f1).

Edit 11/28/2024 : A fix has been published in the latest Unity 6 version (6000.0.29f1) Unity Issue Tracker - Editor hangs when rendering TMP Text Component with Left and Right Margins set in the Extra Settings

1 Like

This issue has resurfaced again with CJK characters in latest Unity 6.2 (6000.2.2f1), probably due to TextMeshPro 3.2.0-pre.13’s release. Painful…

1 Like

This issue is still present in Unity 6000.2.4f1 when using [, ] or 「, 」 with CJK characters.

On my side I propose this fix:

bool shouldSaveHardLineBreak = isFirstWordOfLine;

I am not sure about shouldSaveSoftLineBreak, but to avoid infinit loop shouldSaveHardLineBreak must be true on the first word.

Conditions to reproduce the infinit loop:

  • Allow wrapping
  • Text like " -X" who contain (space) + (dash) + (any non-space)
  • widthOfTextArea must be small or negative

Why it loop? When code reach X in " -X", it RestoreWordWrappingState() but since it’s the first word of the line and it loop on the “-X” part forever.