Loading and Unloading Localization Data

More
6 years 6 months ago - 6 years 6 months ago #3099 by textman
The NGUI localization data in my software program can "live" in the global I2Languages.prefab.

But my software program has a separate library of application text that is localized into 21 languages. This data has a total of about 282,000 characters of text including all localization. To include this in Resources seems to be a poor use of memory. My software program only needs 125 characters at a time. The best approach would be to load these and then unload them before another set is loaded. I mean that the program is only using 125 characters at a time, so it would be wildly inefficient for me to allocate all 282,000 characters into memory when only 125 are needed at any given moment.

My question is how can I load and unload the translated strings with I2 Localization (rather than dump it all into memory)? Is there an API for this? Because the data (282,000 characters) is not defined by scenes. The data is controlled by a game manager script (coroutine) that persists through all scenes and is never destroyed. So it is not possible for me to add it to certain scenes. I need to load and unload only 125 characters at a time, and pull the localized version when this happens, without relying on scenes to accomplish the loading and unloading. This seems like a common scenario actually, since more complex games and apps will not be managed by scenes, but will be managed by persistent manager scripts and coroutines.

A secondary question is how would you suggest metadata be store so it can best be used with I2 Localization? In my program's situation, I have 168 audio files, and the name of the file is used as a key for the "spreadsheet" or data storage, and in a spreadsheet for each of the 168 keys there are four fields (strings like "song name" "song composer" "year composed" and "era") and then 21 languages. I had wanted to use scriptable objects for efficiency to store it all, and to load and unload it using the key, and use I2 to manage it all. Or will I2 take care of the storage (like baking the localization into scripts) and all I have to do is put it into a Google spreadsheet? I'm confused about how the data will be stored if it is not actually attached to anything (I mean that the metadata is information about the audio file and it is connected because the key is the same as the audio file name). Where do I put the info? Just into the Google spreadsheet? And then how would I load and unload it for each set of four fields?

I hope I've explained it well enough. Can you steer me towards the best solution? I'm sure you've thought in detail about memory in large projects. If strings are not controlled by scenes (as in this case), then a large project needs to load and unload the data, per term and per language, using an API. As Unity grows and companies have bigger projects to localize (including AA and AAA projects) they will want to use I2 Localization, and this will be an issue. I was hoping that you had already built in a solution for this scenario.

Thanks.
Last edit: 6 years 6 months ago by textman.

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

More
6 years 6 months ago #3100 by Frank
Hi,
Even when you set all your translations in the I2Languages.prefab in the Resources folder, the memory used by all of them is not loaded while playing.

For simplicity, the plugin allows you to keep all your translations in the same prefab, that way you can see for each terms all its translations and avoid missing terms for some languages.
However, as soon as you start playing, the plugin saves each individual language into temporal files, and unloads the memory they use. Only keeping loaded the one you have active. Then, as you select different languages, the plugin loads the new one and unload the previous language.

That way you only have in memory what you are using.

If you have v2.8.6, you can see that behavior in the editor as well. If you click Play, you will see that all your translations in the I2Languages.prefab get deleted and as you change languages they are loaded back.
In 2.8.7, the editor no longer no longer does that by default (to avoid confusion and allow editing in play mode). There is a new option in the Languages tab, that allows controlling when the automatic unloading happens (NEVER, OnlyInDevice, InDeviceAndEditor).


The other way to control memory in I2 Localization is by having multiple language sources.
By default, you set all your terms in the I2Langauges.prefab which is accessible in All Scenes. That's called a Global Source.

But if there are several terms that are only used in specific scenes, then you can create GameObjects with LanguageSource components that hold those terms. Then, that memory is only used when those Objects are loaded.
That is used in the example scenes. Each example scene has its own LanguageSource which is Local to that scene.

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

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

More
6 years 5 months ago #3148 by HansWursT619
Hey,
do you have any examples on how to use local language sources?
I found multiple comments of you talking about it, but I am not quite sure how it is supposed to work.

Adding a new GameObject with the LanguageSource Component to each Scene makes sense to me.
But what else?

Do I have to create a new script that updated that language source from my .csv each time the Scene loads?
Something like I2.Loc.LocalizationManager.Sources[1].Import_CSV(string.Empty, csvFile, eSpreadsheetUpdateMode.Replace, ',');
With Sources[1] (hopefully) always being the local source in addition to Source[0] as the global source?

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

More
6 years 5 months ago #3149 by Frank
Hi,

do you have any examples on how to use local language sources?
I found multiple comments of you talking about it, but I am not quite sure how it is supposed to work.


All example scenes use local sources.
Local Sources are just GameObjects in the scenes with a LanguageSource script attached. Given that they can be created or destroyed when the scene is Loaded/Unloaded, then the terms inside those sources can only be accessed when the scene is loaded. That's why they are 'local'

Contrary to the Global Sources, that are Prefabs with a LanguageSource attached. Those prefabs are automatically loaded when the game starts by using the names from the GlobalSources array in Assets\I2\Localization\Scripts\Manager\LocalizationManager_Sources.cs. Given that global sources are loaded at startup and they are never destroyed, then the terms in there can be used everywhere in your projects, and thats why they are called 'global' sources.

Do I have to create a new script that updated that language source from my .csv each time the Scene loads?


All LanguageSources can store Terms. So, you don't need to call Import_CSV or modify them.
Unless you are specifically trying to have your users modify CSV files and import them at runtime. If thats the case, then yes, you need to call Import_CSV from one of your scripts.

Said that, if what you need is to not use google spreadsheets, and instead use a local spreadsheet in your computer (a CSV file), but never export the csv with your build. Then you just do as with regular google spreadsheets. In the editor, you switch to Spreadsheets tab, then, select Local, and Import or Export to synchronize. That way the content of the CSV is loaded into the LanguageSource and you don't need to call Import_CSV at runtime.

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

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

More
6 years 5 months ago #3155 by HansWursT619
Thanks for your reply.

Unfortunately I can not use the Google spreadsheets. This is why I use a .csv.
The application still needs to be able to have its terms updated after it is deployed. So basically only provide a new .csv and load it at start up. This is why I can't use the editor import features and store all terms in the I2Languages Prefab/GameObject.

Basically I want to use a global source for shared terms and a local source per scene. Both global and local loaded from a .csv at startup.
I had some trouble using the function Import_CSV(), it did not provide consistent results for me.
The default language is not consistent and every now and then terms are missing/old.

While the import works and the changes are also found in the PersistentStorage file, the terms are not correct in playmode.

So far I have the best results with a function like this called in an Awake():
    private void UseLocalizationCSV(string csvFile)
    {
        LocalizationManager.UpdateSources();
        I2.Loc.LocalizationManager.Sources[0].Import_CSV(string.Empty, csvFile, eSpreadsheetUpdateMode.Merge, ',');
        LocalizationManager.LocalizeAll(true);
    }

For exmaple I an using eSpreadsheetUpdateMode.Merge instead of Replace, also I think this should not be necessary.
I am not quite sure what the issue is, as you make it sound quite simple so load a new .csv at startup and per Scene.

I would now extend this to allow loading the global source to Sources[0] and the per Scene local source to Sources[1].

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

Time to create page: 0.156 seconds
Template by JoomlaShine