Search Unity

Getting String References/key list from a String Table Collection in build

Discussion in 'Localization Tools' started by KantosCode, Feb 8, 2022.

  1. KantosCode

    KantosCode

    Joined:
    Oct 23, 2019
    Posts:
    8
    My goal is to be able to swap my string reference at runtime (and in builds) from within the entries of a specific String Table Collection. For example be able to pick one of these at random and switch my localize String Event to use it.



    I see that there is the method that can set the reference based on the table name and the entry key
    Code (CSharp):
    1. StringReference.SetReference(tableReference,keyReference);
    This works great, but to get the specific tableReferences and keyReferences from the String Table Collection I would of course need the string table collection which requires using the Editor library. Is there some clever way around this or do I have to just manually make a list of strings for the keys I want to use and use that if I want it to work in builds?

    It's not a big deal, but would be nice to be able to just pull all the keys from a particular table collection to use at runtime
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    KantosCode likes this.
  3. KantosCode

    KantosCode

    Joined:
    Oct 23, 2019
    Posts:
    8
    Works great, much appreciated! If anyone in the future wants to test doing something like this I used the following
    Code (CSharp):
    1. public void changeText(string tableName, int entryIndex)
    2. {
    3.      StringTable stringTable = LocalizationSettings.StringDatabase.GetTable(tableName);
    4.      string key = stringTable.SharedData.Entries[entryIndex].Key;
    5.      textObject.GetComponent<LocalizeStringEvent>().StringReference.SetReference(tableName,key);
    6. }
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    Use
    stringTable.SharedData.Entries[entryIndex].Id
    , it has slightly better performance than using the Key.
     
    KantosCode likes this.
  5. magister_yoda_

    magister_yoda_

    Joined:
    Mar 27, 2016
    Posts:
    32
    Is there a way to get string value from LocalizationTable somehow like this?

    var table = tableCollection.GetTable(LocalizationSettings.SelectedLocale.Identifier);
    table.GetString(key);


    I wanna have reference on a StringTableCollection, then pass through all the keys and get a localized string by a key
     
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    The above way works, just do . GetLocalizedString to get the localized string.

    E.g

    Code (csharp):
    1. stringTable.SharedData.Entries[entryIndex].GetLocalizedString();
     
  7. magister_yoda_

    magister_yoda_

    Joined:
    Mar 27, 2016
    Posts:
    32
    I think there is some misconception, I get compilation error. I'm using Localization 1.4.3 version
     
  8. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    Oh. That's my fault for writing code on my phone :(
    Code (csharp):
    1. table.Values[0].GetLocalizedString();
     
  9. magister_yoda_

    magister_yoda_

    Joined:
    Mar 27, 2016
    Posts:
    32
    And what is the best way to localize font? I've found a script, that should localize fonts, but I cannot build project for Android because of using Editor name space in this script



    Here is the script
    Code (CSharp):
    1. using System;
    2. using TMPro;
    3. using UnityEditor.Localization;
    4. using UnityEngine.Events;
    5.  
    6. namespace UnityEngine.Localization.Components
    7. {
    8.     /// <summary>
    9.     /// Component that can be used to Localize a TMP_FontAsset asset.
    10.     /// </summary>
    11.     [AddComponentMenu("Localization/Asset/Localize TMPro Font Event")]
    12.     public class LocalizeTMProFontEvent : LocalizedAssetEvent<TMP_FontAsset, LocalizedTMProFont, UnityEventFont>
    13.     {
    14.         private void Reset()
    15.         {
    16.             //Set up Unity Event automatically
    17.             var target = GetComponent<TextMeshProUGUI>();
    18.             var setFontMethod = target.GetType().GetProperty("font").GetSetMethod();
    19.             var methodDelegate = System.Delegate.CreateDelegate(typeof(UnityAction<TMP_FontAsset>), target, setFontMethod) as UnityAction<TMP_FontAsset>;
    20.             UnityEditor.Events.UnityEventTools.AddPersistentListener(this.OnUpdateAsset, methodDelegate);
    21.  
    22.             //Set up font localize asset table automatically
    23.             var collections = LocalizationEditorSettings.GetAssetTableCollections();
    24.             foreach (var tableCollection in collections)
    25.             {
    26.                 if (tableCollection.name == "Fonts")
    27.                 {
    28.                     this.AssetReference.TableReference = tableCollection.TableCollectionNameReference;
    29.                     foreach (var entry in tableCollection.SharedData.Entries)
    30.                     {
    31.                         if (entry.Key == "font")
    32.                             this.AssetReference.TableEntryReference = entry.Id;
    33.                     }
    34.                 }
    35.             }
    36.         }
    37.     }
    38.  
    39.     [Serializable]
    40.     public class LocalizedTMProFont : LocalizedAsset<TMP_FontAsset> { }
    41.  
    42.     [Serializable]
    43.     public class UnityEventFont : UnityEvent<TMP_FontAsset> { }
    44.  
    45.  
    46. }
     
  10. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    You could remove the Editor code or place it inside of a
    #if UNITY_EDITOR
    #endif
    block.
     
  11. magister_yoda_

    magister_yoda_

    Joined:
    Mar 27, 2016
    Posts:
    32
    Yeap, sorry for a dumb question. But the next question is not so stupid ))
    Look, I wanna localize font, but only for three languages: Korean, Japanese, Chinese. I mean for this three languages I wanna use three different font assets and for the rest languages some default font. How can do this?
     
  12. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
  13. magister_yoda_

    magister_yoda_

    Joined:
    Mar 27, 2016
    Posts:
    32
    Look, I have a TMPro which I have to update from code. I have references on LocalizedString using which I update my TMPro.

    locationName.text = locationData.locName.GetLocalizedString();

    How can I update string when locale is changed? I cannot simply use LocalizeStringEvent, because in editor I don't know yet which LocalizeString to use.
    Now I'm using callback

    LocalizationSettings.SelectedLocaleChanged
    to update texts when locale changed.
    I'm wondering if there a bit more comfortable way to do this?
     
  14. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    You can change the entry that a LocalizedString references, call SetReference to change the table and entry or set the TableEntryReference property to just change the entry in the same table.
    If you use the StringChanged event then it will automatically send the event when the locale changes or you change the reference.

    What does your code look like?
     
  15. magister_yoda_

    magister_yoda_

    Joined:
    Mar 27, 2016
    Posts:
    32
    First I did this, then it appeared that I cannot format string in if it is needed.


    Then I started to use this approach: I subscribe on the SelectedLocaledChanged and then update my strings. Is this OK or there is some other way to update localized texts (beside adding component LocalizeStringEvent and assign the key from editor)?

     
  16. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    Yes, that's fine.