How to set starting locale?

In my app, the user can choose the desired locale and save it as PlayerPrefs.
When starting the app, app tries to change current locale to the saved value. But contrary to expectations, locale is always set as device default, not the saved value.

Is there some timing-related problem or something? What is the best approach to make app start with the desired locale?

Use the Locale selectors. We already have a player preference one https://docs.unity3d.com/Packages/com.unity.localization@0.9/manual/LocalizationSettings.html
Click the + icon to add one.
You can also create a custom one by inheriting from IStartupLocaleSelector
This is the PlayerPrefOne:

using System;

namespace UnityEngine.Localization.Settings
{
    /// <summary>
    /// Uses the Player Prefs to keep track of the last used locale.
    /// Whenever the locale is changed, the new Locale is recorded in the Player prefs.
    /// </summary>
    [Serializable]
    public class PlayerPrefLocaleSelector : IStartupLocaleSelector, IInitialize
    {
        [SerializeField]
        string m_PlayerPreferenceKey = "selected-locale";

        /// <summary>
        /// The Player Pref key to use.
        /// </summary>
        public string PlayerPreferenceKey
        {
            get => m_PlayerPreferenceKey;
            set => m_PlayerPreferenceKey = value;
        }

        /// <summary>
        /// Registers a callback to <see cref="LocalizationSettings.SelectedLocaleChanged"/> in order to save changes made to the Locale.
        /// </summary>
        /// <param name="settings"></param>
        public void PostInitialization(LocalizationSettings settings)
        {
            if (Application.isPlaying)
            {
                // Record the new selected locale so it can persist between runs
                var selectedLocale = settings.GetSelectedLocale();
                if (selectedLocale != null)
                    PlayerPrefs.SetString(PlayerPreferenceKey, selectedLocale.Identifier.Code);
            }
        }

        /// <summary>
        /// Returns the last locale set or null if no value has been recorded yet.
        /// </summary>
        /// <param name="availableLocales"></param>
        /// <returns></returns>
        public Locale GetStartupLocale(ILocalesProvider availableLocales)
        {
            if (PlayerPrefs.HasKey(PlayerPreferenceKey))
            {
                var code = PlayerPrefs.GetString(PlayerPreferenceKey);
                if (!string.IsNullOrEmpty(code))
                {
                    return availableLocales.GetLocale(code);
                }
            }

            // No locale could be found.
            return null;
        }
    }
}

It will update the preference whenever the locale is changed.

Ok, I created custom LocaleSelector class and set it as the first locale selector at the project setting.
Now it works fine. :slight_smile: Thanks!

Also if anyone wants to access it elsewhere, this is the script:

PlayerPrefs.GetString("selected-locale", "en")

what would happen if null is returned?
Does it mean localizaton package will first select a locale based on device (for example if device is hebrew, and there is a locale for hebrew) or english when only available local is english?

Another question is, how can i simulate real device behavior in editor for example, i want to test if a an app is first time run on a device with lets say some other language like russian or chinese (so i know what would happen in first time use cases)

Thanks

The LocaleSelector works through the list until a non-null value is returned
https://docs.unity3d.com/Packages/com.unity.localization@1.5/manual/LocalizationSettings.html#locale-selector

The system locale selector works like this Class SystemLocaleSelector | Localization | 1.4.5

You could try using the device simulator, that should let you simulate the system locale Device Simulator | Unity Documentation

Really sorry for my noob confusion.

What should i do if i want following behaviour?

1- I’ll use IStartupLocaleSelector locale, and get user selected language and return it or will return null (like code above) (Already clear)

2- Now, if i return null, i want localization system to pick locale close to device language

3- if no such device locale is found, then choose english

What should I do on my side, to make sure 2 and 3 works.

Thanks

In the LocalizationSettings, under the Locale Selector you should have 3 items in this order:

  1. Your custom IStartupLocaleSelector (top)
  2. System Locale Selector
  3. Specific Locale Selector set to English (bottom)