Search Unity

Bug Selecting some locales only uses fallback

Discussion in 'Localization Tools' started by Asianware, May 11, 2023.

  1. Asianware

    Asianware

    Joined:
    Dec 28, 2013
    Posts:
    6
    I'm experiencing an issue where selecting specific locales doesn't update the strings to the correct language. Instead, they consistently only use the fallback locale when selected.

    Everything works fine with the 3 languages I've added when I first started using the localization package. Because of demand, I've added Italian (it) and later on Hungarian (hu). However, switching to these languages doesn't work as expected. All locales have English (en) as fallback.

    Here's how I set the selected language, called from a button in the menu:

    LocalizationSettings.SelectedLocale = locale;


    I also have an ITablePostprocessor script that runs to update the selected string table.

    In my logs, I see that the selected locale is available in
    LocalizationSettings.AvailableLocales
    and after the SelectedLocale is set, the ITablePostprocessor script runs the selected locale and the fallback locale.

    The result I see is that all of the text is in the fallback locale (English) and not in the selected locale. If I change scenes, it uses the selected locale correctly. I can't find why it behaves like this for the locales that I've added later, but works fine for the 3 other locales.

    Let me know if I can provide any other information
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Hi,
    That does sound strange. Have you tried doing a clean and rebuild of the addressable assets?
    It working after changing scenes makes me think that maybes it an issue with the text not being updated when the locale changes, are you using the LocalizeddStringBehaviour component or your own? Can you share your code?
     
  3. Asianware

    Asianware

    Joined:
    Dec 28, 2013
    Posts:
    6


    Thanks for the reply Karl. I'm using LocalizeStringEvent to update the strings.

    I did found that for the 3 languages that work as expected, the LocalizationTable has entries. For the other languages there's no entries, as I set those on runtime.

    upload_2023-5-11_13-45-7.png

    Here's how I update the table on runtime, hopefully this is enough information for you to identify the issue.

    Code (CSharp):
    1. public void PostprocessTable(LocalizationTable table)
    2. {
    3.     Debug.Log($"Postprocess {table} ({table.LocaleIdentifier})");
    4.     AsyncPostprocessTable().Forget();
    5.  
    6.     async UniTaskVoid AsyncPostprocessTable()
    7.     {
    8.         StringTable stringTable = table as StringTable;
    9.         if (stringTable == null)
    10.         {
    11.             Debug.LogError("Not a StringTable");
    12.             return;
    13.         }
    14.  
    15.         // Get updated table from the backend
    16.         var updatedTable = await GetUpdatedTable(table.LocaleIdentifier);
    17.  
    18.         if (updatedTable == null)
    19.         {
    20.             Debug.LogError($"Error getting updated table");
    21.             return;
    22.         }
    23.      
    24.         foreach (var sharedEntry in table.SharedData.Entries)
    25.         {
    26.             string key = sharedEntry.Key;
    27.  
    28.             // Skip empty keys
    29.             if (string.IsNullOrWhiteSpace(key))
    30.             {
    31.                 continue;
    32.             }
    33.          
    34.             // Get the updated KV pair for the current sharedEntry.Key
    35.             var updatedKeyValue = updatedTable.FirstOrDefault(x => x.Key != null && x.Key.StripControlChars().Equals(key));
    36.             string updatedValue = updatedKeyValue.Value;
    37.          
    38.             // If there's no value for the key, set it to null to make use of the fallback
    39.             // Hardcoded for English, use the value from the English table
    40.             if (string.IsNullOrWhiteSpace(updatedValue))
    41.             {
    42.                 updatedValue = (table.LocaleIdentifier.CultureInfo.DisplayName == "English")
    43.                     ? stringTable[key].Value
    44.                     : null;
    45.             }
    46.  
    47.             // Update the stringTable for the locale
    48.             if (stringTable.ContainsKey(sharedEntry.Id))
    49.             {
    50.                 // Update the existing value
    51.                 var entry = stringTable.GetEntry(key);
    52.                 if (entry == null)
    53.                 {
    54.                     continue;
    55.                 }
    56.  
    57.                 entry.Value = updatedValue;
    58.             }
    59.             else
    60.             {
    61.                 // Add new
    62.                 stringTable.AddEntry(sharedEntry.Key, updatedValue);
    63.             }
    64.         }
    65.     }
    66. }
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    I think I see the problem. You are doing async code inside of PostprocessTable, this won't work because PostprocessTable expects the table to be populated when it returns, it then checks for the entries however you add the entries later on which is too late.
    Instead of waiting on GetUpdatedTable could you call WaitForCompletion on the operation so it is completed immediately?