Search Unity

Bug when adding string variables with escapes

Discussion in 'UGUI & TextMesh Pro' started by Martin_Gonzalez, Feb 24, 2021.

  1. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    I'm reading strings from a csv files and one of the values has \n escapes. Seems that adding strings variables with escape on them and adding it to a TextMeshPro Text component is does not refresh or parse correctly even having the boolean `parse escapes characters`

    Tested on 2.0.1 & 2.1.4

    I would like to know if there is a workaround. I've tried with
    * _tmpText.ForceMeshUpdate(true);
    * _tmpText.ForceMeshUpdate(true, true); (the second true is force reparse :/)
    * _tmpText.UpdateMeshPadding();
    * putting parse escpae boolean false and true after setting text

    The bug is easy to reproduce.

    Attach this script to a TextMesgPro Text component

    Code (CSharp):
    1. using TMPro;
    2. using UnityEngine;
    3.  
    4. public class TextMeshProBugTest : MonoBehaviour
    5.     {
    6.         public string value = "";
    7.         private TMP_Text _tmpText;
    8.  
    9.         void Awake()
    10.         {
    11.             if (_tmpText == null) _tmpText = GetComponent<TMP_Text>();
    12.             _tmpText.text = value;
    13.         }
    14.     }
     

    Attached Files:

    Last edited: Feb 24, 2021
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The "Parse escape characters" property only affects the text input box. Not text set via the .text property.

    With respect to the text property, TMP processes the string exactly as it is in the string where as such escape sequences will display as is. If the text contains "\\n" then "\n" will be displayed. If the text contains "\n" then we get a linefeed.

    How should you handle this?

    It is important to understand how the external file handles control characters. Most of the time, control characters are escaped where as such you will need to filter the incoming data using string.replace to provide TMP with a string that accurately reflects what you want to see displayed.
     
  3. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    I'm setting this value in an inspector variable

    Some \n Excaped \n Text \n Not working :(

    And is not working :/

    If I update anything, like a padding, a boolean or a space in the text box is reparsed correctly

    upload_2021-2-24_19-35-19.png
     
  4. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    I didn't get the "\\n" and "\n". You are saying that if in my string I have a "\n" it should escape? If yes, the example above shows that is not working that
     
    Last edited by a moderator: Feb 24, 2021
  5. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    If you were to iterate over the string coming from this .csv file, you would notice that "\n" is not char(10) but instead represented as "\\n" which translates to "\" + "n" or two distinct characters.

    Public fields in the Editor also end up being escaped.

    For instance:
    Code (csharp):
    1.  
    2. public string s = "\n"; // This is a single character which is char(10)
    3.  
    Now if you were to type \n in the inspector public field and then iterate over each char of the string. This "\n" would actually be "\\n" in the string which is two distinct character or "\" + "n" which is not char(10).
     
    Last edited: Feb 24, 2021
    Martin_Gonzalez likes this.
  6. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    Ok, doing value = value.Replace("\\n", "\n"); as you said worked.
    Is there a reason why there is no boolean or something related to this out of the box?
    Make sense to add it? I mean, is there a reason I would add \n on the text box where I can hit enter directly or are there other use cases I'm missing?

    BTW thanks for the explanation!
     
  7. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    There is for the Text Input Box which is the "Parse Escape Characters" where in this case, TMP knows the source of the input and the intent of the user.

    However, when the text comes from a string, TMP has no clue whether this was a private string or some public string that was edited in the inspector where in this case it has to process the string exactly as it is provided.
     
  8. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    And adding some bool called forceStringEscapeReparce or something similar you say no adds value?
    That every time text is set, checks that condition and do the replace itself. I'm asking perhaps it can add value to the tool
     
  9. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Assuming we add this new property, we would still end up at the same place where 98% of the time, the user is unaware of the string potentially containing escaped characters based on the source of the string. Ie. Private string, public string edited in the Inspector or external source such as xml, csv, etc.

    Once the user is aware of the above, it is pretty easy to handle the reparsing of the string when necessary depending on the source and to make sure when they set the text, that the string correctly reflects their intent.

    Alternatively, the user could set this new property but that amounts to again knowing when it needs to be set vs when not to set it so why not make sure the content of the string is correct before setting the text property.
     
    Martin_Gonzalez likes this.