Search Unity

TextMesh Pro Leading zeros string-format support

Discussion in 'UGUI & TextMesh Pro' started by Peter77, Feb 10, 2020.

  1. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    I would like to use the GCAlloc free
    TextMeshProUGUI.SetText
    method to display the elapsed time in a racing game.

    I want to display leading zeros for seconds and milliseconds. However, TextMesh Pro currently does not seem to support this.

    Input:
    Label.SetText("{0}:{1:00}.{2:000}", 1, 2, 34);


    Actual output:
    1:2}.34}


    Expected output:
    1:02.034


    Using string.Format can be used as a workaround, but it generates garbage memory.
    Label.SetText(string.Format("{0}:{1:00}.{2:000}", 1, 2, 34));


    Could you please add/fix leading zeros support?
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    I made the improvements to add support for leading / padding the integral part of the values.

    This change will affect the previous format where given {0:2} the 0 indicated the index for the argument and 2 the decimal precision.

    Given {0:0000.000}

    As a result of this change, {0} will continue to represent the index of the argument.
    The sequence of 0's following the ':' will represent the padding for the integral and lastly the 0's following the '.' the decimal precision.

    The format could also be revised to {0:4.2} could be used where 0 is the index, 4 integral padding and 2 decimal precision. This would deviate from string.format but be closer to the previous implementation.
     
    Peter77 likes this.
  3. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Does that change the behavior of any previously-valid usage?
     
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    It does as the previous implementation did not provide for defining leading zeros. In addition, instead of using a series of zero's to define decimal precision, it used a whole number like 4 to indicate 4 decimal places.
     
  5. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    I think you misunderstood my question. Obviously it adds options that didn't exist before. My question is: if someone has already written a working game using the old system, and then they update to the new version of TMP, will their existing code break?

    Or are the old legal usages going to continue doing the same things they've always done?

    (This is just the standard backwards-compatibility question that you should probably be asking every time you change anything in a library.)
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    As per my previous reply, this could potentially affect the previous use case where given...

    Example 1:
    TextComponent.SetText("({0})", 154.575f);

    A value of 155 would be shown whereas a value of 154.575 would be shown in the new implementation.

    Example 2:
    TextComponent.SetText("({0:0})", 154.575f);

    A value of 155 would be shown in both cases.

    Example 3:
    TextComponent.SetText("({0:2})", 154.575f);

    A value of 154.58 would be shown in both cases.

    Example 4:
    TextComponent.SetText("({0:0000})", 154.575f);

    A value of 15500} which is a bug / confusing whereas 0155 would be shown with the change.

    Example 5:
    TextComponent.SetText("({0:0000.00})", 154.575f);

    A value of 15500.00} which is also weird / confusing whereas with the change 0154.58

    I always consider how changes affects backwards compatibility which is why I highlighted the differences in my first post and to get feedback.

    Like I stated, this change would result in a change for the use case of {0} by itself which rounds up the value to show a whole number whereas using {0} with string.format shows the unaltered value. All other usage SetText() would remain the same but with the added functionality.

    P.S. While at it, I also uncovered potential rounding issues (present in previous implementation) which I could also address. Those rounding issues are simply the result of float to double.

    P.S.S. I could make Example 1 behave the same but I think that is unlikely the desired / expected behavior.
     
    Last edited: Feb 11, 2020
    vamuigua, GuitarBro and Peter77 like this.
  7. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    Thanks for the quick help, that's fantastic!

    Do you know in what package version the improvements are made available? I'm using Unity in 2018.4.

    I think the closer TMP is to string.Format, the easier to use it is. The new behavior of Example 1 would match string.Format, so I prefer the new way over the previous.
     
  8. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    OK. I just wasn't confident in my own ability to reason out all the implications given only the information in your first post.
     
  9. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    180
    Has this change been implemented yet? I'm not seeing the expected behavior in 2.0.1/Unity 2019.3.
     
  10. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Latest release is 2.1.0-preview.13.
     
    GuitarBro likes this.
  11. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    180
    Ah ok, I don't have preview releases shown. I'll try that. Thanks.
     
    Stephan_B likes this.
  12. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    180
    Perfect! That did the trick!

    (Also thanks for the killer 11 minute response time on that one. ;))
     
  13. vamuigua

    vamuigua

    Joined:
    Apr 17, 2020
    Posts:
    1
    Thanks...really helped out
     
  14. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    180
    One interesting case I ran into:

    I'd like to show the numbers after the decimal point in a smaller size. Using this formatting, is there a way to get only the fractional part of the float without the leading 0? My guess at using "{0:.00}" unfortunately outputs "#.##" instead of "##" like I want.