Search Unity

TextMesh Pro Programmatically Set Text Doesn't Format By Itself

Discussion in 'Unity UI (uGUI) & TextMesh Pro' started by ATLAS-INTERACTIVE, Aug 1, 2017.

  1. ATLAS-INTERACTIVE

    ATLAS-INTERACTIVE

    Joined:
    Mar 3, 2014
    Posts:
    1,295
    While switching a few things to TextMesh Pro after UT obtained it (great job on that by the way, much love) I realised that formatting, in the sense of rich text, don't format themselves automatically.

    Using the ascii table key \u2022 as a bullet point, and <indent=1em> for padding, my text doesn't format by itself.

    TextMeshPro Rich Text.png

    But once I edit the text in the Unity Editor (remove and re-add a space for example), it displays correctly.

    TextMeshPro Rich Text 2.png

    Code (CSharp):
    1. public TextMeshProUGUI displayPage;
    2. void Start()
    3. {
    4. displayPage.text = displayText;
    5. }
    Does anyone know of a way to fix this, am I missing an option or something?
     
    naviln likes this.
  2. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,187
    Using the following variation of your script works as expected on my end.

    Code (csharp):
    1. public TextMeshProUGUI TextComponent;
    2. private string m_label = "\u2022<indent=3em>Hello there!";
    3.  
    4. void Start()
    5. {
    6.      TextComponent.text = m_label;
    7. }
    Based on how the text appears over each other, check to make sure that if you copy / pasted the text that you don't have some hidden carriage return characters in that string / label.
     
  3. ATLAS-INTERACTIVE

    ATLAS-INTERACTIVE

    Joined:
    Mar 3, 2014
    Posts:
    1,295
    The text that is being assigned to it is being done by passing the text from a text file (TextAsset) into the display.
    I'm not sure whether anything like a return might be added somehow while doing that, but in the file at least, there is no hidden returns or anything.
     
  4. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,187
    I recommend you iterate over each character (debug log value of each char) from that string.

    Most likely, the \u is getting converted into \\u (double escape) which means to process it as a string literal instead of the \u escape character

    You might also notice some char(10) and char(13) in there as well. If that is the case, you will need to use some string.replace to strip those out.
     
  5. JennyHide

    JennyHide

    Joined:
    Sep 30, 2014
    Posts:
    33
    This is happening for me too - the \u2022 gets displayed as \u2022 rather than as a bullet point unless I edit something in the inspector. The text comes from an XML file. If I copy and paste the same text into something like

    Code (CSharp):
    1. text.text = "\u2022 A bullet point";
    It works fine. It's only when the text is coming from an external file that there's a problem.

    Logging the text to the console shows that the text is \u2022, as it should be - there's no double escape happening. I double checked using string.replace to change \\ to \, but nothing changed.

    Any ideas?

    Thanks,
    Jenny
     
  6. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,187
    If the issue only happens when the string comes from an external file then it has to be related to double escaping. Although that is what I believe you did, re-check the unicode value of each character from that file by creating a for loop and iterating over stringText to see the value. This should shed some light on the behavior.
     
  7. JennyHide

    JennyHide

    Joined:
    Sep 30, 2014
    Posts:
    33
    I know logically that you must be right. Here's what I get from looping over each character separately:

    upload_2017-8-18_9-50-18.png

    Am I missing something?
     
  8. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,187
    Take a look at the int value of those characters to make sure the "\" is 92 and the space before it is 32.

    There is also an Parse Escape Characters toggle in the Extra Settings. It should not affect this but just in case.

    Can you create a simple scene that would allow me to reproduce this?
     
  9. JennyHide

    JennyHide

    Joined:
    Sep 30, 2014
    Posts:
    33
    The \ is 92, and the line before comes out as 10, which is \n:

    upload_2017-8-28_10-1-25.png

    (The commas in the output are mine, used to split the character and the ASCII).

    The Parse Escape Characters toggle in Extra Settings didn't make a difference.

    I'll make a simple scene when I have some time.

    Thanks,
    Jenny
     
  10. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,187
    A simple scene would be great but perhaps look at the source text file might reveal the issue and spare you from having to create the scene. You can email me or PM me a link to the source text file.
     
  11. naviln

    naviln

    Joined:
    Oct 18, 2016
    Posts:
    17
    This was frustrating me to no end, but i finally got myself a solution:

    In my source text file, instead of putting:
    \u2022<indent=3em>A Bullet point text test</indent>

    I replaced it with something I can easily target and replace (I chose <bullet> for simplicity):
    <bullet><indent=3em>A Bullet point text test</indent>

    Find out the unicode UTF-16 (hex) code for the bullet point:
    https://www.fileformat.info/info/unicode/char/2022/index.htm

    (so it is 0x2022)

    In my code, I replace the bullet like so:

    Code (CSharp):
    1. //grab unicode patterns and replace them
    2. devMessageText.text = devMessageText.text.Replace("<bullet>", Convert.ToChar(0x2022).ToString());
    and finally i got the bullet point in my TextMeshPro Asset displaying properly.

    Hope that helps someone out there.

    Cheers
    Navil
     
    Last edited: Jun 16, 2018
    unity_QzmvR2WrBsSXAw likes this.
  12. thylaxene

    thylaxene

    Joined:
    Oct 10, 2005
    Posts:
    705
    Yep I'm certainly seeing it here in Unity 2018.2 using TextMesh Pro. You can't simply tell the component to change the text from say \uf028 to \uf026 (I'm using Font Awesome) I have to do the whole Convert.ToChar(0xf026).ToString(). Not a deal breaker but seems strange that this still doesn't seem to work.

    Here is my example:
    Code (CSharp):
    1. public string toggleUnicode = "f026";
    2. public string defaultUnicode = "f028";
    3. private bool _altToggleStateShowing;
    4.  
    5. int code = int.Parse(_altToggleStateShowing?toggleUnicode:defaultUnicode, System.Globalization.NumberStyles.HexNumber);
    6. btnIconText.text = System.Convert.ToChar(code).ToString();
    Probably a better way of doing this?

    Cheers.
     
    Last edited: Aug 25, 2018
  13. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,187
    The issue here isn't related to TextMesh Pro but to how the Unity Editor text field handles escape characters.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using TMPro;
    4.  
    5. public class Sandbox_01 : MonoBehaviour
    6. {
    7.     public string someText = "\uf026";
    8.  
    9.     public TMP_Text TextComponent;
    10.  
    11.     private void Awake()
    12.     {
    13.         // This will work fine.
    14.         TextComponent.text = "\uf026";
    15.  
    16.         // This will work fine as well.
    17.         TextComponent.SetText("\uf026");
    18.  
    19.         // This is tricky since the Unity Editor text field will escape the "\" and instead of converting the value into a single unicode
    20.         // This will result in a string that contains '\' + 'u' + 'f' + '0' + '2' + '6' or 6 individual characters.
    21.         TextComponent.text = someText;
    22.     }
    23. }
    24.  
    If you test the above code, one text line at a time of course, you will see that issue with the public field. If you convert that to a private field, then the text will display correctly again.

    In my opinion, this special handling of escape characters in a public field in the inspector is very confusing. When I have time, this is something that I would like to revise.

    P.S. Unless you are trying to combine text with some value, I would suggest you use the .text property instead of SetText().
     
  14. thylaxene

    thylaxene

    Joined:
    Oct 10, 2005
    Posts:
    705
    OK cool good to know thanks. However whole point is to have it exposed for editing in the Editor. Oh well yet another Unity idiosyncrasy to mark down and remember. ;)
     
  15. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,187
    That is exactly why I want to revise how Escape characters are handled in Editor text fields as most users who run into this are looking to do something similar to you.
     
  16. qwerty21kg

    qwerty21kg

    Joined:
    Nov 7, 2016
    Posts:
    1
    I don't know if it has been fixed in Unity 2019.x but encountered the same issue in 2018.3.1f. I am reading a text from a file and assigning it to a TextMeshPro component in the scene.
    After reading the comments here, I solved the problem in the following way:

    TextMeshProComponent.text = textAsset.text.Replace(@"\u2022", "\u2022");

    Hope it helps someone else as well.
     
  17. unity_QzmvR2WrBsSXAw

    unity_QzmvR2WrBsSXAw

    Joined:
    Dec 7, 2018
    Posts:
    1

    This works, Thanks