Import terms in Runtime from code

More
6 years 2 months ago #2716 by aim4code
Hi!

I'm trying to create/update language sources from code, since i need to maintain updated the localization but i'm not allowed to use either Google or CSV (I actually need to use JSON files).

So my question is, how exactly can i include elements on the language source and ensure those changes are persistent? I've been checking a the code of how CSV or google sheet import is being done, but seems quite complex (maybe due to retrocompativility) and i dont see the whole picture of the internal data structure of the LanguageSource, TermData, and the dependences that it might have between Editor or Runtime code. I've seen there is also a player prefs setting to store a sort of versioning system, but im not sure neither how it is working.

Could you post some guidelines to be sure i'm not skipping any vital step? Would be already super handy with an example implementation of a method to include a single term like:
public string Import_Term( string Category, KeyValuePair<string,string> entry, eSpreadsheetUpdateMode UpdateMode = eSpreadsheetUpdateMode.Replace )
{
	...
}

Thanks a lot man!

Please Log in or Create an account to join the conversation.

More
6 years 2 months ago - 6 years 2 months ago #2717 by Frank
Hi,
To add terms from code, just call the source.AddTerm(..) function which creates/returns the internal term data, then just place the translation in the corresponding array index.
You can also call source.AddLanguage(..) to create new languages

If you run from an Editor script, then just make the source dirty so that Unity saves it. If you are running the code from your game at runtime, then there is no need for saving given that you will be loading from your json.

Here is an example of how this can be implemented:
        public void Import_Term(string termName, string language, string translation)
        {
            var i2languagesPrefab = LocalizationManager.Sources[0];
            var termData = i2languagesPrefab.AddTerm(termName, eTermType.Text);

            // Find Language Index (or add the language if its a new one)
            int langIndex = i2languagesPrefab.GetLanguageIndex(language, false, false);
            if (langIndex<0)
            {
                i2languagesPrefab.AddLanguage(language, GoogleLanguages.GetLanguageCode(language));
                langIndex = i2languagesPrefab.GetLanguageIndex(language, false, false);
            }

            termData.Languages[langIndex] = translation;
        }

This is how you use the Import_Term function. Just get the values from your json:
            var i2languagesPrefab = LocalizationManager.Sources[0];

            i2languagesPrefab.ClearAllData();   // Do this if you are meant to replace ALL the data

            Import_Term("Tutorial/Term1", "English", "This is my key");
            Import_Term("Tutorial/Term1", "Spanish", "Esta es la llave");
            Import_Term("Term2", "English", "Hello");

            // Update internal cache
            i2languagesPrefab.UpdateDictionary();

            // This is only needed if you are running from an Editor Script and want to save the data
            UnityEditor.EditorUtility.SetDirty(i2languagesPrefab);

Hope that helps,
Frank

Are you :-) Give I2L 5 stars!
Are you :-( Please lets us know how to improve it!
To get the betas as soon as they are ready, check this out
Last edit: 6 years 2 months ago by Frank.
The following user(s) said Thank You: aim4code

Please Log in or Create an account to join the conversation.

More
6 years 2 months ago #2718 by aim4code
Hey Frank!

Wow thanks a lot for the quick response! I was blind but know i see! :D

If you are running the code from your game at runtime, then there is no need for saving given that you will be loading from your json.


I don't really get that. Do you mean parsing and importing the JSON content for each language every time i run the app? That can be pretty funky if is done on every run, no?. There is no mechanism for caching that store it in the persistent folder? There has to be one i guess, at least for the case when the content is being refreshed from google drive o.O.

My use case is actually updating an application localization after being published, so it has to be at runtime for me but i wonder in that case if there is other option than loading from the different json languages the new content into the global source.

You are helping a lot already :)

Cheers,
Dani

Please Log in or Create an account to join the conversation.

More
6 years 2 months ago - 6 years 2 months ago #2719 by Frank

Do you mean parsing and importing the JSON content for each language every time i run the app?


I wasn't sure what your use case was.
- You could have been doing an script that runs from the editor (a menu option in the editor or in one of the inspectors), So that the content of the JSON file get imported into the I2Languages.prefab without actually using the json IN-GAME (e.g. in your player's devices)
- Or you could have been running the script IN-GAME (not editor) to download new data or allow users to mod the game.

Now I see that you was referring to the second option.

if there is other option than loading from the different json languages the new content into the global source


There are several ways you can handle this:
1- You can merge all your data into an Spreadsheet (either importing directly in Excel/Google or using a JSON->CSV tool). Then export the Spreadsheet into a CSV file.
Have you game download the CSV from your server (or include it in the AssetBundles). Then at runtime, just use source.Import_CSV(...)

2- Keep using the JSON (downloaded or in AssetBundles), and write an script like the one in the previous post, to apply the new translations.

3- If you are downloading AssetBundles for the update, then add a LanguageSource with the new terms into one of the Scenes. As far as that scene is loaded once, all those terms will be usable in your game.

There is no mechanism for caching that store it in the persistent folder?


At runtime, when the plugin downloads from Google Spreadsheet, it saves into the persistentData folder the downloaded content and everytime the game starts, the source.Import_Google_FromCache() is executed to apply the downloaded content given that there is no way to modify the content of a stored prefab at runtime.

Said that, Import_Google_FromCache uses a format that comes from Google, and there is no Export_ToCache at the moment. What happens is that the downloaded data is saved as-is, given that it comes in an optimal format anyways so no need to loose time re-exporting it.

If your data comes from a server, what you can do is:
- If you need to update, contact the server and download a CSV or JSONs file.
- When the download completes, save the downloaded file
- Import the file into the source

* Have an script in your first scene, that checks if there is anything saved and calls the Import the File function.

I'm sorry there is no other automatic way of doing this. After I finish the new update, will try to make this more generic so that you could hook your own Server/Cache flow and handle the update in a built-in way without using Google Spreadsheets.

Hope that helps,
Frank

Are you :-) Give I2L 5 stars!
Are you :-( Please lets us know how to improve it!
To get the betas as soon as they are ready, check this out
Last edit: 6 years 2 months ago by Frank.

Please Log in or Create an account to join the conversation.

Time to create page: 0.370 seconds
Template by JoomlaShine