TextMeshPro

Hi.

in TMPro_MeshUtilities.cs

method GetWord() can null out on some phantom 0 length word.

So for this string.

“Are you sure you want to <gradient=“TooltipPreset”><link=“tip”>fire this <gradient=“TooltipPreset”><link=“tip”>employee?”

var tmpInfo = tmpField.textInfo;

for (var i = 0; i < tmpInfo.wordInfo.Length; i++)
{
    var wordInfo = tmpInfo.wordInfo[i] ;

    Debug.Log(wordInfo.characterCount + " iterator " +i);

    Debug.Log(wordInfo.GetWord());
}

It will null out after word employee for a word of length=0 iteration i=9.
Also GetWord() method is a garbage collectors dream since it creates new string after adding each char.
There is string s= new string(charArr, index, index) method that would be best, if there is some char array stored somewhere. Or maybe a StringBuilder.
Tmp is great. Thanks for all the work !

First thing, always use code blocks to display code, it won’t eat the indexer and is the preferred way to read code.

Not sure why you are getting a null string on the last word which should be index 8, maybe @Stephan_B can enlighten us.

As for GetWord() generating a new string, that is the nature of strings. Modifying the string will create a new one. Even if it’s stored as a char array or a StringBuilder it will need to create a new one to give you the string object. Strings are immutable objects, meaning you cannot modify them only create and read them. If changes are made a new string is allocated. StringBuilder will minimize those allocations when manipulating, but in the end it will still give you a new string object discarding the old.

These are some examples that will create a new string, every time they are called.

string s= new string(charArr, index, index);
string s2 = stringBuilder.ToString();
string s3 = stringBuilder.ToString();//There is no caching mechanism so calling it multiple times creates multiple strings even when containing the exact same text.
s += "Hello World";
s2 += s + s3;

You probably didn’t look up the method in question.

This is how it looks.

public string GetWord()
        {
            string word = string.Empty;
            TMP_CharacterInfo[] charInfo = textComponent.textInfo.characterInfo;

            for (int i = firstCharacterIndex; i < lastCharacterIndex + 1; i++)
            {
                word += charInfo[i].character;
            }

            return word;
        }

It will create 9 new strings for 10 char word.

This would create just one string, and one chararray that each string has inside it, so the least allocation possible. Also it probably wouldn’t get null pointer exception, although i’m not sure why it does null out in the first place.

public string GetWord()
    {
        if (characterCount <= 0)
        {
            return string.Empty;
        }

        char[] charArrayToFill = new char[characterCount];
           
        TMP_CharacterInfo[] charInfo = textComponent.textInfo.characterInfo;
        int iterator2 = 0;

        for (int i = firstCharacterIndex; i < lastCharacterIndex + 1; i++)
        {
            charArrayToFill[iterator2] = charInfo[i].character;
            iterator2++;
        }

           
        return new string(charArrayToFill);
    }

Cheers.

Can’t even find the TMP_WordInfo class to confirm. Damn packages, can’t look up the class in VS to even find where it is.

it’s TMPro_MeshUtilities.cs

public struct TMP_WordInfo{} is in there.

UnityProjectName\Library\PackageCache\com.unity.textmeshpro@3.0.6\Scripts\Runtime is the folder with the scripts…