i18n localization with asset bundles

  • pedrevans
  • Topic Author
  • Visitor
  • Visitor
7 years 11 months ago #1373 by pedrevans
i18n localization with asset bundles was created by pedrevans
HI

I have many language specific button sprites. I store them in separate folders, e.g.

Assets/Resources/language/de/about-us-button-de.png
Assets/Resources/language/de/stats-button-de.png
Assets/Resources/language/de/about-us-button-de-p.png
Assets/Resources/language/de/stats-button-de-p.png

Assets/Resources/language/fr/about-us-button-fr.png
Assets/Resources/language/fr/stats-button-fr.png
Assets/Resources/language/fr/about-us-button-fr-p.png
Assets/Resources/language/fr/stats-button-fr-p.png

... and many more ...

1. Editor

To reduce the size of the APK and IPA files I want to store the language specific sprites in a separate asset bundle for each language.

The language specific sprites are in the Resources folder. Everything in the resources folder gets bundled in with the build whether I want it or not, so I use the hack of switching off read permissions on the language specific folders to prevent the files getting into the build.

Is there a better way? E.g. can I get I2L to load only stuff that's not assigned to an asset bundle?

2. Runtime

How do I load the sprites at runtime (say when switching from one language to another)?

I succeed in downloading the asset bundle and I can assign a sprite from it to a non-i18n image. But localized images remain stubbornly white when I try to assign the sprite. Is I2L overwriting them?

How do I assign the asset into the localization component? How to trigger the OnModifyLocalization at the right time?

My solutions at the moment involve bypassing the I2L system, but hopefully this is not necessary.

I have the feeling that you may have solved this problem already and that I am thinking too much in the wrong direction.

I have only one source and it is completely available at all times.

I'd be grateful if you could give me a couple of tips to point me in the right direction. :)

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

More
7 years 11 months ago - 7 years 11 months ago #1379 by Frank
Hi,
Sorry for the delay in answering, Fridays are crazy, and I wanted to double check a couple things before replying!

Everything in the resources folder gets bundled in with the build whether I want it or not

I thought that an asset marked as part of bundle (in unity5), was not included in the build, even if it was part of the Resources folder.
But it seems, that may not be the case, so yes, making those assets not readable as part of the build process is the easiest way.

How do I load the sprites at runtime (say when switching from one language to another)?


When a localize component is assigned to a sprite, it will control the sprite image and will change it automatically when switching language.
You shouldn't change the sprite image directly because it will be overridden as soon as the language changes or the object is re-enabled.

Instead, you should get the termData used in the Localize component and change the path to the image. Then call localizeComponent.OnLocalize().

When the OnLocalize method is called, it will try converting the path into an asset that could be assigned to the sprite object.
The Localize component calls GetSecondaryTranslatedObj(...) that in turn calls FindTranslatedObject(...)

FindTranslatedObject searches the referenced Assets in the Localize component (sprites, fonts and other assets not in the Resources folder are automatically added to the referenced assets list).
If the asset is not in that list, then it tries to load from the Resources folder by calling the ResourceManager.pInstance.GetAsset<T>()

My suggestion for dealing with assets bundles is to modify the ResourcesManager.LoadFromResources function to load the asset from the bundle if its not found in the Resources folder:
		public T LoadFromResources<T>( string Path ) where T : Object
		{
			if (string.IsNullOrEmpty(Path))
				return null;
			
			Object Obj;
			// Doing Resource.Load is very slow so we are catching the recently loaded objects
			if (mResourcesCache.TryGetValue(Path, out Obj) && Obj!=null)
			{
				return Obj as T;
			}

			T obj = null;

			if (Path.EndsWith("]", System.StringComparison.OrdinalIgnoreCase))	// Handle sprites (Multiple) loaded from resources :   "SpritePath[SpriteName]"
			{
				int idx = Path.LastIndexOf("[", System.StringComparison.OrdinalIgnoreCase);
				int len = Path.Length-idx-2;
				string MultiSpriteName = Path.Substring(idx+1, len);
				Path = Path.Substring(0, idx);
				
				T[] objs = Resources.LoadAll<T>(Path);
				for (int j=0, jmax=objs.Length; j<jmax; ++j)
					if (objs[j].name.Equals(MultiSpriteName))
					{
						obj = objs[j];
						break;
					}
			}
			else
				obj = Resources.Load<T>(Path);

////--[ Add Your Code HERE ]--------------------------------

			if (obj==null)  // If the object was not in the cache and was not in the Resources folder
			{
			      // Add here your code to load the object "Path" from the AssetBundle 
			      obj = ...... load from path
			}

////--[ END ]--------------------------------

			mResourcesCache[Path] = obj;

			if (!mCleaningScheduled)
			{
				Invoke("CleanResourceCache", 0.1f);
				mCleaningScheduled = true;
			}
			return obj;
		}


Using that you could do the localization by:

- Setup all your localization normally with the sprites in the Resources folder as you already have
- Change the LoadFromResources function to find the asset in the AssetBundle
- At build time, remove or remove permissions to the bundled assets

Given that those assets are not going to be included in the build, the plugin will not find them in the Referenced Assets, nor in the Resources folder, so it will fallback to searching in the AssetBundle.


Most studios manage bundles differently, that's why I haven't already implemented a way to use them directly.
However, I will add that to the list of things to do asap (right after fixing the IOS store integration, the language TranslateAll button and updating the term Normal/Touch variants to support custom variants)

My idea is to add an AssetBundleManager with a few virtual functions, that users could reimplement to adjust to their own bundle managers, and then have the ResourceManager call the AssetBundleManager. That should do the trick! :-)

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: 7 years 11 months ago by Frank.
The following user(s) said Thank You: pedrevans

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

  • pedrevans
  • Topic Author
  • Visitor
  • Visitor
7 years 11 months ago #1383 by pedrevans
Replied by pedrevans on topic i18n localization with asset bundles
Thank you Frank, it looks like you have ended my asset bundle nightmare :)

The suggestion works well.

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

Time to create page: 0.127 seconds
Template by JoomlaShine