TLDR: Using TMP_TextInfo in a Loop(For or Foreach) on a List or Array that is populated at runtime does not work. The TMP_TextInfo seems to refer to the same TMP_Text, no matter how the reference is provided.
Hello, I really hope someone can help me with this, it has been driving me crazy trying to figure it out, and I am completely stuck, and have tried everything I can think of over the last week and a half.
- I am using the TMP_TextInfo class to do various tasks. I use characterInfo, characterCount, line count etc.
I use it in a pretty standard way, for example to get the character at a certain index, or to get the line count of a certain TMP_Text instance. So nothing fancy or strange.
All of this works perfectly if I have a List or Array that is Pre-Populated, and also if I use a single instance that has been pre-assigned (Example, the TMP_Text component of a TMP_InputField)
So basically if I call my method that uses TMP_TextInfo it works perfectly, as expected, and gives me the correct results.
However…
As soon as I populate a List/Array at runtime, and then try to access the TMP_TextInfo of the items that have been added to the collection at runtime, it just returns the same result for all of the TMP_Text objects. So it does not matter if 1 TMP_Text has 9 lines of text and the other only has 2, it will return 1 as a result for both of them(For example)
-
If I debug the value of TMP_Text.text I get the correct result., so for example, the one Tmp_Text.text would return “Grapefruit” and the other would return “Kiwi” if I query the actual text value, so I know I am dealing with different TMP instances for a fact.
-
However if I debug TMP_TextInfo.characterCount for the same TMP_Text, both would return 6 for example.
The same goes for any other TMP_Textinfo values that I try to access.
I have made a small scene that illustrates my problem.
You can download it, or quickly recreate it if you wish.
-
On the left is a Canvas with 5 TMP_Text instances
-
The text values are “A”, “BB”, “CCC”, “DDDD” and “EEEEE” (So 1 - 5 Characters) added to the List TMP_PredefinedSource
-
On the right is an empty Canvas with 1 Template TMP_Text with the value “WORD”
-
The template object has a Button on it that will call GetTextInfo to show that the result is correct if you query a single instance, even if it was instantiated at runtime.
-
When you hit play, it will spawn 5 template objects and set the text to “F”, “FF” … “FFFFF” (So 1 - 5 Characters) and add them to the List TMP_SpawnedSource
-
It will then print the Text, and the character count for each instance in each of the Two lists.
-
So the A - E range debugs correctly.
-
However the F-FFFFF range prints a character count of 4 for all the instances.
A screenshot of the result:
And the code that generates this:
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using TMPro;
public class TInfo_test : MonoBehaviour
{
public List<GameObject> TMP_PredefinedSource;
public List<GameObject> TMP_SpawnedSource;
public GameObject templateObject;
public Transform parent;
private void Start()
{
InstantiateTemplate();
}
public void InstantiateTemplate()
{
//Spawn TMP_Text, add to list, set the text value to F, FF, FFF, FFFF, FFFFF
for(int i = 1; i<=5; i++)
{
var GO = Instantiate(templateObject, parent);
TMP_SpawnedSource.Add(GO);
GO.SetActive(true);
var t = GO.GetComponent<TMP_Text>();
t.text = string.Concat(Enumerable.Repeat("F",i));
}
GetTextInfoFromCollection();
}
public void GetTextInfoFromCollection()
{
//Get TMP_Text component and print Character Count for each instance.
//WORKS
foreach (GameObject t in TMP_PredefinedSource)
{
var tMesh = t.GetComponent<TMP_Text>();
TMP_TextInfo t_Info = tMesh.textInfo;
print("Character Count: " + tMesh.text+ " = " + t_Info.characterCount);
}
//DOES NOT WORK
foreach (GameObject t in TMP_SpawnedSource)
{
var tMesh = t.GetComponent<TMP_Text>();
TMP_TextInfo t_Info = tMesh.textInfo;
print("Character Count: " + tMesh.text + " = " + t_Info.characterCount);
}
}
//Do exactly the same as above, but only for instance that is passed specifically
//WORKS
public void GetTextInfo(GameObject GO)
{
var tMesh = GO.GetComponent<TMP_Text>();
TMP_TextInfo t_Info = tMesh.textInfo;
print("Character Count: " + tMesh.text + " = " + t_Info.characterCount);
}
}
Here is a link to the UnityProject with the test (2018.3.10f1):
https://drive.google.com/file/d/1vmFuK7jjNNLSda_FVb6mZnNpXGNFhS9J/view?usp=sharing
If you have any suggestions I would truly appreciate the help.
Thank you in advance for your time!
V