Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Question Getting text dimensions with TextGenerator.GetPreferredHeight/Width not working.

Discussion in 'Editor & General Support' started by unity_E9FfAw7RsMp7yg, Jul 26, 2022.

  1. unity_E9FfAw7RsMp7yg

    unity_E9FfAw7RsMp7yg

    Joined:
    Jan 13, 2020
    Posts:
    14
    I am using Unity 2021.3.3f1 and trying to make a pop up with a sprite as a background, where the size of this sprite adjusts to the size necessary to fit the text.

    From what I understand,
    UnityEngine.UI.TextGenerator
    should be able to give me the necessary dimensions of the sprite, given an input string and some
    TextGenerationSettings
    .

    Here is the code I am using.

    Code (CSharp):
    1.     public class PopUp : MonoBehaviour
    2.     {
    3.         UnityEngine.UI.Text text;
    4.         TextGenerationSettings textGenSetting;
    5.         TextGenerator generator
    6.  
    7.  
    8.         void Start()
    9.         {
    10.             generator = new TextGenerator();
    11.             textGenSetting.generationExtents = new Vector2(20f, 20f);
    12.         }
    13.  
    14.         void Update()
    15.         {
    16.             RecalculateText();
    17.         }
    18.  
    19.         private void RecalculateText()
    20.         {
    21.             textGenSetting.fontSize = text.fontSize;
    22.             textGenSetting.alignByGeometry = text.alignByGeometry;
    23.             textGenSetting.color = text.color;
    24.             textGenSetting.fontStyle = text.fontStyle;
    25.             textGenSetting.resizeTextForBestFit = text.resizeTextForBestFit;
    26.             textGenSetting.resizeTextMaxSize = text.resizeTextMaxSize;
    27.             textGenSetting.resizeTextMinSize = text.resizeTextMinSize;
    28.             textGenSetting.richText = text.supportRichText;
    29.             textGenSetting.horizontalOverflow = text.horizontalOverflow;
    30.             textGenSetting.verticalOverflow = text.verticalOverflow;
    31.             textGenSetting.updateBounds = true;
    32.             textGenSetting.font = text.font;
    33.             textGenSetting.lineSpacing = text.lineSpacing;
    34.          
    35.    
    36.             var newHeight = generator.GetPreferredHeight(text.text, textGenSetting);
    37.             var newWidth = generator.GetPreferredWidth(text.text, textGenSetting);
    38.             var newRect = generator.rectExtents;
    39.  
    40.             //Debug Log 1
    41.             Debug.Log(string.Format("newWidth: {0}, newHeight: {1}, numLinesGenerated: {2}", newWidth, newHeight, generator.lineCount));
    42.          
    43.             //Debug Log 2
    44.             Debug.Log(string.Format("newRectWidth: {0}, newRectHeight: {1}, numLinesGenerated: {2}", newRect.width, newRect.height, generator.lineCount));
    45.          
    46.             //Debug Log 3
    47.             Debug.Log(string.Format("generationExtents: width {0}, height: {1}, numLinesGenerated: {2}", textGenSetting.generationExtents.x, textGenSetting.generationExtents.y, generator.lineCount));
    48.         }
    49.     }
    Since I'm not sure which method/field should be giving me the correct height and width for any given text, I'm printing multiple fields/method results to the console.

    However, none of those gives the desired result.


    ----------


    Outputs of Debug Log 1

    The line marked //Debug Log 1 above gives the following output when I have an empty string (""), a string with one character ("a"), a string with two characters ("aa"), and a long string (with plenty of spaces in between for potential line breaks)

    Outputs of Debug Log 2

    Here's the same for Debug Log 2

    Outputs of Debug Log 3

    And here for Debug Log 3


    ----------


    Conclusion

    Debug Log 1

    generator.GetPreferredWidthadds 7 to the preferred width for each character (and 4 for each space) and generator.GetPreferredHeight adds 15 to the preferred height for each character (no idea why) and neither GetPreferredWidth nor GetPreferredHeight calculate line Breaks in any sensible way


    Debug Log 2

    generator.rectExtents.width gets incremente by 7 for each character (and 4 for each space), but generator.rectExtents.height is not incremented at all (so again, no line breaks or valid height readings)

    Debug Log 3

    This (probably expected) always outputs 20,20 (i.e., whatever textGenSetting.generationExtents is set to). I tried this anyway since I thought maybe generator.Populate() would update this value of the textGenSetting struct.

    Question: Am I missing something? Or is this in some way expected behaviour? How can I get this to work, or, alternatively, use some other way to auto-layout text and get the extents of said text so that I can adjust my sprites to fit this text?


    Here are my text settings, for complete information.

     
  2. unity_E9FfAw7RsMp7yg

    unity_E9FfAw7RsMp7yg

    Joined:
    Jan 13, 2020
    Posts:
    14
    Welp, turns out after writing this post, even though I had done quite some research before, I finally found an answer. Changing my RecalculateText method to the following worked, allthough I haven't investigated where I went wrong with my previous approaches.

    Code (CSharp):
    1.     private void RecalculateText(string sText)
    2.         {
    3.             TextGenerator textGen = new TextGenerator();
    4.             TextGenerationSettings tgSettings = text.GetGenerationSettings(text.rectTransform.rect.size);
    5.             var width = textGen.GetPreferredWidth(text.text, tgSettings);
    6.             var height = textGen.GetPreferredHeight(text.text, tgSettings);
    7.         }
    Kudos go to pineda100, who's answer to a similar question provided the snippet above.