Search Unity

StringChanged event not getting triggered when language changes?

Discussion in 'Localization Tools' started by emg, Mar 27, 2022.

  1. emg

    emg

    Joined:
    Oct 18, 2015
    Posts:
    5
    I'm very new to this package, and I'm having a really hard time understanding how to use the SmartStrings. For my Localize String Event, I have attached a custom script to the Local Variables as an Object Reference.

    Table entry example:
    My name is {myScriptName.myName}​
    Inside my script:
    public string myName= "Sarah";​
    Outputs:
    My name is Sarah​

    However, I'm trying to get to where I can recompute the value of myName when the language changes (or even just in the first place and not have it as a set variable at the top of my file). I have OnEnable/OnDisable for LocalizedString.StringChanged, but the function I create never gets called. The function literally only has a Debug.Log statement in it.

    Questions:
    1. What event can I listen for to be able to recompute myName whenever the language changes?
    2. How can I recompute myName at all? Lambda functions don't seem to be allowed, but I need to access some of my other files to get the final string I want myName to be.
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    Can you show your code?
     
  3. emg

    emg

    Joined:
    Oct 18, 2015
    Posts:
    5
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using UnityEngine.Localization;
    6. using UnityEngine.Localization.Components;
    7.  
    8. public class LocalPuzzleName : MonoBehaviour
    9. {
    10.     public LocalizedString puzzleNameTemplate;
    11.     public string localPuzzleName = "dskfjlkjs";
    12.  
    13.     void OnEnable()
    14.     {
    15.         puzzleNameTemplate.Arguments = new[] { this };
    16.         puzzleNameTemplate.StringChanged += UpdateString;
    17.     }
    18.  
    19.     void OnDisable()
    20.     {
    21.         puzzleNameTemplate.StringChanged -= UpdateString;
    22.     }
    23.  
    24.     void UpdateString(string s)
    25.     {
    26.         Debug.Log("s: " + s);
    27.         localPuzzleName = s;
    28.     }
    29.  
    30.     void OnGUI()
    31.     {
    32.         puzzleNameTemplate.RefreshString();
    33.         EditorGUILayout.LabelField(localPuzzleName);
    34.     }
    35. }
    36.  
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    The script looks fine. What do you mean by recompute the name? Does string changed work? It sounds like maybe you want a callback when the language changes so that you can generate the name before the string is created? One way would be to use a property instead of a variable and do the calculation inside the get method.
     
  5. emg

    emg

    Joined:
    Oct 18, 2015
    Posts:
    5
    The script never prints the Debug.Log statement I have in the UpdateString method.

    As for recomputing the name, I need to get the current puzzle name in my game (saved as an int representing an index), which then I can use to call a different Localization table to get the localized version of the current puzzle name so that I can insert it into the localized string that uses that name.

    I'm not sure if there is an easier way to do that, like if a Localization table can directly access a different Localization table, with the index to that other table set as a variable inside my script?
     
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    Is this during play mode?
    Have you added the script to a gameobject in the scene?
    Have you assigned a value to the localized string in the inspector?
    Can you put a debug log in on enable? Does it get called?
     
  7. emg

    emg

    Joined:
    Oct 18, 2015
    Posts:
    5
    Well, so I just noticed that I had disabled my script component, which was why nothing was getting called. However, after enabling it, I'm now getting this error:
    FormattingException: Error parsing format string: Could not evaluate the selector "LocalPuzzleName" at 1
    {LocalPuzzleName.localPuzzleName}​


    I've added the script as a component of the TextMeshPro GameObject that also has the Localize String Event component. In the Localize String Event component, I have a Local Variables entry "localPuzzleName" equal to my script component that I added (as an Object Reference).
     
  8. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    Variable names are case sensitive so try {localPuzzleName.localPuzzleName} instead of {LocalPuzzleName.localPuzzleName}

    Also it sounds like you may have 2 LocalizedStrings when you want 1.
    Try replacing
    public LocalizedString puzzleNameTemplate; 
    with
    public LocalizedStringEvent puzzleNameTemplate;
    . Drag the LocalizedStringEvent component into the value.
    Now access
     puzzleNameTemplate.StringReference
     
  9. emg

    emg

    Joined:
    Oct 18, 2015
    Posts:
    5
    Thank you! I got it to work. I'll add my working code below in case anyone else stumbles onto this thread.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Localization;
    5. using UnityEngine.Localization.Components;
    6. using UnityEngine.Localization.Settings;
    7.  
    8. public class GetPuzzleName : MonoBehaviour
    9. {
    10.     public LocalizeStringEvent puzzleNameEvent;
    11.     private LocalizedString localPuzzleName;
    12.  
    13.     public string puzzleKey {
    14.         get {
    15.             return "mgmgmg_" + LocalizationSettings.SelectedLocale;
    16.         }
    17.     }
    18.  
    19.     void OnEnable()
    20.     {
    21.         localPuzzleName = puzzleNameEvent.StringReference;
    22.         puzzleNameEvent.OnUpdateString.AddListener(OnStringChanged);
    23.     }
    24.  
    25.     void OnStringChanged(string s)
    26.     {
    27.         Debug.Log($"String changed to `{s}`");
    28.         Debug.Log("Language selected: " + LocalizationSettings.SelectedLocale);
    29.     }
    30. }
    31.  
     
    karl_jones likes this.