Пишем свой менеджер локализации меню на Unity

в 14:29, , рубрики: game development, unity3d

Рано или поздно пусть даже небольшой успешный проект вам захочется показать не только своим друзьям, но и более широкой публике из других стран. Для того, чтобы всё больше и больше людей прониклись вашей «гениальной» идеей, необходимо осуществить перевод всех текстовых надписей и подписей на понятный язык его «нативных» обитателей.

В статье покажу как можно достаточно быстро написать свой менеджер локализации, параллельно сделаем несложное главное меню и меню выбора языка на Unity. У нас выбор языков будет состоять из 3-х: английский, немецкий и, конечно, русский.

Именно так будут выглядеть локализованное главное меню на 3 языках в итоговом варианте:
Пишем свой менеджер локализации меню на Unity

Для разработки будем использовать Unity3D и C#.

Базовые приготовления

Для начала создадим проект в Unity, создадим сцену, состоящую из: камеры; пустого элемента «Menu» типа «Gameobject»; текстуры типа «GUITexture» с привязанной интересной картинкой, которая будет использована в качестве фона; пустой текстуры с логотипом «unity». Жмём «Play».
Пишем свой менеджер локализации меню на Unity

Создаем файл локализации

Есть несколько вариантов организации и хранения данных локализации:

Моноязычное хранение – данные (текст, диалоги, названия ваших аудио-файлов, и т.д.) будут содержаться в каждом отдельном файле, например, русский в Russian.xml, а какой-нибудь Chinese – соответственно в Chinese.xml

Мультиязычное хранение – тут все данные хранятся в одном файле, что называется «all in one». Кто-то, возможно, скажет, что неудобно хранить в одном файле, но для проектов с малым объемом локализуемых данных, это самое «оно».

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

Для хранения текстовых данных будем использовать наиболее подходящий для этого тип – XML.
Формат данных нашего xml-файла выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8" ?>
<Settings>
    <meta>
        <Name>Project</Name>
        <version>1.0</version>
        <language>Multilingual</language>	
    </meta>
  <group id="Menu">
        <string id="Play">
		    <text lang="en">Play</text>
			<text lang="ru">Играть</text>	
			<text lang="de">Spielen</text>
        </string>	
  </group>	
</Settings>

Внутри элемента «meta» могут содержать общие данные вашего проекта, например, название, версию, данные для проверки оригинальности и целостности файла.
Элемент «group id» мы используем для названий главного меню, его также можно использовать для названия различных второстепенных меню, названий локаций, и т.д.
Элемент «string id», содержит те самые поля данных, которые должны быть локализованы.

Менеджер локализации

Теперь переходим непосредственно к созданию скриптов.

Создадим класс и скрипт «LangManager.cs», это и будет основной скрипт менеджера локализации.

Первое, свой тип данных. У нас, как было уже указано, будет 3 языка:

 enum LangType { en = 0, ru, de }; 

Соответственно, переменная и свойство для хранения текущего языка, по умолчанию будет английский:

    private static LangType _curLanguage = LangType.en;

    public static LangType currentLanguage
    {
        get { return _curLanguage; }

        set { _curLanguage = value; }
    }

Второе, это функция подзагрузки файла:

    XmlDocument root = new XmlDocument();

    if (!File.Exists(LanguagesFileName))
    {
        Debug.Log("Lang file is not find in directory");            
        return;
    }

    root.LoadXml(File.ReadAllText(LanguagesFileName));

    string language = root.SelectSingleNode("Settings/meta/language").InnerText;

    if (language != "Multilingual" || grouping != "Multi")
    {
        Debug.Log("Lang file is wrong");
        return;
    }

    isLoaded = true;

«LanguagesFileName» — переменная типа «string», путь к файлу локализации, например, LanguagesFileName = @"/Settings/Languages.xml"

Третье, функция получения локализованных данных, в зависимости от типа текущего языка. (Некоторые могут сказать, что не очень эффективно и следует использовать словари. Но, как говорится, «nobody cares»).

    public static string Text(string levelName, string id)
    {
        try
        {
            string xPath = "Settings";
            xPath += "/group[@id='" + levelName + "']";
            xPath += "/string[@id='" + id + "']";
            xPath += "/text[@lang='" + _curLanguage.ToString() + "']";
               
            return root.SelectSingleNode(xPath).InnerText;
        }
        catch (NullReferenceException)
        {
            return "Not been translated";
        }
    }

В случае отсутствия данных по запрашиваемому полю, будет показана надпись «not been translated».
Конечно же, каждый может добавить свои фирменные «плюшки». Итак, базовый менеджер локализации получен.

Создание и локализация меню

Первое, что делаем создаем скрипт и привязываем его к игровому объекту Menu.

Пишем свой менеджер локализации меню на Unity

В скрипте при запуске определяем загружен ли файл локализации, если ещё нет, то подгружаем.

    void Start ()
    {
        if (!LangManager.isLoaded)
            LangManager.LoadLanguageXml();
    }

Рендеринг всех элементов меню осуществляется внутри функции «OnGUI».

«ScreenX» и «ScreenY» – координаты левого верхнего угла области, где будет начинаться меню;
«areaWidth» и «areaHeight» – размеры области, ширина и высота;
«currentPage» – переменная собственного типа «Page», используется для определения «в каком меню мы находимся».

   void OnGUI()
    {	
        GUILayout.BeginArea(new Rect(ScreenX, ScreenY, areaWidth, areaHeight));

        switch (currentPage)
        {
            case Page.MainMenu:
                {
                    MainMenu();
                    break;
                }
            case Page.Language:
                {
                    LanguageMenu();
                    break;
                }
        }

        GUILayout.EndArea();
    }

Непосредственно функция создания самих кнопок в главном меню. Внутри можно дописать свои собственные обработчики нажатий, например, загрузка уровня или нового меню.

   void MainMenu()
    {
        if (GUILayout.Button(LangManager.Text("Menu", "Play")))
        {
            //обработка нажатия
        }

        if (GUILayout.Button(LangManager.Text("Menu", "Options")))
        {
            //обработка нажатия
        }

        if (GUILayout.Button(LangManager.Text("Menu", "Language"))
        {
            currentPage = Page.Language;
        }

        if (GUILayout.Button(LangManager.Text("Menu", "Credits")))
        {
            //обработка нажатия
        }

        if (GUILayout.Button(LangManager.Text("Menu", "Quit")
        {
            //обработка нажатия
        }    
    }

Меню выбора языка:

   void LanguageMenu()
    {
        if (GUILayout.Button("English"))
        {
            LangManager.currentLanguage = LangManager.LangType.en;
        }
        if (GUILayout.Button("Русский"))
        {
            LangManager.currentLanguage = LangManager.LangType.ru;
        }
        if (GUILayout.Button("Deutsch"))
        {
            LangManager.currentLanguage = LangManager.LangType.de;
        }

        if (GUILayout.Button(LangManager.Text("Menu", "Back")))
        {
            currentPage = Page.MainMenu;
        }
    }

Сохраняем, жмём «Play».

У меня получилось такое главное меню и меню выбора языка:
Пишем свой менеджер локализации меню на Unity

В конечном итоге, получаем привлекательную картинку, которую при желании можно распечатать и повесить на стену:
Пишем свой менеджер локализации меню на Unity

Альтернативы

В Unity Asset Store есть вполне пригодные для использования наработки (в виде расширения для Unity3D). И даже со специальным разделом Editor Extension/Language.

Бесплатный вариант – Language Manager.

Впрочем, «некоторые» умудряются «зашибать» даже на этом довольно неплохую безналичку. Если, конечно, покупать официально, то можно посмотреть:

Заключение

Сделать можно всё, главное – это желание, немножко терпения и 1 час жизни, и вуаля!

Пишем свой менеджер локализации меню на Unity

Успехов всем!

Автор: LeoMan

Источник

  1. Алексей:

    Статья хорошая, но не слишком подробная. Новичку сложно понять, что делать с некоторыми участками кода, в частности, куда сохранять код функции подзагрузки языкового файла и будет ли это всё работать на мобильных устройствах?

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js