Как добавить в игру переключение языков геймплея? Юнити / Unity

Я сделал игру на русском языке. Допустим, я хочу, чтобы весь текст в игре пользователь мог изменить на тот, который ему нравится. Как наиболее правильно это сделать? Просто изменять весь текст на сцене при ее загрузке или есть какие-то уже готовые решения?


Ответы (1 шт):

Автор решения: Yaroslav

Если говорить о правильном изменении в реальном времени, это должна быть событийная модель, что-бы каждый элемент мог бы сразу отреагировать.

public enum Languages { EN, RU }

public delegate void ChangeLanguage (Languages language);

public class Language { // Singleton

    public ChangeLanguage Change; // Событие изменения языка
    private static Language instance;
    private Languages _current;

    public static Language getInstance () {
        if (instance == null)
            instance = new Language();
        return instance;
    }

    public Languages Current {
        get { return _current; }
        set {
            // Факт изменения языка, сообщение о событии, сохранение
            _current = value;
            if (Change != null)
                Change.Invoke(_current);
            PlayerPrefs.SetInt("language", (int)_current);
            PlayerPrefs.Save();
        }
    }

    private Language () {
        _current = (Languages)PlayerPrefs.GetInt("language");
    }
}

public class UILanguageElement : MonoBehaviour {

    private void Awake () {
        // Подписка на событие
        Language.getInstance().Change += ChangeLanguage;
        ChangeLanguage(Language.getInstance().Current);
    }

    // срабатывает при смене Language.getInstance().Current = Languages.RU;
    private void ChangeLanguage (Languages language) {
        switch (language) {

        }
    }
}

Что касается хранения, как вариант можно через ScriptableObject

(Создаются через Right Click / Create / Language Data, как создать материал или скрипт)

[CreateAssetMenu(fileName = "LanguageData", menuName = "Language Data")]

public class LanguageData : ScriptableObject {
    // Языки в массиве LanguageData по порядку enum Languages
    public string[] Text = new string[2];
}

Хронить для удобства все LanguageData в отдельной папке и подключать к UILanguageElement который тогда будет выглядеть так:

using UnityEngine.UI;

[DisallowMultipleComponent]
[RequireComponent(typeof(Text))]

public class UILanguageElement : MonoBehaviour {
    [SerializeField] private Text _text;
    [SerializeField] private LanguageData _data;

    private void Awake () {
        if (_text == null)
            _text = GetComponent<Text>();
        Language.getInstance().Change += ChangeLanguage;
        ChangeLanguage(Language.getInstance().Current);
    }

    private void ChangeLanguage (Languages language) {
        if (_text != null && _data != null && _data.Text != null) {
            int LanguageNumber = (int)language;
            if (_data.Text.Length >= LanguageNumber && _data.Text[LanguageNumber] != "") {
                _text.text = _data.Text[LanguageNumber];
                return;
            }
            // Если текст для данного языка отсутствует то устанавливается английский
            if (_data.Text.Length >= 0 && _data.Text[0] != "")
                _text.text = _data.Text[0];
        }
    }
}

Либо хранить в json, или даже txt, если не страшен парсинг.

→ Ссылка