Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved Trying to wrap my head around smart strings

Discussion in 'Localization Tools' started by Kazen, Mar 16, 2021.

  1. Kazen

    Kazen

    Joined:
    Feb 17, 2015
    Posts:
    68
    So I'm trying to get smart formatting to work and found this thread that seems to be doing the same thing I'm trying to do. Basically I'm just doing this (for testing purposes obviously), which is the same as in the linked thread:
    Code (CSharp):
    1.  
    2. Dictionary<string, string> dict = new Dictionary<string, string>();
    3. dict["test"] = "testing";
    4. localizedString.GetLocalizedString(dict);
    And using a string like this:
    Start game {test}


    But get errors that I could not format the string
    Code (CSharp):
    1. FormattingException: Error parsing format string: Could not evaluate the selector "test" at 12
    2. Start game {test}
    3. ------------^
    4. UnityEngine.Localization.SmartFormat.SmartFormatter.FormatError
    I don't know if I have to change something in the localization settings (I Haven't touched anything aside from setting 'parse error action' to 'throw error'), or if I'm sending the dictionary wrong. The output I'm looking to acheive is Start game testing based on this input. What am I doing wrong?
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Hi,
    Do you have a Dictionary Source added to the Smart String settings?

    upload_2021-3-16_22-19-3.png

    I did a quick test project and it works for me, its attached.
     

    Attached Files:

    Last edited: Mar 16, 2021
  3. Kazen

    Kazen

    Joined:
    Feb 17, 2015
    Posts:
    68
    Yes I do (see attached image). So I removed the localization settings and created a new one, but that did not work either. I edited the 'No translation found message' just to make sure that it's applied properly and sure enough, the message there is changed, so I know that the localization settings actually updates/changes.

    I guess I'll start with a test project too tonight and see if I can reproduce your behaviour instead. I don't think it should be a unity version issue, but what version did you do this on? I'm on 2020.1.0f1.
     

    Attached Files:

  4. Kazen

    Kazen

    Joined:
    Feb 17, 2015
    Posts:
    68
    Alright, so I got around to test this some more and I found the problem.

    I actually hooked up to the StringChanged event too
    Code (CSharp):
    1.  
    2. Dictionary<string, string> dict = new Dictionary<string, string>();
    3. dict["test"] = "testing";
    4. localizedString.GetLocalizedString(dict);          
    5. localizedString.StringChanged += LocalizedString_StringChanged;
    When I've hooked up to this event (I use it to apply the text to my text object), it does a call to LocalizedString.RefreshString(). The call stack was of help here, where it tells me that the 'AutomaticLoadingCompleted(...)' calls this function and sends an empty list of arguments. I'm not entirely sure why the arguments are not set yet though because it's sent into the localizedString when calling GetLocalizedString(...). If I do set the arguments directly, it works though.
    Code (CSharp):
    1.  
    2. Dictionary<string, string> dict = new Dictionary<string, string>();
    3. dict["test"] = "testing";
    4.  
    5. // set the arguments directly and it works
    6. localizedString.Arguments = new object[] { dict };
    7.  
    8. localizedString.GetLocalizedString(dict);          
    9. localizedString.StringChanged += LocalizedString_StringChanged;
    10.  
    Maybe I can work around not using the StringChanged event, I can look into it, or maybe I can live with setting the arguments directly too
     
  5. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Ah I think I understand. GetLocalizedString and StringChanged event are 2 different ways to get the Localized value, they don't work together.
    GetLocalizedString calls directly in to the StringDatabase and returns the loading operation, it won't trigger the StringChanged event. When you add a subscriber to StringChanged then that will trigger the loading operation using the provided arguments in the property. So you don't need to use GetLocalizedString at all here.

    It does make sense that you may want to use it this way though. I'll see if we can improve it.
     
    Kazen likes this.
  6. Kazen

    Kazen

    Joined:
    Feb 17, 2015
    Posts:
    68
    Well, if you say I can just skip getlocalizedstring and set the arguments directly then I think I'll just do that. I did not know they were not really compatible. Thanks for your help and explanation, now it's time to use the feature :)
     
    karl_jones likes this.