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

от автора

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

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

Именно так будут выглядеть локализованное главное меню на 3 языках в итоговом варианте:


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

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

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

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

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

Моноязычное хранение – данные (текст, диалоги, названия ваших аудио-файлов, и т.д.) будут содержаться в каждом отдельном файле, например, русский в 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.

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

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

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

«ScreenX» и «ScreenY» – координаты левого верхнего угла области, где будет начинаться меню;
«areaWidth» и «areaHeight» – размеры области, ширина и высота;
«currenPage» – переменная собственного типа «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.de;         }         if (GUILayout.Button("Deutsch"))         {             LangManager.currentLanguage = LangManager.LangType.ru;         }          if (GUILayout.Button(LangManager.Text("Menu", "Back")))         {             currentPage = Page.MainMenu;         }     }

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

У меня получилось такое главное меню и меню выбора языка:

В конечном итоге, получаем привлекательную картинку, которую при желании можно распечатать и повесить на стену:

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

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

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

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

Заключение

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

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

ссылка на оригинал статьи http://habrahabr.ru/post/185262/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *