Alright, so basically what I have is a GameObject which contains a TextMesh Pro object. The parent is supposed to adjust itself to the child’s width with a Content Size Fitter, which works fine while the text is on a single line. The thing is, once the Overflow kicks in and a second line is made, the parent takes up the maximum width it can take, regardless of the children’s size, so I’m stuck with a huge empty space, visible because the parents background is supposed to be scaled to the text. I’m a bit confused, because when I simply skip a line by pressing enter in the Text Input Box, the parent scales properly on two lines. It seems the problem lies with the overflow. I was wondering why the overflow setting was causing this and is there’s a way to disable it or change it and to fit the behaviour of a manually entered return.
After looking at it again, it seems that the Text Mesh Pro container doesn’t scale to text which contains more than a line, and since my parent container is set so scale based on the children’s content, it’s taking the maximum size just like the text. How could I make the Text Mesh Pro content box take the width of the text? I’ve tried playing around with the line info and any other information I could fetch but I haven’t been able to do anything. If it’s simply by design, i’d like to know though so I can stop toying around with something that won’t lead to anything ( ;__; )
Not sure I understand clearly the issue. Can you provide some example screenshots of the behavior you are seeing vs. what you would expect / want?
Yes, sorry, I don’t have a picture of the project, but here is an example. The box on the bottom should scale it’s width to fit along with the margin I set, but it simply goes to it’s maximum possible width, although when there is just one line it works fine.
Again just looking to understand … Why should the line scale to “Here”?
The Content Size Fitter uses Preferred Width.
The Preferred Width is: The width of the (longest) line without wrapping. Ie. From first character of line to linefeed.
So if you have text that contains something like this.
A line of text\n
Another line of text\n
A last line of text that is longer\n
In the above example, the preferred width will be the width of the last line.
Ok I did another example which will hopefully clear up what I’m trying to explain. The border around the text is what the border of the text mesh ends up being, so the parent, which contains the text, follows that text border’s size and it’s background then looks odd because it’s too large. The top three boxes are the current behaviour seen.
The problem here is the Content Size Fitter is designed to work with Preferred Width and Height which by design ignores word wrapping. Like I said before, Preferred Width is the width that would enable us to avoid breaking the line.
I think your best option is as follows:
Set the size of the RectTransform of the text object to match the size of your Area that limits the text.
Then using a simple script, get the TMP_Text.textBounds which defines the area of the text as seen in the image below.
Then add some appropriate padding to the returned text bounds to adjust the size of your background image / frame.
Note: TMP_Text.textBounds require the text object has already been processed / rendered. So if you are trying to do this in Awake (for instance), you will need to set the text and then use ForceMeshUpdate() to force the text object to be processed right away in order to get valid bounds.
There should be several posts about ForceMeshUpdate as well as getting the TMP_Text.bounds and TMP_Text.textBounds. The bounds is the bound of the geometry whereas the textBounds are those of the text metrics.
In the TMP Examples & Extras is a script called TMP_TextInfoDebugTool.cs. If you add this script on a text object, it will allow you to visualize the information contained in the textInfo including the bounds and textBounds.
You can center your left-aligned text without Layout-Groups.
For a simple Setup create a Canvas.
- Add a new Image-Object. 500 wide, 100 heigh, Color = Black. Name it DialogueBox.
- Add a new GameObject as a child of the DialogueBox. 480 wide, 80 heigh. Name it TextBounds.
- Add a new TMP-Object as a child of the TextBounds. From the Anchor-Presets choose Stretch-Stretch while holding Shift+Alt (or manually set Anchor Min = 0, 0; Max = 1, 1; Pivot = 0.5, 0.5). Name it DialogueText.
- Create the following script and add it to your DialogueText.
public TMP_Text tmpText; // Assign DialogueText in the Inspector
private void AssignString(string s)
{
// Assign Text to TextObject
tmpText.text = s;
// Updates the Text-Mesh
tmpText.ForceMeshUpdate();
// Get TextBounds and use TextBounds to position the Text-Parent
Bounds bounds = tmpText.textBounds;
Vector2 newPos = new Vector2(-bounds.center.x, -bounds.center.y);
RectTransform rt = tmpText.transform.parent.GetComponent<RectTransform>();
rt.localPosition = newPos;
}
Use this function to assign your string to the DialogueText-Object.
Your text should now be centered within the black rectangle.
Text-Position without the script
Text-Position with the script
The longest line of text always has as much room on left side as it has on the right side.