Search Unity

Need help creating localization table entries for unity 2019.4

Discussion in 'Localization Tools' started by Yukken, Oct 14, 2021.

  1. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    93
    Apparently, Unity already supports getting all the text in a scene and creating table entries for you in the new localization pacakge.
    My game is in unity 2019.4 LTS version and AFAIK that feature isn't available. I tried to write a script that will create a table entry for a textmeshpro component and also assign it in the LocalizedStringEvent components event.
    Code (CSharp):
    1.             var ls = new LocalizedString();
    2.             var key = "1";
    3.             var tmp = GetComponent<TextMeshProUGUI>();
    4.  
    5.             foreach (var table in s.StringTables)
    6.             {
    7.                 table.AddEntry(key, tmp.text);
    8.             }
    9.    
    10.             ls.TableReference = s.TableCollectionName;
    11.             ls.TableEntryReference = key;
    12.    
    13.             GetComponent<LocalizeStringEvent>()
    14.                 .StringReference.SetReference(s.TableCollectionName,key);
    15.  
    16.    
    17.             PropertyInfo stringProp = typeof(TextMeshPro).GetProperty(nameof(tmp.text));
    18.    
    19.             Debug.Log(stringProp + " " + stringProp.GetSetMethod());
    20.             UnityAction<string> textsetDelegate = (
    21.                 UnityAction<string>) Delegate.CreateDelegate(typeof(UnityAction<string>),
    22.                 tmp, stringProp.GetSetMethod());
    23.             UnityEditor.Events.UnityEventTools.AddPersistentListener<String>(
    24.                     GetComponent<LocalizeStringEvent>().OnUpdateString,
    25.                     textsetDelegate
    26.                 );
    This works works but there might be issues. Which is why I'm asking for help.
    If there are none, I'll update this to work with my code to fetch text mesh pro components in scene and turn this into something usable for everyone.

    In the meantime, I hope the feature is backported to LTS versions.

    Edit:

    Well, it's done. It's super barebones but sufficient for my use cases. I hate writing editor GUI code so I won't be extending it further.


    It's a wizard that will fetch textmeshpro and textmeshproUGUI components in a scene. You can chose to ignore certain components if you want. Clicking on an entry will take you to the game object.

    It will add the built-in LocalizedStringEvent component, create a table entry and assign it and also set up the Unity event for the LocalizedStringEvent component's OnStringUpdate().
    Screenshot (5).png .
    All the table entries will have the current text of the textmeshPro component.

    If the gameobject already has a LocalizedStringEvent attached, it will replace the string reference and also add to the UnityEvent (and possibly create duplicate callbacks). But that should be harmless.

    If nothing else, it should be useful for navigating the scene to find TextMeshpro Localized strings and hopefully cutdown some menial work.

    Reqs:
    Localization package: 0.11.1
    Textmeshpro (version shouldn't be an issue)
     

    Attached Files:

    Last edited: Oct 15, 2021
    karl_jones likes this.
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,297
    Im not sure what you mean by this? Are you referring to this? https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/LocalizedPropertyVariants.html
    We don't get all the text, we still require each item to be set up but we do more automatically in the background. We cant backport this to 2019.4, there are too many features missing in 2019.4 needed for it to work.

    Writing a script to set up each text entry should be fine. I can only see a small part of your script so cant say for sure if its correct. Your script looks like it is assigning the same value to all the tables, also using the same key value "1" for every entry will prevent it from working, you will only have a single entry.
    Can you share the full code?

    This is how we setup TMP
    Code (csharp):
    1. public static MonoBehaviour SetupForLocalization(TextMeshProUGUI target)
    2. {
    3.     var comp = Undo.AddComponent(target.gameObject, typeof(LocalizeStringEvent)) as LocalizeStringEvent;
    4.     var setStringMethod = target.GetType().GetProperty("text").GetSetMethod();
    5.     var methodDelegate = System.Delegate.CreateDelegate(typeof(UnityAction<string>), target, setStringMethod) as UnityAction<string>;
    6.     Events.UnityEventTools.AddPersistentListener(comp.OnUpdateString, methodDelegate);
    7.     comp.OnUpdateString.SetPersistentListenerState(0, UnityEventCallState.EditorAndRuntime);
    8.     const int kMatchThreshold = 5;
    9.     var foundKey = LocalizationEditorSettings.FindSimilarKey(target.text);
    10.     If (foundKey.collection != null && foundKey.matchDistance < kMatchThreshold)
    11.     {
    12.         comp.StringReference.TableEntryReference = foundKey.entry.Id;
    13.         comp.StringReference.TableReference = foundKey.collection.TableCollectionNameReference;
    14.     }
    15.     return comp;
    16. }
     
  3. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    93
    I merely heard that there was some automation process. My game is already done so going through and adding localization manually per component would be impractical. If it helps somebody else, that's fine as well.

    The id= 1 is just place holder. I know it has to be unique. In my use case, simply incrementing the count should be enough.

    The count would be stored in some file/SO.

    I'm not sure what "FindSimilarKey" does. Does it try to match the text to already processed text to avoid duplicate strings? That'd be cool though not necessary for my case.
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,297
    Do
    var sharedEntry = collection.SharedTableData.AddKey();
    . This will do the auto naming for you so you don't need to keep track of the id.
    I would do something like
    var sharedEntry = collection.SharedTableData.AddKey(tmp.text);
    . so that the name is a unique version of the actual text. Then you pass sharedEntry.KeyId into the AddEntry method.

    I would not use this. We will be making it obsolete in 1.1 and replacing it with an integration into Unity Search that will let you find matching keys etc.
     
    jonathans42 and Yukken like this.
  5. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    93
    Thanks. I'm done with my code, just want some answers for some QOL improvements.
    I'm using:
    Code (CSharp):
    1. stringEvent.StringReference.TableEntryReference.ReferenceType == TableEntryReference.Type.Empty
    To check if a stringreference is valid. Is there a better way?
     
    Last edited: Oct 15, 2021
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,297
  7. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    93
    Thanks. Last question I swear:
    I'm having a bit of trouble setting the translated text for the entries. The game has already valid text in the textmeshpro components which would be put in all of the langaues(placeholder for non-english ones)
    The collection.SharedTableData.AddKey() works but trying to set the translated entries gives me a null ref:
    Code (CSharp):
    1.         var sharedEntry = stringTable.SharedData.AddKey();
    2.         foreach (var t in stringTable.StringTables)
    3.         {
    4.             t.AddEntry(sharedEntry.Key , tmp.text);
    5.         }
    This happens for both sharedKey.Id and Key. Also:
    Code (CSharp):
    1. var sharedEntry = stringTable.SharedData.AddKey(tmp.text);
    Also gives a null ref for me.
     
  8. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    93
    Actually nvm. It was the textmeshpro component that was null in that case.
     
    karl_jones likes this.
  9. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    93
    Uploaded the package. It's barebones but should cut down menial work for people like me who are stuck on 2019.4.
    I've edited the first post with the package and other descriptions.

    Thank you to @karl_jones for all the help.
     
    karl_jones likes this.
  10. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,297
    Ah very nice. We do have some plans to look into doing something similar in the future.