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

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

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

You can get a StringTable for a locale using a LocalizedStringTable or by calling LocalizationSettings.StringDatababase.GetTable. The table has a reference to the SharedTableData which contains all the keys and ids.

1 Like

Works great, much appreciated! If anyone in the future wants to test doing something like this I used the following

public void changeText(string tableName, int entryIndex)
{
     StringTable stringTable = LocalizationSettings.StringDatabase.GetTable(tableName);
     string key = stringTable.SharedData.Entries[entryIndex].Key;
     textObject.GetComponent<LocalizeStringEvent>().StringReference.SetReference(tableName,key);
}

Use stringTable.SharedData.Entries[entryIndex].Id, it has slightly better performance than using the Key.

1 Like

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

The above way works, just do . GetLocalizedString to get the localized string.

E.g

stringTable.SharedData.Entries[entryIndex].GetLocalizedString();

I think there is some misconception, I get compilation error. I’m using Localization 1.4.3 version

Oh. That’s my fault for writing code on my phone :frowning:

table.Values[0].GetLocalizedString();

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

using System;
using TMPro;
using UnityEditor.Localization;
using UnityEngine.Events;

namespace UnityEngine.Localization.Components
{
    /// <summary>
    /// Component that can be used to Localize a TMP_FontAsset asset.
    /// </summary>
    [AddComponentMenu("Localization/Asset/Localize TMPro Font Event")]
    public class LocalizeTMProFontEvent : LocalizedAssetEvent<TMP_FontAsset, LocalizedTMProFont, UnityEventFont>
    {
        private void Reset()
        {
            //Set up Unity Event automatically
            var target = GetComponent<TextMeshProUGUI>();
            var setFontMethod = target.GetType().GetProperty("font").GetSetMethod();
            var methodDelegate = System.Delegate.CreateDelegate(typeof(UnityAction<TMP_FontAsset>), target, setFontMethod) as UnityAction<TMP_FontAsset>;
            UnityEditor.Events.UnityEventTools.AddPersistentListener(this.OnUpdateAsset, methodDelegate);

            //Set up font localize asset table automatically
            var collections = LocalizationEditorSettings.GetAssetTableCollections();
            foreach (var tableCollection in collections)
            {
                if (tableCollection.name == "Fonts")
                {
                    this.AssetReference.TableReference = tableCollection.TableCollectionNameReference;
                    foreach (var entry in tableCollection.SharedData.Entries)
                    {
                        if (entry.Key == "font")
                            this.AssetReference.TableEntryReference = entry.Id;
                    }
                }
            }
        }
    }

    [Serializable]
    public class LocalizedTMProFont : LocalizedAsset<TMP_FontAsset> { }

    [Serializable]
    public class UnityEventFont : UnityEvent<TMP_FontAsset> { }


}

You could remove the Editor code or place it inside of a #if UNITY_EDITOR #endif block.

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?

You could use the localized property variants to set the don’t for the ones you care about.
https://docs.unity3d.com/Packages/com.unity.localization@1.4/manual/LocalizedPropertyVariants.html

Or you could change the default font

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?

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?

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)?

Yes, that’s fine.