Таблицы локализации
Одна таблица хранит текст вашей игры на всех языках: строки — это ключи, столбцы — это языки. Таблица локализации — это обычная таблица SheetForge во всём, что имеет значение: она импортируется, проверяется, экспортируется, отправляется и проходит round-trip точно так же, как таблица данных, — а когда установлен пакет Unity Localization (com.unity.localization), каждый завершённый импорт также заполняет из неё собственные коллекции StringTable пакета. Ваша среда выполнения затем использует обычные ссылки LocalizedString, пока таблица остаётся единственным источником истины.
Эта страница посвящена тексту вашей игры. Интерфейс продукта на 10 языках — отдельная тема, см. Локализация.
Форма таблицы (@loc)
Таблица становится таблицей локализации, неся строку-маркер @loc. Как и @overlap и @style, она может стоять где угодно над данными; её ячейка в каждом столбце называет код языка этого столбца:
@loc | | en | ko | |
@name | codeName | en | ko | smart | comment
@type | RecordId | string? | string? | bool? | string?
@desc | key | source text | Korean | |
| ui.ok | OK | 확인 | false | Confirm button
| ui.cancel | Cancel | 취소 | |- Ключевой столбец
RecordIdобязателен — значение ключа каждой строки (ui.ok) и есть ключ локализации, а имя вкладки — это имя коллекции StringTable: одна вкладка = одна коллекция. - Языковой столбец — это строковый столбец, чья ячейка
@locнесёт код (en,ko,pt-BR— любая метка, похожая на идентификатор; SheetForge проверяет форму написания, а не существование самого кода, и два столбца, коды которых отличаются только регистром, отклоняются). Пишите их какstring?: тогда непереведённая ячейка — это пробел в покрытии, а не ошибка импорта — см. Покрытие ниже. - Первый языковой столбец — это исходный язык. Именно его текст показывает предпросмотром ячейка-ссылка в таблице данных и именно его записывает автоматическая чеканка.
- Два зарезервированных необязательных столбца, сопоставляемых по имени:
smart(булево значение — помечает запись как Smart String Unity Localization) иcomment(строка — синхронизируется в метаданные комментария записи). Если они присутствуют, таблица является истиной для этих данных; если отсутствуют, мост оставляет соответствующие метаданные StringTable нетронутыми. Зарезервированный столбец не может одновременно нести код языка. - Требуется хотя бы один код языка, и таблица не может быть одновременно таблицей enum и таблицей локализации (
@enum+@loc— это ошибка конфликта, сообщаемая один раз).
Всё остальное — обычная таблица: подготовка изменений и Ctrl+Z, правка структуры, группировка по @style, round-trip через xlsx и Google, отправка и веб-приложение — всё это обращается с ней как с обычной таблицей. Меняется результат: вкладка локализации не выдаёт ни сгенерированного класса записи, ни ScriptableObject базы данных, ни адреса Addressables. Вместо этого она питает две вещи — константы ключей и мост.
Ссылки на текст из таблиц данных (LocRef@Tab)
Таблица данных указывает на запись локализации столбцом-ссылкой LocRef:
@name | codeName | displayName
@type | RecordId | LocRef@Strings
@desc | unique key | shown in UI
| item.sword | item.sword.nameLocRef@Strings ведёт себя точно так же, как уже знакомые вам встроенные ссылки (RecordId@Tab):
- Проверяется на целостность при импорте — ключ, которого нет во вкладке
Strings, — это структурированная ошибка с предложением ближайшего совпадения; опечатка умирает при импорте, а не во время выполнения. Цель должна быть таблицей локализации (иначеLocRefTargetNotLocalizationSheet), аLocRefбез@Targetотклоняется с предложением правильного написания. - Полный набор возможностей ссылок — пикер ключей с поиском, распространение переименования ключа (переименование ключа переписывает каждую ссылающуюся ячейку в том же пакете правок), рёбра графа на холсте записи, экспортированные правила выпадающих списков и обнаружение сирот — всё это работает и в редакторе, и в веб-приложении.
- Составляется как любая ссылка — работают и
List<LocRef@Strings>, и необязательная формаLocRef@Strings?(пустая ячейка — это пустая ссылка). - Ячейка показывает текст, а не только ключ. Ячейка
LocRefпоказывает предпросмотром текст записи на исходном языке прямо в ячейке, так что таблица, полная ключей, всё равно читается как предложения. Холст записей делает то же самое — строки ссылок несут исходный текст рядом с ключом, а обрезанное значение всегда хранит полный текст в подсказке. - Ввод текста в пустую ячейку чеканит запись. Введите исходный текст в пустую ячейку
LocRef, и SheetForge подготовит, как один жест и один шаг отмены: новый ключ в целевой таблице локализации (предложенный на основе имён записи и поля — переименуйте его свободно позже, распространение сохранит каждую ссылку в целости), введённый вами текст как значение на исходном языке, и саму ссылку в ячейке, в которую вы вводили текст. Оба хоста.
Что попадает в ваш код
Генерация кода выводит поле как LocRef — простую сериализуемую структуру (целевая таблица и ключ), которая живёт в сборке рантайма SheetForge и компилируется независимо от того, установлен ли пакет Unity Localization; сгенерированный код и запечённые ScriptableObject никогда не содержат тип из пакета. При установленном пакете один вызов-расширение перекидывает мост к нему:
var text = definition.displayName.ToLocalizedString(); // UnityEngine.Localization.LocalizedStringToLocalizedString() существует только тогда, когда пакет присутствует (версийный define SHEETFORGE_LOCALIZATION включает слой расширений — тот же механизм, что использует SHEETFORGE_ADDRESSABLES). Без пакета поле всё равно остаётся корректно оформленной парой таблица/ключ, которую вы можете использовать сами.
Что генерирует импорт
Наряду с обычными результатами импорт записывает один файл SheetForgeLocalizationKeys.cs на весь проект — статический класс на каждую вкладку локализации (StringsKeys, …), содержащий один public const string на каждый ключ, так что игровой код может написать StringsKeys.ui_ok вместо голой строки "ui.ok" и получить безопасность на этапе компиляции плюс автодополнение в IDE.
- Имена членов — это ключи, очищенные до идентификаторов C# (символы вне ASCII-букв, цифр и
_превращаются в_; коллизии получают детерминированный числовой суффикс). Держите ключи в ASCII, если хотите получить пригодные для использования константы — полностью не-ASCII ключ очищается в кашу из подчёркиваний. - Как и файл enum, определённый таблицей, файл констант — это результат уровня проекта и всегда генерируется в папку сгенерированного кода из настроек — применимо то же замечание о сборке, что и в разделе о enum.
- Вкладка локализации без строк сохраняет пустой класс, так что очистка таблицы не ломает код, ссылающийся на этот тип.
Мост Unity Localization
При установленном пакете SheetForge поддерживает одну коллекцию StringTable на вкладку локализации — ключи, значения и данные smart/comment, когда эти столбцы существуют.
- Когда он запускается: автоматически, в момент завершения импорта — на том же положении, что и экспорт с отправкой как выходы, — плюс ручное действие повторной синхронизации для запуска по требованию.
- Направление: однонаправленное, таблица → StringTable. Таблица канонична; StringTable — это результат.
- Языки: язык таблицы, для которого в проекте нет соответствующего ассета
Locale, создаётся автоматически и называется в отчёте. Язык, существующий только в проекте, остаётся нетронутым и сообщается как не покрытый таблицей. - Переименования ключей сохраняют ссылки сцен живыми. Переименование ключа в Data Studio проходит через ту же машинерию переименования, что использует любая ссылка, и мост переименовывает запись StringTable на месте, сохраняя её внутренний id —
LocalizedStringв сцене или префабе привязывается к этому id, так что переживает переименование. Честная граница: переименование, сделанное вне Studio — прямое редактирование источника таблицы в Google Таблицах или Excel, — неотличимо от удаления одного ключа и добавления другого. Мост создаст новую запись (новый id) и будет считать старую сиротой; ссылки сцен на старую запись продолжат указывать на сироту. Переименовывайте ключи в Studio. - Метаданные, которые таблица не моделирует, всегда сохраняются. Комментарии (когда нет столбца
comment), флаги исключения и любые другие метаданные StringTable проходят через каждую синхронизацию нетронутыми.
О внешних правках спрашивают, но никогда не сливают их молча
Мост помечает таблицы, которыми владеет, и запоминает отпечаток последней синхронизации. Если StringTable изменилась с тех пор — кто-то отредактировал её в окне Localization Tables, или подтянул в неё данные собственным расширением Google Sheets от Unity, — следующая синхронизация останавливается и спрашивает: перезаписать из таблицы или прервать с отчётом о различиях. Здесь нет ни тихого слияния, ни тихой перезаписи. Если вам нужен рабочий процесс с двумя интерфейсами записи, направьте другой интерфейс через таблицу вместо этого — именно для этого существует экспорт для перевода.
Ключи-сироты по умолчанию сохраняются
Ключ, который существует в StringTable, но которого больше нет в таблице, — это сирота: он сохраняется, перечисляется в отчёте о сиротах и удаляется только через явное действие очистки (все сразу или по одному). Переключатель в настройках меняет поведение на удалять при синхронизации, если вы хотите, чтобы StringTable в точности зеркалила таблицу. Ничего никогда не удаляется как побочный эффект.
Без пакета
Пакет Unity Localization необязателен. Без него:
- Таблицы локализации остаются полноценными таблицами — авторинг, проверка, покрытие, экспорт, отправка, xlsx, веб-приложение, константы ключей и поля
LocRefработают в полном объёме. - Единственное, что ждёт, — это выход синхронизации StringTable, который показывает уведомление об установке (один раз за сессию) и останавливается — тот же паттерн подсказки, что и у Addressables, и точно так же никогда не устанавливается программно.
- Каждая сборка и каждая строка сгенерированного кода компилируются без пакета. Поддерживаемая версия пакета: 1.5 или новее.
Перенос существующих таблиц в лист
Уже используете Unity Localization? Обратный импортёр превращает существующую коллекцию StringTable в таблицу локализации, записывая её прямо в ваш источник импорта и импортируя автоматически — тем же путём, каким идёт создание таблицы. Проверяйте и правьте её потом, как любую другую таблицу. Если в активный источник нельзя записать из редактора, файл ложится рядом с результатом вашего экспорта, а к нему прилагается указание перенести его. Когда мост позже синхронизирует эту таблицу обратно в ту же коллекцию, id записей наследуются по совпадению имени ключа — существующие ссылки LocalizedString в сценах и префабах переживают перенос без повреждений.
Рабочие процессы перевода
Покрытие: непереведённые ячейки сообщаются, а не отклоняются
Пустая языковая ячейка — не ошибка: импорт сообщает покрытие по каждому языку (сколько ключей перевёл каждый язык и каких не хватает), и каждый выход остаётся открытым. Текст поступает постепенно; таблица никогда не блокируется из-за незавершённого перевода.
Языковая линза
Работаете с одним языком за раз? Языковая линза переключает, какие языковые столбцы видны. Это метаданные отображения из семейства @style — они никогда не затрагивают отпечаток импорта, генерацию кода или какой-либо результат. Оба хоста.
Экспорт для перевода и частичный повторный импорт
Чтобы передать язык переводчику, экспортируйте книгу переводов: выберите языки и получите xlsx из ключа + исходного текста + комментария + столбца статуса, где запись, чей исходный текст изменился с последнего экспорта, помечается как устаревшая. Когда файл вернётся, повторно импортируйте его как частичное слияние: строки сопоставляются по ключу, и записываются только языковые столбцы — структура, другие языки и всё остальное в таблице остаются нетронутыми. Оба хоста. Одна честная асимметрия: память статуса живёт в машинно-локальном файле рядом с проектом Unity, поэтому книга, экспортированная из браузера, в столбце статуса всегда говорит new; предупреждение «перевод по устаревшему исходному тексту» при повторном импорте сравнивает с исходным текстом, который несёт сам файл, поэтому оно работает в обоих хостах.
XLIFF и псевдоязыки
SheetForge намеренно не реализует заново XLIFF или псевдолокализацию — таблицы, которые заполняет мост, являются обычными таблицами Unity Localization, поэтому собственные экспорт/импорт XLIFF пакета и инструменты псевдоязыков работают на них так же, как в любом проекте. Тем не менее помните об однонаправленной авторитетности: результат, который эти инструменты записывают в таблицы, считается внешней правкой, о которой спросит следующая синхронизация. Чтобы держать переводы в источнике истины, возвращайте их через таблицу (книгу переводов выше), а не прямо в таблицы.
Две связанные границы, честно названные: мост охватывает только строковые таблицы — таблицы ассетов остаются признанным пунктом бэклога, — а SheetForge не поставляет языкоспецифичных помощников Smart Format (например, выбор корейских грамматических частиц). Столбец smart помечает записи как Smart Strings; форматтеры сверх того, что предоставляет пакет, вам предстоит написать самостоятельно через собственные точки расширения пакета.
В веб-приложении
Таблица локализации в браузере — это обычная таблица: авторинг, проверка, покрытие, пикер LocRef с исходным текстом прямо в ячейке, чеканка, языковая линза и книга переводов — всё это работает на web.sheetforge.workers.dev. Синхронизация StringTable — задача редактора Unity — у браузера нет проекта Unity, в который можно было бы записывать таблицы, и он этого не изображает.
Похожие страницы
- Синтаксис таблиц — маркер
@locиLocRefв справочнике по нотации - Локализация — собственные 10 языков интерфейса продукта
- Data Studio — окно авторинга, где происходят чеканка и переименования
- SheetForge Web — браузерный компаньон
- Возможности и ограничения — границы таблиц локализации в честном списке