Search Unity

TextMesh Pro Escape Characters Aren't Being Automatically Parsed From SetText

Discussion in 'UGUI & TextMesh Pro' started by SweetBro, Feb 6, 2018.

  1. SweetBro

    SweetBro

    Joined:
    Jan 14, 2013
    Posts:
    69
    So I've set the flag to parse escape characters. However when I call SetText on the object the escape characters particularly \n aren't parsed. Manually changing the any value in the inspector causes it to update and function as expected. Is there an additional update function I should call to trigger the parse?

    Relevant Code:

    Code (CSharp):
    1.     public void SetText(string newText)
    2.     {
    3.         Initialize();
    4.         text.SetText(newText);
    5.         text.ForceMeshUpdate();
    6.         totalCharacterCounter = text.textInfo.characterCount;
    7.         if(typewriterEffect == true)
    8.         {
    9.             typewriterFinished = false;
    10.             StopCoroutine("TypeWriterEffectLoop");
    11.             StartCoroutine("TypeWriterEffectLoop");
    12.         }
    13.     }
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    In a string of text, TMP will process the text exactly as provided. So if the string is "First line\nSecond line", you will have two lines of text. If the string is "First line\\nSecond line" then the linefeed "\n" will be esacped due to the "\\n".

    In the Text Input Box, depending on whether the "Parse Escape Characters" is set in the Extra Settings, escape characters will either be parse or not.
     
  3. SweetBro

    SweetBro

    Joined:
    Jan 14, 2013
    Posts:
    69
    Neither \n, nor \r\n, nor \\n work. Parse Escape Characters is checked.
     
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The "Parse Escape Character" only applied to the text typed in the "Text Input Box". It does not apply to text contained in a string (for example) passed via the text property of the text object.

    The top line has "Parse Escape Characters" disabled and the bottom line has it enabled.



    Are you typing the text in the "Text Input Box" or using a string?

    If a string, is this string defined in your script or filled-in as a Public string in the Inspector?

    This is important because Unity will escape the "\n" in a public field where if you were to iterate over each character contained in this string you would see this "\n" linefeed has been converted into "\" and "n" which is not a linefeed.

    Here is a simple example to test with. Create some new GameObject and add the following script to it. Create two text components and assigned them to the script. Then type the label2 text which is "A line\nof text.".

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using TMPro;
    4.  
    5. public class Sandbox_01 : MonoBehaviour
    6. {
    7.     public TMP_Text textComponent1;
    8.     public TMP_Text textComponent2;
    9.     string label1 = "A line\nof text.";
    10.     public string label2;
    11.  
    12.     void Awake()
    13.     {
    14.         textComponent1.text = label1;
    15.         textComponent2.text = label2;
    16.     }
    17. }
    18.  


    If you look at the label1 string and label2 in the Inspector, they are the same but like I mentioned the public string in the Inspector ends up with the "\n" getting escaped which can be very confusing.
     
    Last edited: Feb 8, 2018
  5. SweetBro

    SweetBro

    Joined:
    Jan 14, 2013
    Posts:
    69
    Ah I think I know what's happening here. I am actually serializing the data to a JSON and loading from there. However, it looks like the same behavior that automatically escapes "\n" in a public field also causes it to escape when serializing (when I inspected the final JSON I saw that the line contained \\n instead of \n). Thank you very much for helping me clear that up.

    Although I know this is no longer directly related to TMPro would you happen to know the practical method of stopping this behavior?
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    I think this escaping of control characters is by design in many file formats like .json. See the following.

    Once you know this is likely to happen based on the file format you are using, most TMP users will do a string.Replace on the imported text.
     
    unnanego likes this.
  7. SpaceManDan

    SpaceManDan

    Joined:
    Aug 3, 2013
    Posts:
    15
    For those that are having trouble with this it may be important to point out that .Replace is a return value. If you are trying to do the following you'll not see any change.

    myString.Replace("\\n", "\n");

    You'll need to set your string to the value like so

    myString = myString.Replace("\\n", "\n");

    If you have more than one you'd like to replace you can stack the function like so

    myString = myString.Replace("\\n", "\n").Replace("\\t", "\t");
    or
    myString = myString.Replace("\\n", "\n").Replace("\\t", "\t").Replace("nexttexttoreplace", "next text to replace");

    Hope this helps somebody.
     
    AM-Dev, HinxVietti_WITL and unnanego like this.
  8. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    199
    I'm using a scriptable object. I am injecting a text from the scriptable object, but parsing the escape characters is not working anyhow.
     
  9. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    How so?

    Can you provide the raw text you are using?
     
    unnanego likes this.
  10. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    199
    Here's the string: Lunar Dog\nHound of the Baskervilles Sherlock Holmes. I input it into the scriptable object in inspector. Then in the script this string is set to a TMP Text go. Neither \n nor \\n work, "parse" is checked.
     
  11. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    As per some of my posts above, if this text is entered into a public field, Unity will escape the "\n" which will then be seen by C# as 2 distinct characters which are "\" and "n". Stepping through your code to see the content on the string will reveal this. You will need to do a string replace to handle this.

    See the following thread as well.
     
    unnanego likes this.
  12. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    199
    What should I replace it with?
     
  13. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    As per the post right above yours stated, you need to remove the extra "\" from the string.
     
    unnanego likes this.
  14. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    199
    Oh, thanks, it worked!
     
    Last edited: May 9, 2019
    Stephan_B likes this.
  15. sinjimonkey

    sinjimonkey

    Joined:
    Jul 31, 2013
    Posts:
    72
    I can't seem to get this to work at all. As near as I can tell, my string contains /n (not //n) and doing a replace (even with x = x.replace) doesn't seem to change anything according to debug logs.

    I have Parse Escape Characters checked. Now, if I uncheck it and recheck it in the editor, it parses. If it's unchecked when the string is set and I later check it it parses. I figured I could work around this by setting the boolean in code, but it doesn't seem to be exposed (There is a 'parseCtrlCharacters' field, but that doesn't seem to work when I set it ttrue after setting the text.)
     
    13E12K and adityaspt like this.
  16. EmilieCollard191

    EmilieCollard191

    Joined:
    May 8, 2019
    Posts:
    77
    Did you find what was your problem?
     
  17. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The Parse Escape Characters option only applies to text in the Text Input Box. It does not apply to text set via the .text property or SetText() functions as users have full control over those strings and potential escape characters.

    The best way to identify these types of potential parsing issues is to set a break point in your code and check the actual value of each characters. This is when you would notice that some of the characters have been escaped.

    It is pretty common for text coming from XML, json, etc. to contain escaped characters. It is also something to be mindful of when declaring a public string as editing this string in a text field in the Inspector will result in control characters for instance to be escaped.

    Code (csharp):
    1. public string s = "1st line of text.\n2nd line of text.";
    Assigning the above string to the .text property of a text object will work as expected. However, editing this string in a public text field in the Inspector will result in the linefeed "\n" to be escaped where it is now two distinct characters or a "\" + "n" instead of the char(10) linefeed.

    See the thread I referenced in my reply above.