Search Unity

Question TMP: How to determine best-fit font size when "Auto Size" is disabled?

Discussion in 'UGUI & TextMesh Pro' started by SeriouslyNot, Jul 5, 2020.

  1. SeriouslyNot

    SeriouslyNot

    Joined:
    Nov 24, 2017
    Posts:
    121
    Unity said in their "Performance Tips" tutorial that we should never use the "Auto Size" feature on UIText and also TextMeshPro and i strongly agree:



    My game uses TMP on MeshRenderer (no canvas) a lot and i enabled "Auto Size" on all objects.

    How can i "Best Fit" all fonts in their respective container without using "Auto Size"?
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    See the following post which describes how to be use auto size.
     
  3. SeriouslyNot

    SeriouslyNot

    Joined:
    Nov 24, 2017
    Posts:
    121
    Thanks, but my case is a bit more complicated, take a look at the screenshot:





    This is a "balls hitting bricks" game, those are the bricks; each brick has a number, whenever it gets hit by a ball, the number goes down by -1.


    The bricks may have different range of numbers, the brick that has "1000" should has smaller font than the brick that has "9", because if they both have the same fontSize, the "9" brick would look too small or the "1000" brick would overflow.

    The brick is a Prefab (SpriteRenderer gameObject and TMP gameObject), i'm using TextMeshPro component with MeshRenderer (no canvas).

    If i follow your post, i have to run your script every time a brick gets hit (because the number changed) which is a LOT, and we're talking about one cube only....

    I thought a lot about how to make this possible, but i think that i can't, i'll end up doing exactly what "Auto Size" does!

    So i guess i HAVE to use "Auto Size" in my case, right?

    @Stephan_B
     
    Last edited: Jul 6, 2020
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Thank you for providing this additional information and context.

    I think you could still use the revised implementation I suggested in that post but instead pre-calculate the optimum point size per font asset using "0", "00", "000" and "0000" instead of words or lines of text.

    In some loading / preparation process, you would pre-calculate the optimum point size for the given font asset using these "0", "00", "000" and "0000". This would be done using auto-size only once.

    Then while your game runs, you would be sure to set the pre-calculated point size on the relevant text objects (with auto-size disabled) based on whether the number contains 1, 2, 3 or 4 digits. This would ensure that all text for each of the digit group uses the same point size.

    P.S. I picked zero since most of the time it is the widest digit but in this setup / pre-calculation phase, you could actually check the width of each digit for a given font asset to make sure you use the widest one in this calculation of the optimum point size.
     
  5. SeriouslyNot

    SeriouslyNot

    Joined:
    Nov 24, 2017
    Posts:
    121
    @Stephan_B
    Wow, i don’t know why I didn’t think of that. This is brilliant. :)

    So calculate the optimal font sizes for 0, 00, 000, 0000 and save them in an array, then every time the cube gets hit, i check for the new number and apply the font size for the corresponding digit count. Right?
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Correct.

    As you update the numbers on hit, you check the resulting number of digits and adjust the point size as necessary.
     
  7. SeriouslyNot

    SeriouslyNot

    Joined:
    Nov 24, 2017
    Posts:
    121
    @Stephan_B Thank you very very much!
     
    Stephan_B likes this.