Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Using .text of a TMP_Text component to set a unicode value shows up as a string literal

Discussion in 'UGUI & TextMesh Pro' started by LCLapierre, May 29, 2019.

  1. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    Hey,

    So I've been trying to use TMPro and my custom made font asset to show a unicode value (in this example \uE003) as a Y XBox button.
    upload_2019-5-29_11-39-36.png
    This character entry is present in my backup font asset which I assigned to my main font asset.

    If I type \uE003 directly in the inspector in the text box of my component, everything works correctly. If I do it in my code, it doesn't work. I've read on other threads that this might be because C# is adding an additionnal \ to the string because it takes it as a string literal, but I've verified while debugging that the correct string is passed in the .text attribute. See photo :
    upload_2019-5-29_11-42-49.png

    As you can see, I tried a bunch of other ways to make this work, unfortunately it didn't. I also went digging through TMPro code and I found out that the actual cause of the problem is that when you set the text through the inspector, the InputSource is Text and when set through the attribute, the InputSource is String.

    This means that later, in the method : TMP_Text.StringToCharArray(string sourceText, ref UnicodeChar[] charBuffer) the code doesn't enter in the switch case (because the InputSource is String and not Text) and therefore, the code doesn't detect that it's a unicode value that I'm passing to my TextComponent.

    I tried setting directly doing m_Button.text = "\uE003" directly in code to be sure that there wasn't a \ that was being added and that also doesn't work. As soon as I change anything in the inspector, all goes well. So this is why I'm beginning to think that StringToCharArray might be missing some support when using the .text attribute or I'm missing something here.

    If you need anymore information, do not hesitate, thanks!
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    If I understand correctly. You are initially setting the text using a char[] and then subsequently use the .text property at which point the text doesn't get updated. Correct?
     
  3. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    I have a scriptable objects in which I map a ButtonBinding to a UnicodeValue.
    upload_2019-5-30_13-54-7.png
    upload_2019-5-30_13-55-2.png

    Like so.

    I then search for the correct string when I want to create my prompt depending on which button needs to be shown. I've seen threads saying that if you enter a string in the inspector like this, C# and Unity will add an additional / in front of it so it's a string literal but it's not what I'm seeing as I debug and see the value of the actual string that I'm passing in the .text method.
     
  4. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    Also, the .text gets updated correctly, it gets set to \uE003 but not to the actual glyph being represented by that unicode value, which is a Y button on xbox.
     
    Last edited: May 30, 2019
  5. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    What does the string contain when you inspect it while debugging? Can you post that?

    If you type these values in the Inspector, they will be escaped. There is no way around this, since that is default behavior of all text fields in the editor.
     
  6. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    The string contains \uE003 like I posted in my first post (second image). I also tried doing this :
    m_Button.text = "\uE003" and it also doesn't work.
     
    Last edited: May 30, 2019
  7. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    Text before set.
    upload_2019-5-30_16-5-35.png
    The buttonText string is "\uE003"
    upload_2019-5-30_16-3-18.png
    The text after set.
    upload_2019-5-30_16-6-33.png
     

    Attached Files:

  8. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The above should work.

    When you say it does not work, do you mean the glyph doesn't show up or you see the string literal?

    Can you create a simple repro project / scene that I could take a look at?
     
  9. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    I see the string literal, afterwards, if I go in the inspector of my text component, add a space, the glyph then shows up, I can remove the space and it's still there.
    I can try and create a simple project tomorrow (currently not at the office), I'll see what I can do. Won't be able to use my company's font asset and stuff but I'll try with a random unicode.
     
    Stephan_B likes this.
  10. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    So, I made a few tests and I don't know what was happening before but I can now confirm that if I do :

    m_Button.text = "\uE003", it works correctly, I'm not sure what I did before but now it works.

    I still have the same problem though that when it comes from the ScriptableObject (meaning it was entered in the inspector), it comes out as a string literal (as expected as you told me and as I understand from other posts) and not the glyph.

    Would there be a good way to do this and still use the inspector? Some way to transform the string literal that I receive in another string to be properly recognized as a unicode value?
     
  11. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    I tried removing my having \\uE003 in my inspector and then in my code doing a Replace(@"\\", @"\") but the result is the same as I assume what's being returned is a string literal.
     
  12. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    See the following post and thread.
     
  13. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    So the only way to compile the code with Replace is to use :
    m_Button.text = buttonText.Replace(@"\\", @"\"); and this doesn't work.

    upload_2019-5-31_15-27-59.png

    upload_2019-5-31_15-28-19.png

    Since \u is not an escape sequence like \n or \t, I'm not sure how i can properly replace the \\ with a single \, any more ideas?
     
  14. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The following should do the trick for both "\u" and "\U"

    Code (csharp):
    1.  
    2. using System.Globalization;
    3. using System.Text.RegularExpressions;
    4. using UnityEngine;
    5. using TMPro;
    6.  
    7. public class Example : MonoBehaviour
    8. {
    9.     public TMP_Text TextComponent;
    10.     public string m_Label = "\uFFFC";
    11.  
    12.     private Regex m_RegexExpression = new Regex(@"(?<!\\)(?:\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8})");
    13.  
    14.     private void Awake()
    15.     {
    16.         m_Label = m_RegexExpression.Replace(m_Label,
    17.             match =>
    18.             {
    19.                 if (match.Value.StartsWith("\\U"))
    20.                     return char.ConvertFromUtf32(int.Parse(match.Value.Replace("\\U", ""), NumberStyles.HexNumber));
    21.                
    22.                 return char.ConvertFromUtf32(int.Parse(match.Value.Replace("\\u", ""), NumberStyles.HexNumber));
    23.             });
    24.  
    25.         TextComponent.text = m_Label;
    26.     }
    27. }
     
  15. LCLapierre

    LCLapierre

    Joined:
    Apr 29, 2019
    Posts:
    15
    It indeed worked, thank you very much.
     
  16. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Glad it is working and you are most welcome.