Каталоги перевода PO и gettext
Заголовки PO, контекст, формы числа, fuzzy и обновление каталогов по POT.
Используйте отдельный каталог PO для каждой локали, когда переводчикам нужны независимые файлы, контекст и множественные формы. Reckfell загружает .po напрямую как ресурс Translation; компилировать его в .mo для этого сценария не требуется.
Рабочий русский каталог
Сохраните файл Locale/ru.po в UTF-8. Это полный каталог, а не шаблон:
msgid ""
msgstr ""
"Language: ru\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
msgid "PO_PLAY"
msgstr "Играть"
msgctxt "verb"
msgid "Open"
msgstr "Открыть"
msgctxt "state"
msgid "Open"
msgstr "Открыто"
msgid "PO_ITEM"
msgid_plural "PO_ITEMS"
msgstr[0] "{0} предмет"
msgstr[1] "{0} предмета"
msgstr[2] "{0} предметов"- Добавьте Locale/ru.po в Project Settings → Localization → Translations. В отличие от таблицы CSV, файл PO сам является загружаемым ресурсом перевода.
- Установите локаль игры: TranslationServer.SetLocale("ru").
- TranslationServer.Translate("PO_PLAY").ToString() вернёт Играть.
- TranslationServer.Translate("Open", "state").ToString() вернёт Открыто.
- TranslationServer.TranslatePlural("PO_ITEM", "PO_ITEMS", 5).ToString() вернёт {0} предметов. Передайте результат в string.Format вместе с числом, чтобы получить 5 предметов.
Эти вызовы размещаются внутри метода. Полный скрипт Label с обновлением при смене локали есть в примере CSV: замените ITEM/ITEMS на PO_ITEM/PO_ITEMS и зарегистрируйте этот каталог PO.
Локаль ресурса задаёт заголовок Language: одного имени файла недостаточно. Сохраняйте все формы с индексами от 0 до nplurals−1 и заполнители форматирования. Не подключайте этот каталог вместе с другим, определяющим ту же пару ключ/контекст для той же локали: объедините сообщения или используйте разные ключи.
Записи, которые не дают переведённого текста
Загрузчик пропускает запись со специальным комментарием #, fuzzy. Флаг означает, что перевод требует проверки. Исправьте и подтвердите текст перед снятием флага; не удаляйте флаги только ради появления строк на экране.
Пустой msgstr не означает пустую надпись. При поиске нет пригодного текста, поэтому возвращается резервный перевод или исходный ключ. Для сообщения с контекстом передайте тот же контекст в вызов. Обычный запрос Open не может выбрать между verb и state.
Фрагменты PO в кавычках соединяются. Для переноса строки используйте \n внутри строки, для кавычки — ", для буквальной обратной косой черты — \. Сохраняйте эти последовательности при переводе.
Поддерживать шаблон POT
Файл .pot хранит исходные сообщения; его значения msgstr остаются пустыми. Файл .po содержит переводы, .mo — скомпилированный каталог. Подключайте каталоги PO или MO, а не шаблон POT.
В Project Settings → Localization → Template Generation добавьте исходные файлы и создайте .pot. Парсер PackedEntity принимает распознаваемые расширения этого ресурса, включая уровни и префабы; используйте настоящие файлы .rscene/.rprefab. Парсер C# распознаёт вызовы перевода Tr, TrN, TranslationServer.Translate и TranslatePlural, когда аргументы сообщений вычисляются как строковые константы. Ключ, собранный во время игры, требует явной записи в каталоге или отдельного способа извлечения: генератор не может вывести все возможные значения.
После добавления сообщений заново создайте шаблон, обновите каталоги каждого языка и проверьте изменённые переводы. Не заменяйте переведённый каталог пустым шаблоном.
Если установлен GNU gettext, выполните из каталога проекта:
msgmerge --update Locale/ru.po Locale/messages.pot
msgfmt --check --output-file=Locale/ru.mo Locale/ru.poПервая команда обновляет существующий PO по актуальному POT. Вторая проверяет каталог и создаёт MO. Разберите диагностику: проверка заголовка может сообщить о недостающих метаданных, а успешное выполнение не доказывает точность перевода. Официальные описания: параметры msgmerge и проверки msgfmt.
Храните редактируемые PO в системе контроля версий, даже если распространяете скомпилированные каталоги. Не подключайте PO и MO одного каталога одновременно. Текущий загрузчик движка распознаёт оба расширения; проверка этого руководства выполнялась для PO, без компиляции/загрузки MO и внешних утилит gettext.
Диагностика каталога
| Симптом | Что проверить |
|---|---|
| Ошибка заголовка или конфигурации | Начальные пустые msgid/msgstr и строки заголовка присутствуют, кавычки и обратные косые черты записаны правильно |
| Неверная локаль | Заголовок Language, активную локаль и подключённый ресурс |
| Вместо переведённой записи виден ключ | Флаг fuzzy, пустой msgstr, точное совпадение ключа/контекста, регистрацию и резервный язык |
| Ошибка чтения множественных форм | Корректный заголовок Plural-Forms перед записями и соответствующее число msgstr с индексами |
| Новых сообщений из исходников нет | Обновите POT, объедините каталоги, переведите записи и перезагрузите ресурсы |
| Вместо числа осталось {0} | Отформатируйте выбранную форму: поиск перевода не подставляет числа |
В движке проверены загрузка такой структуры каталога, русские правила множественного числа, контекст, многострочные записи, пропуск fuzzy, пустые переводы и регистрация во время игры. Инструкции извлечения сверены с исходниками. Автоматическая генерация POT, внешние утилиты, файлы MO, отображение шрифтов и экспорт на платформы этим запуском не проверялись.