Unity "Простая система перевода игры на другие языки"

Данная система подойдет для начинающих разработчиков или инди разработчиков. Данной решение не идеальное. Оно создавалось для простой hyper casual. Для визуальных новел или какой-нибудь RPG оно конечно же не подойдет.

Система рассчитана для работы в одной сцене. Для игр с несколькими сценами, данное решение может не работать. Тем не менее разобравшись в нем, его можно доработать под свои нужды.

Начнем со списка языков. Для удобства выбора языка в редакторе Unity я решил воспользоваться перечислением.

public enum EnumLanguage { en = 0, ru = 1 }

Следующий скрипт я наследовал от Scriptable Object. Сделано это для использования его в скриптах как объект, который хранит выбранный язык интерфейса.

Так же он содержит метод изменения выбранного языка на другой (ChangeLanguage).

using System; using UnityEngine; [CreateAssetMenu(fileName = "Current Language", menuName = "MyTools/Language System/Current Language", order = 2)] public class CurrentLanguage : ScriptableObject { [SerializeField] private EnumLanguage language; private int countLanguage; public EnumLanguage Language => language; private void OnEnable() { countLanguage = Enum.GetNames(typeof(EnumLanguage)).Length - 1; } public void ChangeLanguage() { language++; if (((int)language) > countLanguage) language = 0; } }

Следующий скрипт. Скрипт предназначен для хранения строк на разных языках.

using UnityEngine; [CreateAssetMenu(fileName = "Translation String", menuName = "MyTools/Language System/Translation String", order = 1)] public class TranslationString : ScriptableObject { [SerializeField] string[] strs; public string[] Strs => strs; }

Последний скрипт, который понадобится, это скрипт изменения текста на интерфейсе.

Данный скрипт работает с только TextMeshPro. Если у вас в проекте обычный Text или какой-то еще. Тогда надо по подобию написать скрипт для вашего компонента интерфейса.

using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; public class SetTextMehProLanguage : MonoBehaviour { [SerializeField] private TranslationString translationString; [SerializeField] private CurrentLanguage currentLanguage; private TextMeshProUGUI textMesh; private void OnEnable() { EventsManager.onChangeLanguage.AddListener(SetTxt); } private void Awake() { textMesh = GetComponent<TextMeshProUGUI>(); SetTxt(); } public void SetTxt() { int index = (int)currentLanguage.Language; textMesh.text = translationString.Strs[index]; } }

В этом скрипте используется событие onChangeLanguage, которое находится в статическом классе EventsManager. Вы можете добавить это событие туда, где будет удобно вам. Главное, чтобы к нему был общий доступ. Затем, вы можете вызывать его где угодно. Например при нажатии на кнопку сменить язык.

public static UnityEvent onChangeLanguage = new UnityEvent();

Попробуем использовать данную систему.

Создаем CurrentLanguage объект и выбираем язык, который будет установлен при старте игры.

Unity "Простая система перевода игры на другие языки"

Далее создаем несколько объектов TranslationString. Прописываем текст по соответствию языка.

Unity "Простая система перевода игры на другие языки"
Unity "Простая система перевода игры на другие языки"

Далее добавляем на объект, который содержит Text Mesh Pro — скрипт SetTextMeshProLanguage. И выбираем для него подходящий объект TranslationString.

Unity "Простая система перевода игры на другие языки"

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

using UnityEngine; public class OnClickBtnLanguage : MonoBehaviour { [SerializeField] CurrentLanguage currentLanguage; public void OnClick() { currentLanguage.ChangeLanguage(); EventsManager.onChangeLanguage?.Invoke(); } }

Во время написания статьи, я понял, что Current Language нужно создать как-то по-другому. Например, статическим классом или синглтоном. Из-за того, что приходится каждый раз его выбирать в SetTextMeshProLanguage. Хотя он всегда будет в единственном экземпляре.

Что касается системы в целом. В дальнейшем, можно очень просто добавить еще один язык. И строки перевода. Если не устроит какая-то часть системы, то ее можно легко заменить (до того, как начали внедрять в свой проект).

55
2 комментария

О таком не знал. Писать велосипеды нужно хотя бы для того, чтобы научится.

А если не знаком с каким то решением, то можно потратить очень много времени. Я потратил пол часа. И все идеально работает.

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

В любом случае, спасибо за статью. Почитаю, как будет время

1