Локализация
Локализация
Локализация интерфейса помогает игре выйти на мировую аудиторию и делает приложение понятным и привычным на любом языке. Unity 6 упрощает процесс благодаря прямой интеграции пакета Localization с UI Toolkit. Она позволяет предлагать игрокам содержимое с учётом их региона, где бы они ни находились. Ключевую роль в локализации Unity играет класс Locale: он представляет конкретный язык и управляет региональными параметрами, например форматами валют и чисел. Рассмотрим простой пример настройки локализации в UI Toolkit. После такой настройки приложение сможет динамически менять содержимое в соответствии с выбранным Locale.
элементы управления |
Пример локализации на испанский язык в UI Toolkit Sample - Dragon Crashers
Как это работает Основные возможности пакета Localization: - Локализация строк: класс LocalizedString позволяет управлять строками, которые автоматически обновляются при смене Locale во время выполнения. Smart Strings поддерживают заполнители, формы множественного числа и другие языковые особенности.
- Локализация ресурсов: текстуры и другие ресурсы можно заменять в зависимости от Locale, создавая региональные варианты не только текста, но и другого содержимого. - Привязка данных: пакет Localization интегрирован с привязкой данных UI Toolkit во время выполнения и связывает элементы интерфейса с String Table и Asset Table. Изменение данных, Locale или состояния загрузки автоматически обновляет интерфейс. - Управление String Table и Asset Table: таблицы хранят пары «ключ - значение» для перевода текста или замены других ресурсов вариантами, соответствующими Locale. Централизованный интерфейс даёт общее представление обо всех локализованных строках и ресурсах проекта. - Переключение Locale: язык можно менять в реальном времени без перезапуска приложения. Выберите новый Locale во время выполнения, и интерфейс сразу обновится.
При адаптации к разной длине и оформлению текста используйте FlexBox-контейнеры и элементы UI Toolkit с автоматическим размером. Это помогает создавать интерфейсы, которые лучше приспосабливаются к разным языкам.
элементы управления |
Настройка локализации Чтобы начать использовать пакет Localization Unity с UI Toolkit, выполните следующие основные действия: подготовьте локализованное содержимое и свяжите его с элементами интерфейса в UI Builder.
Установите пакет Localization через Package Manager.
1. Настройте Localization Settings. Установите пакет Localization через Package Manager, затем откройте Project Settings > Localization и создайте ресурс Localization Settings. В нём настраиваются все локализованные ресурсы проекта.
Создание и настройка Localization Settings в Project Settings.
элементы управления |
2. Создайте Locale. С помощью Locale Generator определите поддерживаемые языки и регионы. Для каждого Locale будет создан ресурс с уникальным двухбуквенным кодом: например, en для английского, fr для французского и es для испанского. Укажите Locale по умолчанию, который будет использоваться при запуске приложения.
Добавление Locale.
3. Создайте String Table и Asset Table. Используйте String Table для хранения текстовых записей каждого Locale. Добавьте строки элементов интерфейса: надписей, кнопок и вариантов раскрывающихся списков.
Создание String Table и Asset Table.
элементы управления |
4. В окне Localization Tables (Window > Asset Management > Localization Tables) добавьте пары «ключ - значение» для каждого текстового элемента интерфейса. Ключ обозначает конкретный текстовый элемент, например метку или кнопку, а значение содержит перевод этого элемента для каждой локали. 5. Храните региональные ресурсы, например изображения или GameObject, в таблицах ресурсов (Asset Tables). В частности, туда можно добавить спрайты или текстуры значков для каждой локали. Свяжите каждый ключ с ресурсами, предназначенными для соответствующей локали и учитывающими региональные или культурные особенности.
Каждый локализуемый элемент представлен парой «ключ значение».
6. Создайте интерфейс в UXML. В UI Builder создайте UXML-файл с такими элементами, как Button, DropdownField и Label. В демонстрационной сцене этот UXML содержит несколько элементов, подготовленных к локализации. Для текстовых полей используйте запись из таблицы строк (String Table), а для нетекстовых, например текстур, - запись из таблицы ресурсов (Asset Table).
Демонстрационная сцена
Пример реализации локализации находится в сцене LocalizationDemo проекта QuizU. Чтобы открыть его во время выполнения, перейдите в главное меню и выберите Demos > Localization. Также можно отключить загрузчик (Quiz > Don’t Load Bootstrap Scene on Play) и загрузить сцену LocalizationDemo напрямую.
элементы управления |
Добавьте в UI Builder привязки данных к локализованным строкам и ресурсам.
7. Привяжите данные к элементам интерфейса в UI Builder. Здесь раскрываются возможности системы привязки данных UI Toolkit во время выполнения. Выберите в UI Builder элемент, который требуется локализовать. Откройте панель Inspector и в поле содержимого выберите Add Binding: например, для Label это поле text, а для изображения - backgroundImage. В качестве типа привязки выберите LocalizedString или другой локализованный ресурс и укажите соответствующую запись в таблице строк или ресурсов. По мере локализации новых элементов добавляйте записи в эти таблицы.
Для предварительного просмотра локализации используйте раскрывающийся список локалей в окне Game View.
элементы управления |
8. Для проверки выберите нужные языки в раскрывающемся списке локалей окна Game View и убедитесь, что элементы интерфейса правильно отображаются в каждой локали.
Базовая настройка завершена! Теперь в этом примере текстовые свойства кнопок и меток можно переключать на любой настроенный язык. Чтобы локализовать весь интерфейс, создайте в таблице строк отдельную запись для каждого фрагмента текста. Пакет Localization позволяет гибко организовать содержимое: крупный проект можно разделить на удобные разделы с помощью нескольких таблиц строк или сгруппировать записи по категориям. Для локализации текстур и других нетекстовых ресурсов используйте таблицы ресурсов. После добавления привязок локализации в UI Builder они сохраняются непосредственно в элементах UXML-файла. В результате получается такой блок кода, где каждое локализованное свойство связано с конкретной записью в таблице строк или ресурсов:
<Bindings> <UnityEngine.Localization.LocalizedString property="text" table="GUID:6aaa262cde38a4024bc3fc7f5ce6d50d" entry="Id(104135776002048)" /> </Bindings>
Этот фрагмент UXML создаёт привязку данных, которая связывает свойство text элемента интерфейса с записью в таблице строк или ресурсов.
При каждом обновлении таблиц локализации связанные элементы интерфейса автоматически получают актуальное локализованное содержимое. Примечание. UI Builder упрощает создание привязок данных, однако опытные пользователи могут редактировать UXML напрямую, чтобы точнее управлять локализованным содержимым.
Использование API локализации Раскрывающийся список локалей в окне Game View удобен для проверки разных языков в редакторе, но в сборке приложения его не будет. Чтобы пользователи могли менять язык в готовом приложении, создайте собственный интерфейс переключения локалей.
Выбор локали Если известен двухбуквенный идентификатор локали, активную локаль можно задать через LocalizationSettings. Затем свяжите это действие с кнопками: используйте манипулятор clicked каждой кнопки или метод RegisterCallback<ClickEvent>.
элементы управления |
Один из вариантов реализации показан в скрипте LocalizationDemo из примера проекта:
void SelectLocale(string localeCode) {
Locale locale = LocalizationSettings.AvailableLocales.GetLocale(localeCode);
LocalizationSettings.SelectedLocale = locale;
}void RegisterCallbacks() {
m_ButtonDanish.clicked += () => SelectLocale("da");
m_ButtonEnglish.clicked += () => SelectLocale("en");
m_ButtonSpanish.clicked += () => SelectLocale("es");
m_ButtonFrench.clicked += () => SelectLocale("fr");
}Теперь каждая кнопка может переключать интерфейс на указанную для неё локаль. При нажатии кнопки English, French, Spanish или Danish текст интерфейса меняется во время выполнения.
Кнопки позволяют переключать локали.
Использование SetBinding Настраивать привязки данных в UI Builder удобно и наглядно. Однако иногда привязку требуется создать скриптом во время выполнения - например, если элементы интерфейса создаются динамически или данные для привязки становятся доступны только во время игры.
элементы управления |
Чтобы настроить привязку данных в C#, вызовите метод SetBinding у визуального элемента. Ниже показано, как связать свойство text элемента Label с записью LocalizedString в StringTable:
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.UIElements;public class LocalizationDemo : MonoBehaviour {
// Set in Inspector
[SerializeField] LocalizedString m_LocalizedText;
Label m_LocalizedLabel;
UIDocument m_UIDocument;
void Start() {
m_LocalizedLabel = m_UIDocument.rootVisualElement.Q<Label>("text__label");
m_LocalizedLabel.SetBinding("text", m_LocalizedText);
}} В этой конфигурации полю m_LocalizedText через Inspector назначается запись из DemoStringTable. Код связывает свойство text элемента m_LocalizedLabel с указанным объектом LocalizedString, поэтому при смене локали текст обновляется автоматически.
Отслеживание смены локали Иногда при смене локали нужно не только обновить локализованные строки, но и выполнить дополнительные действия. Если требуется запускать определённую логику при каждом изменении локали, подпишитесь на событие SelectedLocaleChanged API LocalizationSettings.
элементы управления |
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
public class LocalizationExample: MonoBehaviour {
void OnEnable() {
LocalizationSettings.SelectedLocaleChanged += OnLocaleChanged;
}
void OnDisable() {
LocalizationSettings.SelectedLocaleChanged -= OnLocaleChanged;
}
void OnLocaleChanged(Locale newLocale) {// Perform actions when the Locale changes, like updating UI elements Debug.Log($"Locale changed to: {newLocale.Identifier.Code}");
}
}В данном случае метод OnLocaleChanged вызывается при каждой смене локали, позволяя обновить другие элементы или выполнить пользовательскую логику. С помощью этого обработчика можно корректировать свойства и стили интерфейса, особенно если переведённый текст не помещается в текущую компоновку.
Работа с таблицами строк Основная часть локализации выполняется с помощью таблиц строк (String Tables), в которых хранятся все текстовые переводы для интерфейса и меток. Откройте окно Localization Tables (Window > Asset Management > Localization Tables) и создайте или выберите коллекцию таблиц строк (String Table Collection). Здесь можно добавлять записи, задавать для них уникальные ключи и вводить перевод для каждой локали.
Импорт и экспорт строковых данных
CSV-файлы Таблицу строк можно заполнить, импортировав данные из CSV-файла (значения, разделённые запятыми), поэтому дизайнеры смогут подготовить текст во внешнем редакторе. Чтобы редактировать существующие записи в обычном текстовом формате, экспортируйте таблицу строк в CSV.
элементы управления |
Импортируйте или экспортируйте CSV-файлы.
После редактирования импортируйте файл обратно в Unity: записи автоматически обновятся по своим ключам.
Синхронизация с Google Таблицами Чтобы подключить проект к Google Таблицам, потребуется ресурс Sheets Service Provider. Он управляет аутентификацией и позволяет создавать таблицы непосредственно в редакторе. Для его создания выберите Assets > Create > Localization > Google Sheets Service. .
Создайте сервис Google Таблиц и выполните авторизацию.
элементы управления |
Сервис Google Таблиц поддерживает два способа авторизации: OAuth и API Key. Используйте OAuth, если нужен доступ к закрытым таблицам для чтения и записи. Ключ API подходит, если требуется только читать общедоступные таблицы. Для полного доступа на чтение и запись необходимо получить разрешение Google. Подробнее см. в документации Google Таблиц в разделе Authorizing Requests. Чтобы связать коллекцию таблиц строк с Google Таблицей, добавьте расширение Google Sheet в список Extensions этой коллекции. Выберите ресурс String Table, затем в Inspector нажмите кнопку Add (+) рядом с разделом Extensions. В одну коллекцию таблиц строк можно добавить несколько расширений и при необходимости назначить каждой локали отдельную таблицу. Для синхронизации таблицы строк с Google Таблицей подключите её к ресурсу Sheets Service Provider. Инструкции по созданию и настройке ресурса см. в разделе Sheets Service Provider.
Добавьте сервис Google Таблиц в список расширений StringTable.
После настройки синхронизации дизайнеры и другие участники команды, не занимающиеся разработкой, смогут редактировать записи локализации непосредственно в Google Таблицах.
элементы управления |
Использование Smart Strings Smart Strings - мощная альтернатива String.Format для создания динамических строк. Они позволяют использовать шаблоны на основе данных с поддержкой форм множественного числа, условного форматирования, списков и других языковых правил. Благодаря этому настройка локализации становится проще.
Чтобы использовать Smart String, пометьте строку как интеллектуальную в окне Localization Tables. Откройте это окно, затем в меню ( ) выберите Smart Format и убедитесь, что рядом с записью появился значок {S}. Другой способ - включить параметр Smart в редакторе Localized String в Inspector.
Включить Smart Strings можно в окне StringTable или в Inspector.
Настройка Smart String в скрипте Чтобы управлять SmartString из скрипта:
- Настройте локализованную строку с заполнителями. Smart String состоит из обычного текста и заполнителей в фигурных скобках {}, как в String.Format, но обладает более гибкими возможностями. Создайте в таблице строк запись с заполнителем, например "Welcome, {0}!". Здесь {0} будет заменён данными во время выполнения.
элементы управления |
- Используйте LocalizedString и аргументы. Создайте в скрипте объект LocalizedString для этой записи и передайте данные времени выполнения через свойство Arguments. Например, следующий фрагмент из SmartStringDemo показывает, как заменить один заполнитель:
// //Replaces placeholder with player name (e.g., "Welcome, {0}!" => "Welcome, Player One!")m_PlaceholderLabel = root.Q<Label>("welcome__label");
m_PlaceholderMessage.Arguments = new object[] { m_PlayerName };
m_PlaceholderLabel.SetBinding("text", m_PlaceholderMessage);
Этот код связывает LocalizedString со свойством text метки и во время выполнения подставляет имя игрока. Исходная запись "Welcome, {0}!" может отобразиться на экране как "Welcome, Player One!".
Принцип работы заполнителей Заполнители Smart Strings не ограничиваются простой подстановкой {0}. Они могут иметь более сложную структуру и предназначены для расширенных сценариев. Заполнитель может состоять из нескольких частей, включая:
- Селектор: определяет, какие данные использовать. Например, {player.name} выбирает свойство name объекта player. - Имя форматтера: задаёт применяемый форматтер, например plural для выбора формы числа.
- Параметры форматтера: настраивают его поведение, например задают формы единственного и множественного числа. - Формат: определяет представление результата, например преобразование числа в слово нужной формы, форматирование даты или времени либо выбор фразы в зависимости от входных данных.
Заполнитель может состоять из нескольких частей.
элементы управления |
Селекторы отличаются гибкостью и позволяют динамически получать данные во время выполнения. Они могут обращаться к свойствам и полям объектов. Например, селектор {gameObject.name} возвращает свойство name объекта GameObject, а {slider.value} свойство value ползунка.
Форматтеры преобразуют полученные данные в итоговую строку. С их помощью можно форматировать даты, время и списки, выбирать формы множественного числа и даже применять условную логику. После получения данных форматтер преобразует их в итоговый результат. У каждого форматтера есть собственные параметры и правила форматирования. В примере проекта используются два форматтера:
- Форматтер Choose: {0:choose(1|2|3):morning|afternoon|evening|anytime} выбирает значение "morning", "afternoon" или "evening" в зависимости от входных данных.
- Форматтер Plural: {0:plural:one item|{} items} выбирает форму единственного или множественного числа. Измените значения в Inspector и перейдите в режим Play, чтобы увидеть полученный текст.
Smart Strings - альтернатива String.Format.
элементы управления |
Smart Strings предоставляют ряд встроенных форматтеров, которые расширяют возможности локализации и позволяют адаптировать текст к состоянию игры или контексту:
- Форматтер Choose: применяет условную логику на основе числового значения. - Форматтер Plural: автоматически выбирает форму числа в зависимости от количества.
- Форматтер Time: отображает дату и время. - Форматтер Conditional: реализует логику, подобную if/else. - Форматтер List: форматирует массивы и списки. - Форматтер Is Match: выбирает отображаемый текст по шаблону регулярного выражения. С помощью API также можно создавать собственные форматтеры. Дополнительные сведения см. в документации по Smart Strings.
Предварительная обработка строк В некоторых случаях прямая привязка элементов интерфейса к LocalizedString неудобна. Например, перед отображением локализованного текста может потребоваться дополнительное форматирование или преобразование. В таких ситуациях LocalizedString можно предварительно обработать до вывода в интерфейсе.
GetLocalizedString Для этого подходит метод GetLocalizedString: во время выполнения он преобразует LocalizedString в обычную строку. До передачи обработанной строки в интерфейс к ней можно применить собственное форматирование - например, добавить префикс или объединить несколько строк. Пример:
[SerializeField] int m_PlayerLevel = 1;
LocalizedString m_LevelMessage = new LocalizedString("My_Table", "My_Entry");
// A property that retrieves the localized string and replaces the placeholder {0}
with the player’s level
[CreateProperty] public string LevelMessage => m_LevelMessage.GetLocalizedString(m_PlayerLevel);
В этом примере свойство LevelMessage заменяет заполнитель {0}в LocalizedString текущим уровнем игрока. Атрибут [CreateProperty] позволяет использовать это свойство в системе привязки данных во время выполнения и напрямую связывать его с элементами интерфейса. В простых случаях подобные свойства, как показанное выше LevelMessage, могут инкапсулировать логику форматирования без дополнительных обработчиков событий.
элементы управления |
Использование события StringChanged Событие StringChanged объекта LocalizedString удобно использовать для такой предварительной обработки. Оно срабатывает при каждом обновлении LocalizedString, например при смене локали, и позволяет изменить текст перед отрисовкой. Для этого подпишите обработчик на StringChanged. Следующий фрагмент создаёт объект LocalizedString из записи My_Entry таблицы My_Table:
LocalizedString localizedString = new LocalizedString ("My_Table", "My_Entry"); localizedString.StringChanged += OnLocalizedStringChanged; Обратите внимание: обработчик OnLocalizedStringChanged автоматически получает результат как обычную строку. Затем перед отображением текста к нему можно применить собственную логику:
void OnLocalizedStringChanged(string value) {
// Example: Add a prefix based on certain conditions string processedString = $"[Prefix] {value}";
// Update the UI element with the processed string m_TextLabel.text = processedString;
}Динамические элементы управления интерфейса Разумеется, предварительная обработка LocalizedString не ограничивается простыми текстовыми полями. Она особенно полезна для сложных свойств и структур интерфейса, когда одной Smart String недостаточно для требуемой логики или форматирования. Например, свойство choices элемента DropdownField содержит список строк. Предварительная обработка позволяет динамически локализовать этот список вариантов в соответствии с активной локалью.
элементы управления |
В данном случае скрипт PreprocessDemo локализует варианты DropdownField и обновляет их каждый раз, когда игрок выбирает другой язык. Логика перестроения списка снова запускается в ответ на событие StringChanged.
Предварительная обработка LocalizedString с помощью события StringChanged.
Ниже приведён фрагмент скрипта PreprocessDemo, демонстрирующий этот механизм:
[SerializeField] LocalizedString m_Choice1LocalizedString;
[SerializeField] LocalizedString m_Choice2LocalizedString;
[SerializeField] LocalizedString m_Choice3LocalizedString;
[SerializeField] LocalizedString m_Choice4LocalizedString;
public void Initialize(VisualElement root) {
m_DropdownField = root.Q<DropdownField>("dropdown__field");
m_Choice1LocalizedString.StringChanged += UpdateDropdownChoices;
m_Choice2LocalizedString.StringChanged += UpdateDropdownChoices;
// … register other choices // Initial population UpdateDropdownChoices(null);
}элементы управления |
При срабатывании события StringChanged список вариантов раскрывающегося поля перестраивается, а текущее выбранное значение сохраняется: void UpdateDropdownChoices(string value) {
// Save the current selection int selection = m_DropdownField.index;
// Remove previous choices m_DropdownField.choices.Clear();
// Add current localized values m_DropdownField.choices.Add(m_Choice1LocalizedString.GetLocalizedString());
m_DropdownField.choices.Add(m_Choice2LocalizedString.GetLocalizedString());
// … Add other choices // Restore selected index and value m_DropdownField.index = selection;
m_DropdownField.SetValueWithoutNotify(m_DropdownField.choices[selection]);
}Метод SetValueWithoutNotify обновляет отображаемое значение раскрывающегося поля, не вызывая ChangeEvent. Это предотвращает рекурсивные обновления и сохраняет выбор пользователя при изменении списка вариантов. В примере проекта DropdownField динамически обновляет свойство choices на основе значений LocalizedString. При выборе новой локали язык обновляется и в вариантах раскрывающегося списка. Таким образом, предварительная обработка служит дополнительным инструментом для создания локализованных интерфейсов, учитывающих контекст. Smart Strings решают многие задачи локализации, включая заполнители и формы множественного числа, а предварительная обработка обеспечивает дополнительную гибкость и форматирование в случаях, с которыми Smart Strings самостоятельно не справляются.
элементы управления |
Локализация ресурсов Хотя основная часть локализации связана со строками, помимо текста иногда требуется локализовать и ресурсы. Например, в демонстрационном проекте предусмотрены значки, соответствующие настроенным локалям.
Каждую локаль обозначают флаг и значок «Hello, world».
Настройка локализации ресурсов Локализация ресурсов устроена почти так же, как локализация строк. Для локализованного текста используются таблицы строк, а для локализованных ресурсов таблицы ресурсов (Asset Tables). Рабочий процесс у них схож: в таблицы добавляют записи, на которые затем ссылаются из скриптов или UXML-файлов. Локализованные ресурсы можно привязать к элементам интерфейса в UI Builder или в скрипте C#. Например, свойство style.backgroundImage визуального элемента можно связать с локализованным спрайтом или текстурой.
элементы управления |
В примере проекта: - Привязка данных одного элемента задана в UXML с помощью UI Builder. - Привязка другого элемента настроена в скрипте C#. Теперь при выборе локали во время выполнения значки обновляются вместе с текстовыми метками, наглядно показывая активную локаль.
Объекты LocalizedTexture обновляются при каждой смене локали.
элементы управления |
Таблицы ресурсов и таблицы строк Работа с таблицами ресурсов во многом повторяет работу с таблицами строк. Оба типа позволяют задавать записи для каждой локали и получать их во время выполнения. Однако между ними есть различия:
- Обработка событий: таблицы ресурсов уведомляют об изменении локализованных ресурсов событием AssetChanged, тогда как для строк используется StringChanged. - Методы привязки: и строки, и ресурсы можно привязывать методом SetBinding, но целевое свойство зависит от типа данных - например, text для строк и style.backgroundImage для текстур.
В следующем фрагменте демонстрационный код получает LocalizedTexture из таблицы ресурсов по имени, а затем привязывает её к свойству style.backgroundImage:
m_LocalizedTexture = new LocalizedTexture() {
TableReference = "DemoAssetTable", TableEntryReference = "HelloWorld_Icon"
}
;
m_IconElement = root.Q<VisualElement>("icon__hello-world");
m_IconElement.SetBinding("style.backgroundImage", m_LocalizedTexture);Распространённые локализуемые ресурсы в UI Toolkit Локализуемые ресурсы бывают разных типов. При работе с UI Toolkit чаще всего встречаются следующие: - Локализованные текстуры: идеально подходят для значков, фонов и других декоративных изображений. Их можно напрямую привязать к свойствам визуального элемента, например style.backgroundImage.
- Локализованные спрайты: встречаются реже, но полезны для пользовательских компонентов и графики на основе спрайтов. - Локализованные шрифты: позволяют переключать шрифты, чтобы поддерживать письменность или особенности типографики разных языков. - Локализованные объекты: подходят для ссылок на сложные ресурсы, например префабы или ресурсы на основе данных, которые должны меняться в зависимости от локали. Используя эти ресурсы вместе с таблицами ресурсов, можно динамически адаптировать к активной локали не только текст интерфейса, но и его визуальное оформление.
элементы управления |
Локализация в примере Dragon Crashers Демонстрационный проект UI Toolkit Sample - Dragon Crashers показывает несколько приёмов локализации в действии. На экране Settings можно выбрать один из поддерживаемых языков в раскрывающемся меню. После выбора нового языка система LocalizationSettings обнаруживает изменение и обновляет интерфейс в реальном времени.
Выберите локаль в раскрывающемся меню Language.
Самостоятельно изучая проект, обратите внимание на следующие аспекты:
- Выбор локали в SettingsScreen: экран настроек позволяет выбрать локаль из раскрывающегося меню. Интерфейс отслеживает изменения LocalizationSettings, обнаруживает выбор новой локали и обновляется в реальном времени. - Приёмы привязки данных: в интерфейсе сочетаются разные способы локализации. Статические свойства привязываются непосредственно в UI Builder и сохраняются в UXML. Для динамически заполняемых полей привязку данных выполняют скрипты во время выполнения. Метод SetBinding связывает текстовые свойства с объектами LocalizedString, поэтому интерфейс соответствует выбранной локали.
элементы управления |
- Предварительно отформатированные объекты LocalizedString в ScriptableObject: некоторые ресурсы ScriptableObject содержат заранее отформатированные свойства LocalizedString. Например, на экране Settings раскрывающиеся поля Theme и Language динамически перестраивают списки из локализованных значений, переводя доступные варианты. Другие элементы, такие как RadioButtonGroup и пользовательский SlideToggle, также предварительно обрабатывают LocalizedString с помощью события StringChanged.
Независимо от способа локализации - привязки данных в UXML или настройки из скрипта C# - интерфейс реагирует на смену локали в реальном времени. Используйте решения из демонстрационного проекта как основу для локализованных интерфейсов в собственных проектах Unity. Сочетание привязки данных и UI Toolkit позволяет создать гибкий многоязычный интерфейс для игроков со всего мира.
Дополнительные примеры локализации представлены в проекте UI Toolkit Sample - Dragon Crashers.
Localization
Localizing your UI can help your game connect with a global audience, making your application feel intuitive and familiar in any language. Unity 6 simplifies this process by directly integrating the Localization package with UI Toolkit. This integration lets you provide region-specific content for your players, no matter where they might be. Key to Unity localization is the Locale class, which represents a specific language and manages region-specific details, such as currency and number formatting. Let’s explore a simple example of how you can set up localization in UI Toolkit. With this setup, your app can dynamically adjust its content based on a selected Locale.
An example of Spanish localization in UI Toolkit Sample - Dragon Crashers
How it works Here are a few of its key features of the Localization package: —
String Localization: The LocalizedString class lets you manage strings that automatically update when switching Locales at runtime. With Smart Strings, you can add placeholders, handle plurals, and adjust for other language-specific nuances.
Asset localization: Swap textures and other assets based on the Locale, allowing you to create region-specific content beyond simple text.
Data Binding: The Localization package integrates with UI Toolkit’s runtime data binding, linking UI elements to String and Asset Tables. Changes in data, Locale, or load state trigger automatic updates.
String and Asset Table management: String and Asset Tables store key-value pairs for translating text or other assets into Locale-specific equivalents. A centralized UI interface provides a high-level overview of all localized text and assets in your project.
Locale Switching: Switch languages in real-time without restarting the application. At runtime, select a new Locale, and the UI updates immediately to reflect the change.
Remember to take advantage of UI Toolkit’s FlexBox containers and auto-sizing elements when adapting to changes in text length and formatting. This can make your UIs more responsive when supporting different languages.
Localization setup To start using Unity’s Localization package with UI Toolkit, follow these basic steps to set up localized content and bind it to UI elements in UI Builder.
Install the Localization package from the Package Manager.
Set Up Localization Settings: Install the Localization package from the Package Manager, then go to Project Settings > Localization to create and configure your Localization Settings asset, which will manage all localized assets.
Create and configure your Localization Settings in the Project Settings.
Create Locales: Define the languages and regions your project will support using the Locale Generator. This creates assets for each Locale, identified by a unique two-letter code (e.g., "en" for English, "fr" for French, "es" for Spanish, etc.). Set a default Locale to use when the application starts.
Add a Locale.
Create String and Asset Tables: Use String Tables to store text entries for each Locale. Add entries for UI text elements like labels, buttons, and dropdown options.
Create String Tables and Asset Tables.
In the Localization Tables window (Window > Asset Management > Localization Tables), add key-value pairs for each text element in the UI. Each key represents a specific text item (like a label or button), and each value is the translated text for that item in each Locale.
Store region-specific assets like images or GameObjects in Asset Tables. For instance, you might add sprites or textures for icons representing each Locale. For each key, link assets that are specific to each Locale to reflect regional or cultural preferences.
Key-value pairs represent each element to localize.
Define a UXML interface: Use UI Builder to create a UXML file with elements such as Buttons, DropdownFields, and Labels. In the demo scene, this UXML shows a few elements ready to be localized. For text fields, use an entry from a String Table. For nontext fields, such as textures, use an Asset Table.
Demo scene You can find a sample implementation of Localization in the LocalizationDemo scene included in the QuizU project. To access it, navigate at runtime to the main menu and select Demos > Localization, or load the LocalizationDemo scene directly after disabling the bootloader (Quiz > Don’t Load Bootstrap Scene on Play).
Add data bindings in the UI Builder to localized strings and assets.
Bind data to UI Elements in UI Builder: This is where the power of UI Toolkit’s runtime data binding system comes into play. In UI Builder, select the element you want to localize. Open the Inspector panel and select Add Binding in the content field (e.g., text
for Labels or backgroundImage for images).
Choose LocalizedString or other localized asset as the binding type, and link to the corresponding entry in your String or Asset Table. Add more entries to the tables as you need to localize more elements.
Use the Game View Locale drop-down to preview the localization.
To test, use the Game View Locale drop-down to preview the UI in different languages, ensuring elements display correctly in each Locale.
And that’s the basic setup! In this example, the text properties of the buttons and labels can now switch to any other configured language. To localize the entire UI, make sure every piece of text has its own entry in the String Table. The Localization package is flexible in how you organize content. Use multiple String Tables to break a larger project into more manageable sections or to categorize different entries. Then, use Asset Tables to help localize your textures and other non-text assets. After adding localization bindings in UI Builder, your UXML file incorporates the localization directly into the UI elements. This results in a code block like this, where each localized property is tied to a specific entry in your String or Asset Table:
<Bindings> <UnityEngine.Localization.LocalizedString property="text" table="GUID:6aaa262cde38a4024bc3fc7f5ce6d50d" entry="Id(104135776002048)" /> </Bindings>
This snippet of UXML establishes a data binding that links the UI element’s text property to an entry in the String or Asset Tables.
Every time you update the localization tables, the linked UI elements automatically reflect the latest localized content. Note: While UI Builder simplifies the creation of data bindings, experienced users may also edit the UXML directly for greater control over the localized content.
Using the Localizatizon API The Game View Locale drop-down in the Editor is helpful for testing different languages, but it won’t be available in a build of your application. To allow users to change languages in the final application, you’ll need to create your own UI for Locale switching.
Selecting a Locale If you have the two-letter identifier of your Locale, you can set the active Locale in the LocalizationSettings. Then, connect this action to your buttons using the clicked manipulator on each button or the RegisterCallback<ClickEvent> method.
The LocalizationDemo script in the sample project shows one implementation:
void SelectLocale(string localeCode) {Locale locale = LocalizationSettings.AvailableLocales.GetLocale(localeCode);
LocalizationSettings.SelectedLocale = locale;
}
void RegisterCallbacks() {
m_ButtonDanish.clicked += () => SelectLocale("da");
m_ButtonEnglish.clicked += () => SelectLocale("en");
m_ButtonSpanish.clicked += () => SelectLocale("es");
m_ButtonFrench.clicked += () => SelectLocale("fr");
}
Each button can then change the locale to its indicated locale. Now when you press the button named English, French, Spanish, or Danish, the text within the UI changes at runtime.The buttons can change Locales.
Using SetBinding Using the UI Builder to set up data bindings is interactive and easy. Sometimes, however, you’ll need to set up binding via a script at runtime. For example, you might create UI elements dynamically, or you might have bindings that rely on data only available during gameplay.
To set up a data binding in C#, use the SetBinding method on the visual element. Here’s how to bind the text property of a Label to a LocalizedString entry in the StringTable:
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.UIElements;public class LocalizationDemo : MonoBehaviour {
// Set in Inspector
[SerializeField] LocalizedString m_LocalizedText;
Label m_LocalizedLabel;
UIDocument m_UIDocument;
void Start() {
m_LocalizedLabel = m_UIDocument.rootVisualElement.Q<Label>("text__label");
m_LocalizedLabel.SetBinding("text", m_LocalizedText);
}} In this setup, m_LocalizedText is assigned in the Inspector to an entry in DemoStringTable. This code links the text property of m_LocalizedLabel to the specified LocalizedString, allowing it to update automatically when the Locale changes.
Listening for Locale changes In some cases, you might need to take additional actions when the Locale changes, beyond updating localized strings. Listen for the SelectedLocaleChanged event in the LocalizationSettings API if you want to execute some logic every time the Locale is updated.
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
public class LocalizationExample: MonoBehaviour {
void OnEnable() {
LocalizationSettings.SelectedLocaleChanged += OnLocaleChanged;
}
void OnDisable() {
LocalizationSettings.SelectedLocaleChanged -= OnLocaleChanged;
}
void OnLocaleChanged(Locale newLocale) {// Perform actions when the Locale changes, like updating UI elements Debug.Log($"Locale changed to: {newLocale.Identifier.Code}");
}
}
In this case, OnLocaleChanged is called each time the Locale changes, allowing you to update other elements or run custom logic. Use this event handler to adjust UI properties or styles, especially if translated text doesn’t fit well within the current layout.Working with String Tables Most of your localization work will involve String Tables, which handle all text-based translations for your UI and labels. Open the Localization Tables window (Window > Asset Management > Localization Tables) and create or select a String Table Collection. From here, you can add new entries, define unique keys, and input translations for each Locale.
Importing and exporting string data
CSV files You can populate a String Table by importing data from a CSV (comma-separated-value) file, allowing designers to set up text externally. To edit entries in plain text format, export the existing String Table as a CSV.
Import or export CSV files.
After updating the file, import it back into Unity to automatically update entries based on their keys.
Google Sheets synchronization To connect your project to the Google Sheets service, you need to use a Sheets Service Provider asset. This asset manages authentication and allows you to create new sheets directly within the Editor. To create it, navigate to Assets > Create > Localization > Google Sheets Service.
Create a Google Sheets Service and authorize.
The Google Sheets Service has two authorization options: OAuth or API Key. Use OAuth if you need to access private sheets for reading and writing. Use an API Key if you only need to read from public sheets. For full read/write access, you’ll need to request authorization from Google. For details, see the Google Sheets documentation: Authorizing Requests. To link a String Table Collection to a Google Sheet, add a Google Sheet Extension to the collection’s Extensions list. Select the String Table asset, then click the Add (+) button next to Extensions in the Inspector. You can add multiple extensions to a single String Table Collection, allowing you to assign different sheets to each Locale if needed. To sync a String Table to a Google Sheet, connect it to a Sheets Service Provider asset. See Sheets Service Provider for information on creating and configuring one.
Add the Google Sheets Service to the StringTable’s extensions.
Once set up, this synchronization allows designers or non-developers to make edits to your localization entries directly in Google Sheets.
Using Smart Strings Smart Strings are a powerful alternative to using String.Format when generating dynamic strings. They enable data-driven templates that support features like pluralization, conditional formatting, lists, and other language-specific rules. These features can simplify setting up localization. To use Smart Strings, mark a string as smart in the Localization Tables window. Open the Localization Tables window. Then, select Smart Format from the menu options (⁝). Confirm that the {S}
icon appears next to the entry. Alternatively, enable Smart Strings in the Smart field within the Localized String Editor in the Inspector.Enable Smart Strings in either the StringTable window or Inspector.
Setting up a Smart String in your script To manage a SmartString from a script: —
Set Up the Localized String with Placeholders: A Smart String consists of literal text with placeholders in {} brackets, similar to String.Format but with added flexibility. In your String Table, create an entry with placeholders, like "Welcome, {0}!". Here, {0} is a placeholder for runtime data.
// //Use a LocalizedString and Arguments: In your script, create a LocalizedString for this entry and specify the runtime data using the Arguments property. For example, this snippet from the SmartStringDemo shows how to replace a single placeholder:
Replaces placeholder with player name (e.g., "Welcome, {0}!" => "Welcome, Player One!")m_PlaceholderLabel = root.Q<Label>("welcome__label");
m_PlaceholderMessage.Arguments = new object[] { m_PlayerName };
m_PlaceholderLabel.SetBinding("text", m_PlaceholderMessage);
This binds the LocalizedString to the label’s text property and inserts the player’s name at runtime. The original entry of "Welcome, {0}!" might appear as "Welcome, Player One!" onscreen.Understanding placeholders Placeholders in Smart Strings are not limited to simple {0} substitutions. They can be more complex and are designed to handle advanced scenarios. In fact, a placeholder can consist of multiple parts, including: —
Selector: This determines which data to use (e.g., {player.name} selects the name property of a player object).
Formatter Name: This defines the formatter to apply (e.g., plural for pluralization).
Formatter Options: This customizes the formatter’s behavior (e.g., specifying singular and plural forms).
Format: This determines how the output is presented (e.g., converting a number to a plural word, formatting a date or time, or selecting a phrase based on input).
A placeholder can consist of several parts.
Selectors are flexible and can retrieve data dynamically at runtime. They can query properties or fields of objects at runtime. For example, using the selector {gameObject.name}
can retrieve the name property of a GameObject, while a selector of {slider.value}
retrieves the value property of a slider. Formatters convert the retrieved data into the final string format. Formatters allow you to format dates, times, lists, plural forms, or even apply conditional logic. After retrieving data, formatters transform it into the final output. Each formatter defines its own options and format rules. The sample project includes a couple formatters: —Choose Formatter: {0:choose(1|2|3):morning|afternoon|evening|anytime} selects "morning," "afternoon," or "evening" based on input.
Plural Formatter: {0:plural:one item|{} items} adjusts text for singular or plural forms.
Modify the values in the Inspector and enter Play mode to see the resulting text.
Smart Strings are an alternative to String.Format.
Smart Strings provide a number of built-in formatters that enhance localization, allowing you to adapt text based on game state or context: —
Choose Formatter: Allows you to apply conditional logic based on numeric input
Plural Formatter: Automatically applies pluralization rules based on quantity
Time Formatter: Displays date and time
Conditional Formatter: For if/else-like logic
List Formatter: Formats arrays or lists
Is Match Formatter: For conditional text display based on regex patterns
You can also use the API to create a custom formatter. For additional information about formatters, see the Smart String documentation.
String pre-processing In some cases, directly binding UI elements to LocalizedString may not be convenient. For example, certain elements might need additional formatting or modification before displaying the localized text. If that’s the case, you can pre-process the LocalizedString before it appears in the UI.
GetLocalizedString The GetLocalizedString method can help here; it converts the LocalizedString into a standard string at runtime. This allows you to apply custom formatting, such as adding prefixes or combining strings, before exposing the processed string to the UI. Here’s an example:
[SerializeField] int m_PlayerLevel = 1;
LocalizedString m_LevelMessage = new LocalizedString("My_Table", "My_Entry");
// A property that retrieves the localized string and replaces the placeholder {0}
with the player’s level
[CreateProperty] public string LevelMessage => m_LevelMessage.GetLocalizedString(m_PlayerLevel);
In this example, the LevelMessage property replaces the {0}
placeholder in the Localized String with the player’s current level. The [CreateProperty] attribute allows this property to be used with runtime data binding, making it easy to bind directly to UI elements. For simple use cases, you can define properties like the above LevelMessage to handle formatting logic, eliminating the need for additional event handlers.Using the StringChanged event A LocalizedString’s StringChanged event is useful for this kind of pre-processing. It triggers every time the LocalizedString updates (i.e. when the Locale changes), allowing you to modify the text before rendering it. To use it, attach a handler to the StringChanged event. Here is a code snippet that creates a new LocalizedString from the My_Table StringTable using the My_Entry entry:
LocalizedString localizedString = new LocalizedString ("My_Table", "My_Entry"); localizedString.StringChanged += OnLocalizedStringChanged; Note how the OnLocalizedStringChanged event handler handles the conversion to a standard string automatically. Then, you can apply custom logic to modify the text before displaying it: void OnLocalizedStringChanged(string value) {
// Example: Add a prefix based on certain conditions string processedString = $"[Prefix] {value}";
// Update the UI element with the processed string m_TextLabel.text = processedString;
}Dynamic UI controls Of course, pre-processing LocalizedStrings isn’t limited to basic text fields. It’s especially useful when working with complex properties or UI structures where a Smart String alone can’t handle the required logic or formatting. For example, a DropdownField has a choices property consisting of a list of strings. Preprocessing can help localize this list of options dynamically, ensuring it reflects the active Locale.
Here, the PreprocessDemo script localizes the DropdownField choices, updating them whenever the player selects a new language. Again, the logic to rebuild the list runs in response to the StringChanged event.
Pre-process a LocalizedString using the StringChanged event.
Here’s an excerpt from the PreprocessDemo script that shows how this works:
[SerializeField] LocalizedString m_Choice1LocalizedString;
[SerializeField] LocalizedString m_Choice2LocalizedString;
[SerializeField] LocalizedString m_Choice3LocalizedString;
[SerializeField] LocalizedString m_Choice4LocalizedString;
public void Initialize(VisualElement root) {
m_DropdownField = root.Q<DropdownField>("dropdown__field");
m_Choice1LocalizedString.StringChanged += UpdateDropdownChoices;
m_Choice2LocalizedString.StringChanged += UpdateDropdownChoices;
// … register other choices // Initial population UpdateDropdownChoices(null);
}When the StringChanged event triggers, the drop-down’s options are rebuilt, and the current selection is preserved: void UpdateDropdownChoices(string value) {
// Save the current selection int selection = m_DropdownField.index;
// Remove previous choices m_DropdownField.choices.Clear();
// Add current localized values m_DropdownField.choices.Add(m_Choice1LocalizedString.GetLocalizedString());
m_DropdownField.choices.Add(m_Choice2LocalizedString.GetLocalizedString());
// … Add other choices // Restore selected index and value m_DropdownField.index = selection;
m_DropdownField.SetValueWithoutNotify(m_DropdownField.choices[selection]);
}Using SetValueWithoutNotify updates the drop-down’s display without triggering a ChangeEvent. This prevents recursive updates and preserves the user’s selection when the drop-down options change. In the sample project, the DropdownField dynamically updates its choices based on LocalizedString values. Each time a new Locale is selected, the updated language propagates to the dropdown options. Pre-processing can then be an extra technique to help you create localized, context-aware UIs. While Smart Strings handle many localization tasks like placeholders and pluralization, some extra pre-processing can offer extra flexibility and formatting that Smart Strings alone can’t handle.
Localizing assets Though strings weigh heavily in localization, you may need to localize assets in addition to text. For example, the sample project includes icons to stand in for the differently configured Locales.
The flag and "Hello, world" icons represent each Locale.
Setting up asset localization Asset localization works similarly to string localization. Just as you use String Tables for localized text, you use Asset Tables for localized assets. Both tables share a similar workflow, including adding entries and referencing them in your scripts or UXML files. Localized assets can be bound to UI elements either through the UI Builder or C# scripting. For example, you can bind a visual element’s style.backgroundImage property to a localized sprite or texture.
In the sample project: —
One element has its data binding defined in UXML via the UI Builder.
Another element’s binding is set up in a C# script.
Now, when selecting a Locale at runtime, the icons update along with the text labels, providing a quick visual indicator of the active Locale.
The LocalizedTextures update with each Locale.
Asset Tables versus String Tables The process of working with Asset Tables mirrors that of String Tables. Both allow you to define entries by Locale and retrieve them at runtime. Note these differences: —
Event Handling: Asset Tables use an AssetChanged event to notify changes in localized assets instead of the StringChanged event for strings.
Binding Methods: Both string and asset bindings work with SetBinding, but the bound properties (e.g., text for strings vs. style.backgroundImage for textures) depend on the asset type.
This snippet shows how the demo example retrieves the LocalizedTexture from the Asset Table by name and then binds to the style.backgroundImage property:
m_LocalizedTexture = new LocalizedTexture() {
TableReference = "DemoAssetTable", TableEntryReference = "HelloWorld_Icon"
}
;
m_IconElement = root.Q<VisualElement>("icon__hello-world");
m_IconElement.SetBinding("style.backgroundImage", m_LocalizedTexture);Common localized assets in UI Toolkit Localized assets come in different forms. Here are a few that you might encounter when working with UI Toolkit: —
Localized textures: Ideal for icons, backgrounds, and other decorative visuals, these can be bound directly to visual element properties, such as style.backgroundImage.
Localized sprites: These are less common but useful for custom components or spritebased visuals.
Localized fonts: These allow for switching fonts to support specific scripts or typographic styles required by different languages.
Localized objects: These are useful for referencing complex resources, such as prefabs or data-driven assets, that need to vary based on the Locale.
By leveraging these assets with Asset Tables, you can ensure that your UI dynamically adapts not only its text but also its visuals to align with the active Locale.
Localization in the Dragon Crashers sample The UI Toolkit Sample – Dragon Crashers demo includes several localization techniques in action. In the Settings view, you can use the drop-down menu to select between one of the supported languages. When a new language is chosen, the LocalizationSettings system detects the change and updates the UI in real time.
Select a Locale from the Language drop-down menu.
Here are a few things you can check as you explore the project on your own: —
SettingsScreen Locale selection: The Settings screen allows users to select a Locale via a drop-down menu. This UI listens for changes in LocalizationSettings to detect new Locale selections, updating in real-time as the drop-down changes.
Data binding techniques: The UI features a combination of localization techniques. Static properties are bound directly in UI Builder and stored in the UXML. Meanwhile, dynamically populated fields rely on runtime scripts for data binding. The SetBinding method connects text properties to LocalizedString objects, ensuring the UI reflects the selected Locale.
Pre-formatted LocalizedStrings in ScriptableObjects: Some ScriptableObject assets contain pre-formatted LocalizedString properties. For example, in the Settings screen, the Theme and Language drop-down fields dynamically rebuild lists from localized values, translating the available choices. Other elements like the RadioButtonGroup and custom SlideToggle also pre-process the LocalizedStrings by handling the StringChanged event.
Regardless of the localization technique – whether data binding through UXML or C# scripting – the UI responds in real-time to Locale changes. Use the techniques in this sample project as inspiration for building localized interfaces in your own Unity projects. By combining data binding and UI Toolkit, you can create a flexible, multilingual UI that’s ready to welcome players from around the world.
Explore UI Toolkit Sample – Dragon Crashers for more examples of localization.