Unity noob here, just got the Localization package running today. Using Localization package v1.0.5 within Unity 2021.2.14f1.
In my case I am hoping to be able to selectively apply locale to different parts of my application. Instead of always applying locale globally, it possible to have one canvas with all child UI in “English (en)” locale and a separate canvas with all child UI “Spanish (es)” locale simultaneously? And within those canvases provide separate controls to change locale on user input?
For context, my case is a split screen application where both sides of the screen are running separate instances of essentially the same application, but it is not a multiplayer game.
Yes you can do this. First I would upgrade to 1.3.1 to make sure you have the latest version. It should be visible in the package manager if you enable the show all versions option in the package manager. Alternatively you can just edit the manifest JSON file in the packages file.
@karl_jones Thanks for your help! I’ll look into this at some point this week and update the thread when I’ve tried it.
I may come up with some questions about best practices for implementing the LocaleOverride. Seems like I’ll just need to connect all LocalizedStrings on my secondary canvas to its UI toggle (a button for switching between English and Spanish) via LocaleOverride.
Assuming you have 2 Canvases, 1 for selected locale and 1 for the override locale:
Call this on the locale override canvas.
void ApplyLocaleOverride(Locale locale, GameObject canvasRoot)
{
foreach(var ls in canvasRoot.GetComponentsInChildren<LocalizeStringEvent>())
{
ls.StringReference.LocaleOverride = locale;
}
}
You should not need to call GetLocalizedString, the text should automatically update when LocaleOverride is changed, as long as you are using the StringChanged event.
My mistake with using GetLocalizedString(), I must have misinterpreted one of my early tests with assigning LocalizeStringEvent.StringReference.LocaleOverride to think I needed that.
Below is my final script solving this problem for anyone that might be searching in the future. This is meant to provide language toggling on two identical canvases, each with their own button to switch between English and Spanish, via the onClick listener. I have a CanvasManager component class attached to the root canvas for each UI, which holds public references to the child UI objects - just my current choice for managing each UI. Both of my language buttons use this one script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Components;
using TMPro;
public class LangButton : MonoBehaviour
{
[SerializeField] CanvasManager CanvasManager;
// To be used as reference to check locale override status within ApplyLocaleOverride
LocalizeStringEvent LocalizeStringEventRef;
UnityEngine.Localization.Locale EnLocale;
UnityEngine.Localization.Locale EsLocale;
// Start is called before the first frame update
IEnumerator Start()
{
// Wait for the localization system to initialize
yield return LocalizationSettings.InitializationOperation;
// Establish available locales
//
// These could also be accessed with
// LocalizationSettings.AvailableLocales.GetLocale(SystemLanguage.English);
// LocalizationSettings.AvailableLocales.GetLocale(SystemLanguage.Spanish);
for (int i = 0; i < LocalizationSettings.AvailableLocales.Locales.Count; ++i)
{
var Locale = LocalizationSettings.AvailableLocales.Locales[i];
switch (Locale.name)
{
case "English (en)":
EnLocale = LocalizationSettings.AvailableLocales.Locales[i];
break;
case "Spanish (es)":
EsLocale = LocalizationSettings.AvailableLocales.Locales[i];
break;
}
}
// Initialize reference to check locale override status within ApplyLocaleOverride
LocalizeStringEventRef = CanvasManager.GetComponentInChildren<LocalizeStringEvent>();
// Set initial locale override to English
ApplyLocaleOverride(EnLocale, CanvasManager.gameObject);
// Add listener to button
CanvasManager.LangBtn.GetComponent<Button>().onClick.AddListener(ChangeLang);
}
void ChangeLang()
{
if (LocalizeStringEventRef.StringReference.LocaleOverride == EnLocale)
{
ApplyLocaleOverride(EsLocale, CanvasManager.gameObject);
}
else if (LocalizeStringEventRef.StringReference.LocaleOverride == EsLocale)
{
ApplyLocaleOverride(EnLocale, CanvasManager.gameObject);
}
}
// Override locale per canvas by looping through each LocalizeStringEvent component within a canvas
void ApplyLocaleOverride(Locale locale, GameObject canvasRoot)
{
foreach(var LocalizeStringEvent in canvasRoot.GetComponentsInChildren<LocalizeStringEvent>(true)) // Pass includeInactive param as true to get inactive UI strings too
{
LocalizeStringEvent.StringReference.LocaleOverride = locale;
}
}
}