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

Change text with specific localization key in table

Discussion in 'Localization Tools' started by fomafomitch, Dec 29, 2020.

  1. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    86
    Hello,

    I have a menu to select a character between 4 types.
    When a character is selected, a text pannel is updated to add informations.
    I want to update this pannel with localization. I know how to do it withtout the new localization package, but what I want to do is "write this specific localization key here".
    The localization key may varie for each character so I will make a "variable variable" to seperate :

    I will have this on my localization database :
    Code (CSharp):
    1. Character_TypeKnight_Name
    2. Character_TypeKnight_Description
    3. Character_TypeMagician_Name
    4. Character_TypeMagician_Description
    Here the script I tried using autocompletion :

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4. using UnityEngine.Localization;
    5.  
    6. public class SelectCharacterEvent : MonoBehaviour, ISelectHandler
    7. {
    8.     public string CharacNameIDUI;
    9.     public Text CharacSelectionName;
    10.  
    11.     public void OnSelect(BaseEventData eventData)
    12.     {
    13.             Debug.Log("I'm selected" + CharacNameIDUI);
    14.  
    15.         CharacSelectionName.text = UnityEngine.Localization.Tables.DetailedLocalizationTable<TTable, Tentry>;
    16.     }
    17. }
    I know how to change text with localization, but in this case it's more complicated because the text depend on event.

    https://docs.unity3d.com/Packages/c....html#9-string-localization-use-string-tables
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,845
    I'm not entirely sure I understand but it sounds like you want to change the Key for a LocalizedString at runtime.
    This is fine. The Samples contain various ways to work with LocalizedStrings, this is a modified version that may do what you need:

    Code (csharp):
    1.  
    2. public class LocalizedStringWithChangeHandlerExample : MonoBehaviour
    3. {
    4.     public LocalizedString stringRef = new LocalizedString() { TableReference = "My String Table", TableEntryReference = "Character_TypeKnight_Name" };
    5.  
    6.     public string CharacNameIDUI;
    7.     public Text CharacSelectionName;
    8.  
    9.     void OnEnable()
    10.     {
    11.         stringRef.StringChanged += UpdateString;
    12.     }
    13.  
    14.     void OnDisable()
    15.     {
    16.         stringRef.StringChanged -= UpdateString;
    17.     }
    18.  
    19.     void UpdateString(string translatedValue)
    20.     {
    21.         CharacSelectionName.text = translatedValue;
    22.     }
    23.  
    24.     public void OnSelect(BaseEventData eventData)
    25.     {
    26.         Debug.Log("I'm selected" + CharacNameIDUI);
    27.  
    28.         // Change the Key here. This will trigger an update which will call UpdateString with the new translated value
    29.         stringRef.TableEntryReference = CharacNameIDUI;
    30.     }
    31. }
     
  3. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    86
    Thank you for your time.

    There is 2 character playable : a Magician, a Knight. The player must do a choice.
    On my UI there is 2 images that represent a Magician, and a Knight, they can be selected.
    I have ONE character_nametype_ui that display the choice before confirmation, and is updated when I select Magician or Knight (i.e : "Will you play a Magicial ?").

    All I want, is that when someone click on the Magician's Image, the character_nametype_ui update with the magician name, but I want to localize that as well. I can change the character_nametype_ui content, but how do I do it with localization ?


    In my "Table Collection Name" : UI_Text I have these entries :

    KEY‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎en_EN ‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎fr_FR
    Character_Name_Magician ‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎Magician ‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎Sorcier
    Character_Name_Knight ‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎Knight ‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎Chevalier

    There is a lot of way to do it. Simpler for me will be :
    • Search on the "Table Collection Name" in "UI_Text"
    • Search for the entry "Character_Name_VARIABLE"
    • Go to "localisation settings"
    • Put this text into my variable.
    • Update character_nametype_ui with my variable.
     
  4. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    86
    I dont know if i'm clear, I just want to know how to access to a "Key" or "Key ID" in a specific table from my script that's all ?

    Something like : variable = "Entry Value" for "Key Id = XXX" && "Table Collection = YYYY" for the current localisation language selected.
     
  5. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,845
    You can get a StringTable and then query the Keys and Key Ids.
    See the LocalizedStringTableExample in the Samples.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.Localization;
    4. using UnityEngine.Localization.Settings;
    5. using UnityEngine.Localization.Tables;
    6.  
    7. namespace UnityEditor.Localization.Samples
    8. {
    9.     /// <summary>
    10.     /// This example shows how a <see cref="StringTable"> can be used directly in order to get translated
    11.     /// strings for multiple entries using a <see cref="LocalizedStringTable>"/>.
    12.     /// </summary>
    13.     public class LocalizedStringTableExample : MonoBehaviour
    14.     {
    15.         public LocalizedStringTable stringTable = new LocalizedStringTable { TableReference = "My Strings" };
    16.  
    17.         // We will cache our translated strings
    18.         string m_TranslatedStringHello;
    19.         string m_TranslatedStringGoodbye;
    20.         string m_TranslatedStringThisIsATest;
    21.  
    22.         void OnEnable()
    23.         {
    24.             stringTable.TableChanged += LoadStrings;
    25.         }
    26.  
    27.         void OnDisable()
    28.         {
    29.             stringTable.TableChanged -= LoadStrings;
    30.         }
    31.  
    32.         void LoadStrings(StringTable stringTable)
    33.         {
    34.             m_TranslatedStringHello = GetLocalizedString(stringTable, "Hello");
    35.             m_TranslatedStringGoodbye = GetLocalizedString(stringTable, "Goodbye");
    36.             m_TranslatedStringThisIsATest = GetLocalizedString(stringTable, "This is a test");
    37.         }
    38.  
    39.         static string GetLocalizedString(StringTable table, string entryName)
    40.         {
    41.             // Get the table entry. The entry contains the localized string and Metadata
    42.             var entry = table.GetEntry(entryName);
    43.             return entry.GetLocalizedString(); // We can pass in optional arguments for Smart Format or String.Format here.
    44.         }
    45.  
    46.         void OnGUI()
    47.         {
    48.             // We can check if the localization system is ready using the InitializationOperation.
    49.             // Initialization involves loading locales and optionally preloading localized data for the current locale.
    50.             if (!LocalizationSettings.InitializationOperation.IsDone)
    51.             {
    52.                 GUILayout.Label("Initializing Localization");
    53.                 return;
    54.             }
    55.  
    56.             GUILayout.Label(m_TranslatedStringThisIsATest);
    57.             GUILayout.Label(m_TranslatedStringHello);
    58.             GUILayout.Label(m_TranslatedStringGoodbye);
    59.         }
    60.     }
    61. }
    62.  
    63.  
    Once you have the table you can access its SharedData property which contains all the keys and ids.
    You can also use LocalizationSettings.StringDatabase.GetTableAsync to get the table instead of LocalizationSettings.StringDatabase.GetTableAsync
     
    elfasito and MoR81204 like this.
  6. ejjht

    ejjht

    Joined:
    Jan 22, 2020
    Posts:
    10
    If you have a table with a list of words, how would you make a textMesh text change to a random item of the table every 30 seconds ?
     
  7. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,845
    Something like this

    Code (csharp):
    1. public class Example : MonoBehaviour
    2. {
    3.     public TextMeshProUGUI tmp;
    4.     public LocalizedStringTable myTable = new LocalizedStringTable("Random Strings Table");
    5.     public float delay = 30;
    6.  
    7.     StringTable table;
    8.     Coroutine coroutine;
    9.  
    10.     private void Start()
    11.     {
    12.         myTable.TableChanged += MyTable_TableChanged;
    13.     }
    14.  
    15.     void MyTable_TableChanged(StringTable value)
    16.     {
    17.         table = value;
    18.  
    19.         if (coroutine != null)
    20.             StopCoroutine(coroutine);
    21.  
    22.         coroutine = StartCoroutine(UpdateStrings());
    23.     }
    24.  
    25.     IEnumerator UpdateStrings()
    26.     {
    27.         var wait = new WaitForSeconds(delay);
    28.  
    29.         while (Application.isPlaying)
    30.         {
    31.             var randomEntry = table.SharedData.Entries[Random.Range(0, table.Count)];
    32.             tmp.text = table.GetEntry(randomEntry.Id).GetLocalizedString();
    33.  
    34.             yield return wait;
    35.         }
    36.     }
    37. }
     
    BackToPanda and ejjht like this.
  8. ejjht

    ejjht

    Joined:
    Jan 22, 2020
    Posts:
    10
    Thanks, that's exactly what I was looking for :)
     
    karl_jones likes this.
  9. ejjht

    ejjht

    Joined:
    Jan 22, 2020
    Posts:
    10
    Sorry but how would you do almost the same but now with an audio clip? Get a random audio clip asset and play it
     
  10. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,845
    Similar but by using an AssetTable.
    Instead of calling GetLocalizedString on the entry you would call LocalizationSettings.AssetDatabase
    LoadAssetAsync<AudioClip>(table name, EntryId)
     
  11. ejjht

    ejjht

    Joined:
    Jan 22, 2020
    Posts:
    10
    Sorry But I didn't get it, right now my code looks like this, it's not working

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.Localization;
    4. using UnityEngine.Localization.Tables;
    5. using UnityEngine.Localization.Settings;
    6.  
    7.  
    8. public class GetRandomAudioClip : MonoBehaviour
    9. {
    10.  
    11.     public LocalizedAssetTable myTable = new LocalizedAssetTable("Tabla");
    12.  
    13.     public AssetTable table;
    14.  
    15.     public AudioClip clip;
    16.  
    17.     private void Start()
    18.     {
    19.         myTable.TableChanged += MyTable_TableChanged;
    20.     }
    21.  
    22.     private void MyTable_TableChanged(AssetTable value)
    23.     {
    24.         table = value;
    25.     }
    26.  
    27.     private void Update()
    28.     {
    29.         if (Input.GetKeyDown(KeyCode.F))
    30.         {
    31.             getAudioClip();
    32.         }
    33.     }
    34.  
    35.     public void getAudioClip()
    36.     {
    37.  
    38.         StartCoroutine(getRandomAudioClipFromAssetTable());
    39.     }
    40.  
    41.     IEnumerator getRandomAudioClipFromAssetTable()
    42.     {
    43.         int entryIndex = UnityEngine.Random.Range(0, table.Count);
    44.  
    45.         var randomEntry = table.SharedData.Entries[entryIndex];
    46.  
    47.         var assetLoadOperation = LocalizationSettings.AssetDatabase.GetLocalizedAssetAsync<AudioClip>(table.name, randomEntry.Id);
    48.  
    49.         yield return assetLoadOperation;
    50.  
    51.         clip = assetLoadOperation.Result;
    52.     }
    53.  
    54.  
    55.  
    56. }
     
  12. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,845
    Try ch
    Do you get any errors?
    Try changing table.name to table.TableCollectionName.
     
  13. ejjht

    ejjht

    Joined:
    Jan 22, 2020
    Posts:
    10

    You are right, that was my error, thank you :D
     
    karl_jones likes this.