image

Публикуя свою игру в Play-Market, я локализовал её только на два языка: английский и русский. Обзорные статьи по игре размещал тоже, соответственно, только на русскоязычных и англоязычных форумах. Статистика первого месяца позволила определить перечень стран, в которых игру начали активно качать. Поэтому было решено для закрепления успеха добавить локализацию еще на ряд языков. Среди прочих интерес к игре проявила и Индия.

За помощью по локализации игры на хинди я обратился к своему старинному индийскому другу, доктору Рудре Нараяну Пандею, который любезно согласился мне в этом помочь. Я предоставил Рудре таблицу игровых фраз, он быстро перевел всё на Хинди, а я, без всякой задней мысли, так же быстро скопипастил перевод в JSON-файл локализации. И, довольный, отправил Рудре билд на проверку. О, как же наивен был я тогда!

Рудра только снисходительно улыбнулся моей наивности и сказал, что текст содержит огромное количество неточностей, которых не было в его переводе. По описанию Рудры, текст в игре выглядел, как будто бы по аналогии в русском языке вместо «Ё» стояло бы «ЙО», а вместо «Ц» – «ТС». А для меня, совершенно не посвященного в тонкости хинди, всё выглядело одинаковым: что перевод в документе MS Word, что текст в игре. Но, внимательно пройдясь по рисунку текста, я действительно заметил разницу: как будто в некоторых местах буквы были переставлены местами, а кое-где выглядели по-разному. Ни мой друг, ни я не были посвящены в тайны шрифтов, и о причинах такого поведения текста могли только догадываться.

Поиск решения


После некоторого блуждания по бескрайним просторам Интернета причину удалось выяснить. Проблема оказалась в том, что Unity не поддерживает работу с таблицами GSUB и GPOS шрифтов. Первая, GSUB (Glyph Substitution Table), отвечает за замену последовательности символов на одну лигатуру, а вторая, GPOS (Glyph Positioning Table), – за корректировку взаимного расположения символов.

Если для русского текста в качестве примера работы GSUB я сходу вспомню только замену в MS Word трех точек подряд на один символ троеточие, то текст на хинди чуть ли не наполовину состоит из лигатур.

Например, вот так выглядит самоназвание языка:

image

В этом слове 2 лигатуры:

image     и     image

А вот так это слово отображается в Unity:

image

Unity просто рисует знаки по порядку их следования в слове, не изменяя согласно правил GSUB.

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

Идея первая


Взята тут. Перед отображением текста программно менять местами знак огласовки image (и) и предшествующую ему букву.

Да, это решение делает текст в Unity более похожим на хинди. Но оно затрагивает только малую часть правил GSUB, к тому же, не позволяет корректировать ширину «шапочки» знака в зависимости от ширины «накрываемой» буквы. Можно было бы написать такие замены для всех правил GSUB, но есть еще одна беда: Unity не импортирует символы шрифта, если они не имеют Unicode-номера. Стандартным шрифтом хинди в Windows является Mangal – в нём все лигатуры не имеют Unicode-номеров, поэтому Unity их «не видит». Следовательно, используя Mangal, программно сделать все замены не получится.

До перестановки:

image

После перестановки:

image

Должно быть:

image

Идея вторая


Из этого обсуждения, начиная с комментария #20. Для перевода текста на хинди использовать текстовый редактор, написанный на Unity, и шрифт, который включает в себя все возможные лигатуры, но с Unicode-номерами.

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

Идея третья


Из того же обсуждения, комментарий #38. Использовать шрифт Chanakya и конвертор текста для этого шрифта.

Данный шрифт содержит хинди-алфавит, а также небольшое количество (несколько десятков) наиболее часто используемых лигатур, которые имеют Unicode-номера, и, следовательно, могут быть импортированы и отображены в Unity. Web-конвертор производит преобразование Unicode-текста в кодировку шрифта Chanakya с одновременной заменой последовательностей символов, образующих лигатуры, на символы из шрифта с изображениями этих лигатур.

Опробовав этот метод, я убедился в его работоспособности.

Процесс локализации данным способом выглядит так:

1) Делаем перевод на хинди в любом удобном Unicode-редакторе, например, MS Word.
2) Конвертируем Unicode-текст из документа MS Word в кодировку шрифта Chanakya при помощи web-конвертора.
3) Полученную последовательность символов сохраняем в файле локализации.
4) В Unity эту последовательность отображаем шрифтом Chanakya, в результате чего визуально получаем красивый и правильный хинди.

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

Во-первых, огромный недостаток данного метода – это то, что шрифт Chanakya не содержит стандартных латинских символов, не говоря уже о кириллице. Из-за этого невозможно совместное отображение в одном текстовом поле текста на хинди и текста на каком либо другом языке.

Во-вторых, шрифт не содержит всех стандартных знаков пунктуации, а те, что содержит, стоят не под своими Unicode-номерами. Если в исходном тексте есть какие-либо знаки пунктуации, то они будут заменены конвертором на нежелаемые хинди-символы. Поэтому, для правильного результата нужно перед конвертированием удалить в исходном тексте все знаки пунктуации, а в результат добавить те Unicode-символы, на местах которых в Chanakya стоят требуемые знаки пунктуации.

Например, в исходном тексте имеются кавычки. Перед конвертацией мы их удаляем, а в результирующий текст на места открывающей и закрывающей кавычек добавляем символы O и O, соответственно, т.к. вместо этих символов в Chanakya стоят кавычки (только одинарные).

В-третьих, так как шрифт Chanakya содержит ограниченное количество лигатур, то возможны некоторые неконвертируемые последовательности – это видно по тому, что на странице конвертора в поле результата текст содержит латинские символы вместо хинди-символов. В этом случае следует попросить переводчика подобрать синонимы к тем словам, которые несконвертировались.

Иллюстрация процесса локализации:

Перевод на хинди:

image

Перевод, подготовленный для конвертирования – убраны знаки пунктуации:

image

Конвертированный текст в Unicode-виде:

image

Конвертированный текст с добавленными кавычками и точкой:

image

Конвертированный текст, отображаемый в Unity с помощью шрифта Chanakya:

image

Вот так, через танцы с бубном я и локализовал игру. У меня в игре язык переключается «на лету», поэтому я написал враппер на текстовое поле, который по событию переключения на хинди меняет Unicode-шрифт на Chanakya и обратно, соответственно, при переключении на другой язык. Также, враппер увеличивает размер шрифта текстового поля, потому что символы Chanakya маленькие.

При подготовке скриншотов для Play-Market и добавлении к ним подписей оказалось, что Photoshop, как и Unity, тоже не умеет работать с таблицами GPOS и GSUB. Этот метод помог и тут. Для этого потребовалось установить шрифт Chanakya в систему, конвертировать текст подписей web-конвертором, а в Photoshop отобразить полученный текст шрифтом Chanakya.

Мой друг Рудра остался очень доволен результатом. Он с гордостью рассказал в Facebook о нашей совместной работе, вспомнив давно забытый лозунг «Хинди руси бхай бхай». Наградой нам стал плавный, но уверенный рост количества скачиваний и большое количество пятерок с комментариями по поводу локализации.

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

Универсальный метод локализации Unity-игры на хинди.


Тогда-то и родилась еще одна идея, а именно: из идеи номер два взять шрифт Siddhanta, содержащий полный набор лигатур с Unicode-номерами, и написать на C# конвертор текста, эмулирующий действие GSUB и GPOS.

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

Также я написал автору шрифта Siddhanta – Михаилу Боярину, который разрешил использовать свой шрифт и проконсультировал меня по некоторым вопросам. Выражаю Михаилу благодарность за помощь. А объем работы, проделанный Михаилом при создании такого всеобъемлющего шрифта, поражает и вызывает уважение!

Результатом моих изысканий стал скрипт HindiCorrector, содержащий таблицу соответствий последовательностей символов лигатурам, и шрифт Siddhanta Unity.

Скачать проект можно тут: HindiCorrector.

Формат записей таблицы GSUB из скрипта HindiCorrector следующий:

{ source = "\u091F\u094D\u091F", dest = "\uF5A2\uF61F" }

Символы в полях source – это в основном простые буквы, знак халант и знаки огласовки, которые переводчик вводит с клавиатуры в текстовом редакторе. Символы в полях dest – это конечные лигатуры, которые, в отличие от шрифта Mangal, в шрифте Siddhanta имеют Unicode-номера, поэтому могут быть импортированы и отображены в Unity.

Метод скрипта Correct заменяет в исходном тексте все вхождения source на dest.

Помимо замены последовательностей символов на лигатуры скрипт также решает задачу корректировки ширины «шапочек» знаков огласовки image (и) и image (ии). В шрифте Siddhanta есть линейки этих символов с «шапочками» разной ширины. Скрипт выбирает символ с нужной шириной в зависимости от буквы, стоящей перед этим символом.
image

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

Данный метод локализации не требует каких-то ручных модификаций исходного текста на хинди. Всё делает скрипт.

Если требуется «обучить» хинди другой шрифт, используемый в игре, достаточно скопировать диапазоны символов 0900-097F и F000-F633 из шрифта Siddhanta Unity в нужный шрифт.

Шрифт Siddhanta Unity отличается от исходного шрифта Михаила Боярина тем, что из второго удалены все лигатуры, не участвующие в таблице GSUB скрипта HindiCorrector. Это позволило значительно снизить размер конечного шрифта, что крайне принципиально для мобильной разработки. Также добавлен диапазон символов F000-F01B, в который помещены некоторые существующие символы с откорректированными позициями.

Моя таблица GSUB не претендует на полноту, но она однозначно больше, чем реализовано в шрифте Chanakya из третьей идеи. Если потребуется добавить новую лигатуру, которой нет в моей таблице GSUB, то нужно выполнить следующие действия:

1) найти в исходном шрифте Siddhanta нужную лигатуру и cкопировать её под своим Unicode-номером в шрифт Siddhanta Unity;
2) добавить в таблицу GSUB скрипта HindiCorrector запись о замене последовательности символов на эту лигатуру.

Есть еще один важный момент: Unity не умеет стандартным способом распознавать установленный на телефоне язык хинди – метод Application.systemLanguage возвращает значение Unknown, что делает все усилия по локализации наполовину бессмысленными, т.к. далеко не все игроки посмотрят в настройках варианты выбора языка. На помощь пришло решение, описанное тут – запрашивать системный язык напрямую из JAVA-окружения.

В заключение благодарю своего друга доктора Рудру Нараяна Пандея за плодотворную совместную работу, интересное общение и новые знания. «Хинди руси бхай бхай»!
Поделиться с друзьями
-->

Комментарии (13)


  1. Igor_Sib
    10.03.2017 05:37
    +1

    Рентабельно хоть было?


    1. stepanoffvitaly
      10.03.2017 10:22
      +2

      С моим трафиком — нет. Это больше исследование во благо человечества.


      1. DnV
        10.03.2017 19:40

        Наверно, Индия изначально проявила интерес как раз по причине наличия английской локализации. Добавление хинди вообще намного интерес увеличило?


        1. stepanoffvitaly
          10.03.2017 19:43

          С последнего обновления по чуть-чуть начало расти. Правда, кроме хинди я еще добавил локализации на французский, немецкий, португальский и испанский )) До обновления было по 300-400 в день. Сейчас по 400-500 в день.


  1. Lorien_Elf
    10.03.2017 10:27
    +4

    То есть вы теперь… хинди-разработчик?
    *бадум-тсс*


    1. stepanoffvitaly
      10.03.2017 10:32

      Можно и так сказать )


  1. bfDeveloper
    10.03.2017 11:49
    +2

    Занимался как-то тем же самым. Только у нас ещё и bitmap шрифты были. То есть надо было все возможные графемы затолкать, а потом рендерер научить их мёржить. Как до, так и после этой работы, считал, что никогда не надо писать свои рендереры шрифтов. Да, мы добились успеха и многие подтвердили, что рисуем правильно, но невозможно забыть тот месяц, когда хинди стоял третьей раскладкой клавиатуры в системы на равне с RU и ENG. Там же каждая гласная может модифицировать написание предыдущей согласной, (и) меняет порядок, (р) хоть и согласная, но умеет сливаться с другими согласнымии и с самой собой. Как оказалось, word неправильно рисует длинные последовательности из этой (р), да и вообще ошибки много где нашлись, видимо потому, что в языке не встречается.
    По этой причине мне кажется, что подход с фиксированной таблицей в статье не может работать. Общее количество возможных лигатур в деванагари колоссально, их надо уметь рисовать на ходу. Та же шапочка у (и) вообще-то имеет очень много разных длин, так как она относится к слогу, и между ней и согласной может быть ещё пачка графем. Хотя на это обычно забивают.
    Вариативность у (р) с отсечением матры (|) вообще безумная и часто своя для каждой пары.
    Это, кстати, оказалось даже рентабельно. Индусов много.


    1. stepanoffvitaly
      10.03.2017 12:03

      Мой метод, конечно же, не охватывает всех правил. Но тот текст, который мне прислали на хинди, он позволил отобразить абсолютно правильно. Индийские друзья подтвердили это. Я думаю, что при повседневном наборе текста с клавиатуры индусы используют ограниченный набор лигатур, а для тех, которые не охвачены этим методом, можно подобрать слова-синонимы. Для перевода литературы не годится, а для локализации игр — легко и просто. Я даже скажу больше: для локализации игр не подойдет полный способ, т.к. потребует значительных вычислительных ресурсов.


  1. butch_plusplus
    10.03.2017 15:08

    Стало лучше, чем было ( я видел первоначальный вариант ), но по-прежнему попадаются косяки. Там где буквы имеют центральную "|", присеодиненные «р» (косая черта снизу) и «э» (косая черта сверху) смещены вправо. Особенно в буквах "?" и "?" это высаживает. Должно быть например: ????, ????. У тебя нижняя косая как бы перечеркивает ?, а верхняя сильно правее (должна быть ровно над «стволом»).


    1. stepanoffvitaly
      10.03.2017 15:11

      Совершенно верно. В Play-Market сейчас третий вариант локализации. Он-то и имеет эти недостатки. А вот последний вариант, описанный в статье, от них избавлен. Но я хочу набрать еще доработок игры, чтобы выпустить комплексное обновление, и в него включу последний вариант локализации.


  1. Arxitektor
    10.03.2017 18:46

    А как вообще язык такой сложности учат?
    И как такой тип языков называется? Просто похож очень на язык пришельцев).


    1. stepanoffvitaly
      10.03.2017 19:31

      Вот о языке:
      https://ru.wikipedia.org/wiki/Хинди
      На этом сайте в доступном виде ознакомительная информация по хинди:
      http://hindirus.ru/bukva-ligatura-alfavit-dopolnitelnie-znaki.html


    1. bfDeveloper
      10.03.2017 19:45

      Он не такой и сложный. По крайней мере читать научиться можно быстро. Про разговор не знаю, я только читал и писал :), что всё это значило понятия не имею. Мы, между прочим, их цифрами пользуемся. Видоизменёнными кончено, но вот как выглядят их цифры сейчас: ? ? ? ? ? ? ? ? ? ?
      Кое-что вывернуто, но вполне читаемо.