Modded Language

Hi,

I wanted to ask what the best approach would be to allow users create their own translation when using the localization package. I know that it’s possible to automatically create entries with scripts in the editor and I was wondering if the same was possible with a build. Where I could read a csv file for a specific language on startup and create entries from them.

Is it even supported?

See the custom table loading and applying changes to a table in a build examples here
https://docs.unity3d.com/Packages/com.unity.localization@1.5/manual/Scripting.html

Thank you very much!

1 Like

I’m having trouble understanding the example to be honest. Should we use ITableProvider or ITablePostprocessor? What do AssignTablePostprocessor and AssignTableProvider do?

To explain the situation, the goal is to have user-made fan translations.
The idea is that the game has been translated in English and French already, but we want to have a system that checks if there’s a file in the root folder of the game for any given language and then automatically add that locale to every table with the appropriate translations (located in the file). So for example if there’s a file called portuguese.json and another called german.json , we’re able to extract those translations and dynamically add brand new locales to the game.
Could you explain how to 1) dynamically add a new locale and 2) dynamically add a translation to a given table (for the dynamically loaded locale).

Thank you very much.

To dynamically add a new locale you will need to write a script to run at the start. Wait for LocalizationSettings.InitializationOperation and then add the locales.

public class InitializationOperationExampleAsync : MonoBehaviour
{
    IEnumerator Start()
    {
        yield return LocalizationSettings.InitializationOperation;

        var foundLocaleCodes = new List<string>();

        // Find the new locales

        foreach (var code in foundLocaleCodes)
        {
            var locale = Locale.CreateLocale(code);
            LocalizationSettings.AvailableLocales.AddLocale(locale);
        }
    }
}

You want to use a TableProvider, its for adding new tables for languages. TablePostprocessor is for editing your existing tables, such as adding new entries in the same language or fixing existing entries.
For example. if your users were able to add additional content to the game then they may need to add some new strings for the existing languages, the table post processor would allow this. You could also require that modded content always uses a new table, its really up to how you architect things. If you only want to add new languages then it doesnt sound like you will be adding new strings, so a TableProvider is enough.

I recommend assigning the custom class in the editor to the LocalizationSettings,so its serialized into the build and wont need assigning again. Alternatively you can also assign it in your script that adds the locales, you just need to be sure that none of the tables will need to be loaded before then or they will be missed.

https://docs.unity3d.com/Packages/com.unity.localization@1.5/manual/Scripting.html#custom-table-loading

1 Like

Thank you so much for your answer, I understand a little bit better now. However, I don’t understand this part:

I can’t seem to find any variable where I can assign my CustomTableProvider in the Localization Settings. Perhaps I missed something?

I appreciate your help :slight_smile:

Its not available through the editor, we have not gotten around to adding that feature yet. It can be done through a script

public static class AssignCustomTableProviderExample
{
    [MenuItem("Localization Samples/Assign Custom table provider")]
    public static void AssignTableProvider()
    {
        // Create an instance of the table provider.
        var provider = new CustomTableProvider();

        // A provider can be assigned to each database or the same provider can be shared between both.
        var settings = LocalizationEditorSettings.ActiveLocalizationSettings;
        settings.GetStringDatabase().TableProvider = provider;
        settings.GetAssetDatabase().TableProvider = provider;

        // Set dirty so the changes are saved.
        EditorUtility.SetDirty(settings);
    }
}
1 Like