Інтернаціоналізація ігор
Вступ
Хоча інді-ігри або нішеві ігри зазвичай не потребують локалізації, ігри, орієнтовані на більший ринок, часто потребують локалізації. Godot пропонує багато інструментів, щоб зробити цей процес більш простим, тому цей підручник більше схожий на збірку порад і підказок.
Локалізацією зазвичай займаються спеціальні студії, найняті для цієї роботи. Незважаючи на величезну кількість програмного забезпечення та форматів файлів, доступних для цього, найпоширенішим способом локалізації досі залишаються електронні таблиці. Процес створення електронних таблиць та їх імпортування вже описано в посібнику Імпорт перекладів. Якщо ви раніше не читали сторінку «Імпортування перекладів», радимо прочитати її перед тим, як читати цю сторінку.
Примітка
Ми будемо використовувати офіційну демонстрацію як приклад; ви можете завантажити його з Asset Library.
Налаштування імпортованого перекладу
Переклади можуть оновлюватися та повторно імпортуватися, при їх заміні, але їх все одно потрібно додати до проекту. Це робиться в Проект → Параметри проекту → Локалізація:
Наведене вище діалогове вікно використовується для додавання, або видалення, перекладів по всьому проекту.
Локалізація ресурсів
Також можна доручити Godot використовувати альтернативні версії ресурсів (ресурсів) залежно від поточної мови. Це може бути використано для локалізованих зображень, таких як ігрові білборди або локалізовані голоси.
Для цього можна використовувати вкладку Remaps:
Виберіть ресурс, який потрібно змінити, а потім додайте кілька альтернатив для кожної мови.
Примітка
Система перепризначення ресурсів не підтримується для DynamicFonts. Щоб використовувати різні шрифти залежно від сценарію мови, скористайтеся резервною системою DynamicFont, яка дозволяє визначати скільки завгодно резервних шрифтів.
Перевагою резервної системи DynamicFont є те, що вона працює незалежно від поточної мови, що робить її ідеальною для таких речей, як чат для кількох гравців, де мова тексту може не збігатися з мовою клієнта.
Автоматичне налаштування мови
Рекомендується за замовчуванням вибрати мову, яку користувач надає перевагу, яку можна отримати через OS.get_locale_language(). Якщо ваша гра недоступна цією мовою, вона повернеться до Fallback у Project Settings > Internationalization > Locale або до en, якщо пусто. Проте дозволити гравцям змінювати мову в грі рекомендується з різних причин (наприклад, якість перекладу чи переваги гравця).
var language = "automatic"
# Load here language from the user settings file
if language == "automatic":
var preferred_language = OS.get_locale_language()
TranslationServer.set_locale(preferred_language)
else:
TranslationServer.set_locale(language)
Локаль проти мови
locale зазвичай поєднує мову з регіоном або країною, але також може містити інформацію, як-от шрифт або варіант.
Приклади:
en: англійська моваen_GB: англійська у Великобританії / британська англійськаen_US: англійська в США / американська англійськаen_DE: англійська в Німеччині
Інді-ігри зазвичай потребують лише мови, але читайте далі, щоб дізнатися більше.
Чому існують локалі, можна проілюструвати на прикладі США та Великої Британії. Обидва говорять однією мовою (англійською), але відрізняються багатьма аспектами: - Правопис: напр. сірий (США), сірий (Великобританія) - використання слів: напр. баклажани (США), баклажани (Великобританія) – одиниці або валюти: напр. фути/дюйми (США), метри/см (ГБ)
Однак це може стати більш складним. Уявіть, що ви пропонуєте різний вміст у Європі та Китаї (наприклад, у MMO). Вам потрібно буде перекласти кожну з цих варіацій вмісту багатьма мовами, зберігати та завантажувати їх відповідно.
Перетворення ключів на текст
Деякі елементи керування, такі як Button і Label, автоматично отримуватимуть переклад, якщо їх текст відповідає ключу перекладу. Наприклад, якщо текст мітки є "MAIN_SCREEN_GREETING1" і цей ключ існує в поточному перекладі, то текст буде автоматично перекладений.
Така поведінка автоматичного перекладу може бути небажаною у певних випадках. Наприклад, якщо ви використовуєте мітку для відображення імені гравця, ви, найімовірніше, не хочете, щоб ім'я гравця перекладалося, якщо воно збігається з клавішею перекладу. Щоб вимкнути автоматичний переклад на певному вузлі, вимкніть Локалізація > Автоматичний переклад в інспекторі.
У коді можна використовувати функцію Object.tr(). Вона просто буде шукати текст у перекладах і конвертувати його, якщо він знайдений:
level.text = tr("LEVEL_5_NAME")
status.text = tr("GAME_STATUS_%d" % status_index)
level.Text = Tr("LEVEL_5_NAME");
status.Text = Tr($"GAME_STATUS_{statusIndex}");
Примітка
Якщо після зміни мови текст не відображається, спробуйте використати інший шрифт. Шрифт проекту за замовчуванням підтримує лише підмножину набору символів Latin-1, який не можна використовувати для відображення таких мов, як російська чи китайська.
Хорошим ресурсом для багатомовних шрифтів є Noto Fonts. Переконайтеся, що ви завантажили правильний варіант, якщо ви використовуєте менш поширену мову.
Завантаживши шрифт, завантажте файл TTF у ресурс DynamicFont і використовуйте його як спеціальний шрифт вашого вузла керування. Для кращого повторного використання зв’яжіть новий ресурс теми з кореневим вузлом керування та визначте DynamicFont як шрифт за замовчуванням у темі.
Заповнювачі
Щоб додати заповнювачі у ваші перекладені рядки, використовуйте Форматований текст GDScript або еквівалентну функцію в C#. Це дозволяє перекладачам вільно переміщувати місце заповнювача в рядку, що дозволяє перекладам звучати більш природно. По можливості слід використовувати іменовані заповнювачі з функцією String.format(), оскільки вони також дозволяють перекладачам вибирати порядок, у якому з’являються заповнювачі:
# The placeholder's locations can be changed, but not their order.
# This will probably not suffice for some target languages.
message.text = tr("%s picked up the %s") % ["Ogre", "Sword"]
# The placeholder's locations and order can be changed.
# Additionally, this form gives more context for translators to work with.
message.text = tr("{character} picked up the {weapon}").format({character = "Ogre", weapon = "Sword"})
Контексти перекладу
Якщо ви використовуєте звичайну англійську мову як вихідні рядки (а не коди повідомлень LIKE_THIS), ви можете зіткнутися з двозначностями, коли вам доведеться перекладати той самий англійський рядок різними рядками на певних цільових мовах. Ви можете додатково вказати контекст перекладу, щоб вирішити цю двозначність і дозволити цільовим мовам використовувати різні рядки, навіть якщо вихідний рядок ідентичний:
# "Close", as in an action (to close something).
button.set_text(tr("Close", "Actions"))
# "Close", as in a distance (opposite of "far").
distance_label.set_text(tr("Close", "Distance"))
// "Close", as in an action (to close something).
GetNode<Button>("Button").Text = Tr("Close", "Actions");
// "Close", as in a distance (opposite of "far").
GetNode<Label>("Distance").Text = Tr("Close", "Distance");
Множинність
Більшість мов вимагають різних рядків залежно від форми об’єкта в однині чи множині. Однак жорстке кодування умови "є множини" залежно від того, чи існує більше ніж 1 об’єкт, не є дійсним для всіх мов.
Деякі мови мають більше двох форм множини, і правила щодо кількості об’єктів, необхідних для кожної форми множини, відрізняються. Godot пропонує підтримку множини, щоб цільові локалі могли виконувати це автоматично.
Множина призначена для використання лише з додатними (або нульовими) цілими числами. Від’ємні значення та значення з плаваючою комою зазвичай представляють фізичні об’єкти, для яких однина та множина не застосовуються однозначно.
var num_apples = 5
label.text = tr_n("There is %d apple", "There are %d apples", num_apples) % num_apples
int numApples = 5;
GetNode<Label>("Label").Text = string.Format(TrN("There is {0} apple", "There are {0} apples", numApples), numApples);
За потреби це можна поєднати з контекстом:
var num_jobs = 1
label.text = tr_n("%d job", "%d jobs", num_jobs, "Task Manager") % num_jobs
int numJobs = 1;
GetNode<Label>("Label").Text = string.Format(TrN("{0} job", "{0} jobs", numJobs, "Task Manager"), numJobs);
Примітка
Переклад у формі множини підтримується лише Локалізація за допомогою gettext (PO-файли), а не CSV.
Контроль розміру
Один і той же текст на різних мовах може сильно відрізнятися за довжиною. Для цього обов'язково прочитайте підручник Розмір і анкери, оскільки динамічне регулювання розмірів може допомогти. Корисним може бути Container, як і параметри обтікання текстом, доступні в Label.
Щоб перевірити, чи може ваш інтерфейс користувача вмістити переклади з довгими рядками, ніж оригінальні, ви можете увімкнути pseudolocalization у розширених налаштуваннях проекту. Це замінить усі ваші локалізовані рядки на довші версії самих себе, а також замінить деякі символи в оригінальних рядках на версії з акцентами (при цьому вони залишаться читабельними). Заповнювачі залишаються без змін, щоб вони продовжували працювати, коли увімкнено псевдолокалізацію.
Наприклад, рядок Hello world, this is %s! стає [Ĥéłłô ŵôŕłd́, ŧh̀íš íš %s!], коли псевдолокалізацію ввімкнено.
Хоча на перший погляд виглядає дивно, псевдолокалізація має кілька переваг:
Це дозволяє швидко помітити нелокалізовані рядки, тож ви можете переглянути їх і зробити їх локалізованими (якщо це має сенс).
Це дозволяє перевіряти елементи інтерфейсу користувача, які не можуть вмістити довгі рядки. Багато мов містять набагато довші переклади, ніж вихідний текст, тому важливо переконатися, що ваш інтерфейс користувача може вміщувати довші, ніж зазвичай, рядки.
Це дозволяє перевірити, чи ваш шрифт містить усі символи, необхідні для підтримки різних мов. Однак, оскільки метою псевдолокалізації є збереження вихідних рядків читабельними, це не є ефективним тестом для перевірки того, чи підтримує шрифт CJK або мови з написанням справа наліво.
Параметри проекту дозволяють вам налаштувати поведінку псевдолокалізації, щоб за бажанням ви могли вимкнути її частини.
Сервер Перекладу
Godot має сервер низькорівневого керування перекладами під назвою TranslationServer. Переклади можна додавати або видаляти під час виконання; поточну мову також можна змінити під час виконання.
Двонаправлений текст і віддзеркалення інтерфейсу користувача
Арабська та іврит пишуться справа наліво (за винятком змішаних цифр і латинських слів), і інтерфейс користувача для цих мов також має бути дзеркальним. У деяких мовах форма гліфа змінюється залежно від навколишніх символів.
Підтримка двонаправлених систем письма та віддзеркалення інтерфейсу користувача є прозорою, зазвичай вам не потрібно нічого змінювати або знати про конкретну систему письма.
Для мов RTL Godot автоматично внесе такі зміни в інтерфейс користувача:
Дзеркальні ліві/праві прив’язки та поля.
Міняє місцями вирівнювання тексту по лівому та правому краю.
Віддзеркалює горизонтальний порядок дочірніх елементів керування в контейнерах і елементи в елементах керування Tree/ItemList.
Використовує дзеркальний порядок внутрішніх елементів керування (наприклад, кнопка спадного списку OptionButton, вирівнювання прапорців, порядок стовпців у списку, піктограми елементів дерева та вирівнювання сполучних ліній тощо), у деяких випадках дзеркальні елементи керування використовують окремі стилі теми.
Система координат не віддзеркалюється, і вузли, що не належать до інтерфейсу користувача (спрайти тощо), не впливають.
Можна змінити текст і керувати напрямком макета за допомогою таких властивостей елемента керування:
text_direction, встановлює основний напрямок тексту. Якщо встановлено значення «авто», напрямок залежить від першого сильного спрямованого символу в тексті відповідно до двонаправленого алгоритму Unicode,мова, замінює поточну мову проекту.Властивість
structured_text_bidi_overrideі_structured_text_parserзворотний виклик, дозволяють спеціальну обробку структурованого тексту.layout_direction, замінює дзеркальне відображення керування.
Дивись також
Ви можете побачити, як набір справа наліво працює в дії, використовуючи демонстраційний проект BiDI та Font Features <https://github.com/godotengine/godot-demo-projects/tree/master/gui/bidi_and_font_features>`__.
Додавання даних ітератора розриву до експортованого проекту
Деякі мови пишуться без пробілів. У цих мовах розрив слів і рядків вимагає більше, ніж просто правил для послідовностей символів. Godot включає правила ICU та дані ітератора розриву на основі словника, але ці дані за замовчуванням не включаються до експортованих проектів.
Щоб додати його, перейдіть до Проект → Налаштування проекту, увімкніть Інтернаціоналізація → Локаль → Включити дані текстового сервера, а потім експортуйте проєкт. Розмір даних ітератора розриву становить приблизно 4 МБ.
Перевизначення структурованого тексту BiDi
Алгоритм Unicode BiDi розроблений для роботи з природним текстом і не може обробляти текст із порядком вищого рівня, як-от імена файлів, URI, адреси електронної пошти, регулярні вирази чи вихідний код.
Наприклад, шлях до цієї показаної структури каталогу буде відображено неправильно (верхній елемент керування «LineEdit»). Заміна структурованого тексту типу "Файл" розбиває текст на сегменти, а потім алгоритм BiDi застосовується до кожного з них окремо для правильного відображення імен каталогів будь-якою мовою та збереження правильного порядку папок (нижній елемент керування "LineEdit").
Користувальницькі зворотні виклики забезпечують спосіб замінити BiDi для інших типів структурованого тексту.
Локалізація чисел
Елементи керування, спеціально розроблені для введення чи виведення чисел (наприклад, ProgressBar, SpinBox), автоматично використовуватимуть локалізовану систему нумерації, для іншого елемента керування TextServer.format_number(string, language) можна використовувати для перетворення західноарабських чисел ( 0..9) до локалізованої системи нумерації та TextServer.parse_number(string, language), щоб перетворити його назад.
Локалізація значків і зображень
Піктограми зі стрілками вліво та вправо, які, можливо, потрібно поміняти місцями для арабської та івритської мови, якщо вони вказують на рух або напрямок (наприклад, кнопки назад/вперед). В іншому випадку вони можуть залишитися такими ж.
Тестування перекладів
Можливо, вам варто протестувати переклад проєкту перед його публікацією. Godot пропонує три способи зробити це.
Спочатку в налаштуваннях проєкту, в розділі (якщо ввімкнено розширені налаштування), є властивість Test. Встановіть для цієї властивості код локалі мови, яку ви хочете протестувати. Godot запустить проєкт з цією локаллю під час запуску проєкту (або з редактора, або під час експорту).
Майте на увазі, що оскільки це параметр проекту, він відображатиметься в елементі керування версіями, коли встановлено непусте значення. Таким чином, він повинен бути повернутий назад до порожнього значення, перед внесенням змін до керування версіями.
По-друге, у редакторі перейдіть до верхньої панелі та натисніть на верхній панелі, потім перейдіть до Preview Translation та виберіть мову, яку ви хочете переглянути.
Весь текст у сценах редактора тепер має відображатися вибраною мовою.
Переклади також можна перевірити, запустивши Godot з командного рядка. Наприклад, щоб перевірити гру французькою мовою, можна надати такий аргумент:
godot --language fr
Переклад назви проекту
Назва проекту стає назвою програми під час експорту в інші операційні системи та платформи. Щоб указати назву проекту кількома мовами, перейдіть до Проект > Параметри проекту > Програма > Конфігурація. Звідси натисніть кнопку з написом Локалізований рядок (розмір 0). Тепер під цією має бути кнопка «Додати переклад». Натисніть на це, і ви перейдете на сторінку, де ви зможете вибрати мову (і країну, якщо потрібно) для перекладу назви вашого проекту. Після цього ви можете ввести локалізовану назву.
Якщо ви не впевнені в коді мови для використання, зверніться до списку кодів мов.