Search Unity

Bug Text metrics sometimes incorrect when the text contains spaces

Discussion in 'UGUI & TextMesh Pro' started by dlorre, Jul 5, 2021.

  1. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    699
    It looks like it does some kind of word wrapping despite being unnecessary:
    upload_2021-7-5_9-15-21.png

    My code is inspired from CodeMonkey's tooltip video, with some extra for handling minimum height and width:

    Code (CSharp):
    1.         label.text = message;
    2.         label.ForceMeshUpdate();
    3.  
    4.         var width = Mathf.Max(label.preferredWidth + padding * 2, minWidth);
    5.         var height = Mathf.Max(label.preferredHeight + padding * 2, minHeight);
    6.  
    7.         Vector2 bgSize = new Vector2(width, height);
    8.         rtBackground.sizeDelta = bgSize;
    9.         rtLabel.sizeDelta = bgSize;
    Naturally there is a workaround which consist of replacing the spaces with something else before checking the metrics.

    EDIT: it seems that it's not caused by spaces, other labels without spaces present the same issue...
     
    Last edited: Jul 5, 2021
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Can you provide / export some simply scene that I could use to test this?
     
  3. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    699
    I have sent the report twice from Unity but I did not receive a confirmation email. Here is the project stripped of the Library folder.
     

    Attached Files:

  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Thank you for submitting the bug report along with project. I was able to look at it and the reported behavior is not a bug but related to how the preferred values are computed which can certainly be confusing.

    First, it is important to understand the preferred width is calculated as if the width of the text container (RectTransform) was infinite. Ie. no restrictions on the width where unless the text contains line feeds, the preferred width is that of the text rendered on a single line. If there are line feeds, then the preferred width is that of the longest line.

    The preferred height however, does take into consideration the width of the text container where as such, if the text doesn't all fit within that width, you get a larger preferred height as the text may take render on multiple lines.

    So in the case of the project you provided, the behavior is the result of the RectTransform of the ToolTip text object having a width of 200.0. Since the first button / text has a preferred width of less than 200, the whole text fits on a single line resulting in the preferred height being that of a single line.

    However, in the case of the 2nd button / text, its preferred width is greater than 200 thus resulting in the text rendering on two lines and corresponding preferred height.

    Then, as you add padding to the RectTransform, the width becomes such that the text can fit on a single line but since you already changed the height of RectTransform to the large height you are left with extra space at the top and bottom.

    Here is a revised implementation of your Show() function that will work as expected.

    Code (csharp):
    1.  
    2. public void Show(string message)
    3. {
    4.         // Calculate the preferred width and height of the text without any constraints
    5.         Vector2 preferredValues = label.GetPreferredValues(message, float.PositiveInfinity, float.PositiveInfinity);
    6.         var width = Mathf.Max(preferredValues.x + padding * 2, minWidth);
    7.         var height = Mathf.Max(preferredValues.y + padding * 2, minHeight);        Vector2 bgSize = new Vector2(width, height);
    8.         rtBackground.sizeDelta = bgSize;
    9.         rtLabel.sizeDelta = bgSize;        // Set the text
    10.         label.text = message;
    11. }
    12.  
     
    dlorre likes this.