Search Unity

Need some help understanding how to use complex SmartStrings

Discussion in 'Localization Tools' started by B_Richard, May 4, 2021.

  1. B_Richard

    B_Richard

    Joined:
    Sep 21, 2020
    Posts:
    16
    Hi,
    I'd like to get some help understanding how to properly use complex SmartStrings.

    By "complex", I mean those with imbricated {} (like, with Lists, objects, etc).

    Up until now, I've been using SmartStrings for simple strings that only looked like
    My value is {0}
    and everything worked fine but now that I'm trying with more complex ones, it does not work as expected.

    So, here is the complex SmartString I'm trying to work with :
    {Options:{Value} Options:{Type:A|B|C|D|E|F|G}| | and }


    And here is my current code :
    Code (CSharp):
    1.  
    2. var opts = new List<object>();
    3. opts.Add(new { Value = 1, Type = 2 });
    4. opts.Add(new { Value = 1, Type = 0 });
    5. // here, myKey is linked to the correct SmartString I defined above (in the inline code block)
    6. StringUtils.CreateLocalizedString("myTable", "myKey", new List<object>() { new { Options = opts } }).StringChanged += (s) =>
    7.         {
    8.             text.text += s;
    9.         };
    10.  
    And in another class :
    Code (CSharp):
    1.  
    2.     public static LocalizedString CreateLocalizedString(string tableRef, string tableKey, List<object> arguments = null)
    3.     {
    4.         var locString = new LocalizedString();
    5.         if (arguments != null)
    6.             locString.Arguments = arguments.ToArray();
    7.         locString.SetReference(tableRef, tableKey);
    8.         return locString;
    9.     }
    10.  
    So, with this code, I expected to get this string "1 C and 1 A\r" but I got "A\r".

    Is there anything I'm doing wrong ?
    Maybe there is a setting I forgot to toggle to make intricated SmartStrings work ?

    Also, I'm working on Unity 2020.2.2f1 and Localization package v0.11.0-preview (almost the latest, I just saw that you released a new update).

    Thanks.
    Benoît R.
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    Hey,

    Nice to see someone getting stuck into Smart Strings :)

    So we want to first select our value, then pick the formatter and then provide options etc.


    Let's start simple and build-up

    1)
    First we want each item in the list.
    so
    Code (csharp):
    1. {Options:list:{}|, |, and }
    produces:
    { Value = 1, Type = 2 }, and { Value = 1, Type = 0 }

    Here I am telling it to use the list formatter. You can also leave the formatter name empty and let it implicitly pick the list formatter but I'm being explicit here. This is how implicit would look:
    Code (csharp):
    1. {Options:{}|, |, and }
    2) Now for each item we first want the Value. So instead of {} which is the whole item we will select the Value only.
    Code (csharp):
    1. {Options:list:{Value}|, |, and }
    This produces:
    1, and 1

    3) Now the next thing we want is to also add the choice value next to the value. So we need a separate nested area. First lets just print the value:


    Code (csharp):
    1. {Options:list:{Value}{Type}|, |, and }
    This produces
    12, and 10

    4) We want to convert the Type using a choice:
    We need to provide the choices and the values that should be used instead. A bit like an enum.

    0 = A
    1 = B
    2 = C
    3 = D
    4 = E
    5 = F
    6 = G

    We do this by first saying the values we expect inside of () and then the value to map to after the ():
    like so:

    Code (csharp):
    1. {Type:(0|1|2|3|4|5|6):A|B|C|D|E|F|G)
    now put this into the string and we get:

    Code (csharp):
    1. {Options:list:{Value}{Type:choose(0|1|2|3|4|5|6):A|B|C|D|E|F|G}|, |, and }
    which produces
    1C, and 1A
     
    Last edited: May 4, 2021
    B_Richard likes this.
  3. B_Richard

    B_Richard

    Joined:
    Sep 21, 2020
    Posts:
    16
    Thank you very much ! Your answer was really helpful !

    Side note to anybody that may need this info : an enum value is not automatically casted as an integer when used with SmartStrings. You have to manually cast it if you want it to be used as an int, otherwise it is the enum name that is used.

    In my example, I was using an enum value as the argument for this section
    {Type:choose(0|1|2|3|4|5|6):A|B|C|D|E|F|G}
    and it took me quite a long time to figure out what was the problem.
     
    karl_jones likes this.
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    Hmmm I think it should be possible to use an enum. I'll look into it.