Skip to main content

Полное руководство по локализации Unreal Engine

От макросов FText до цепочек резервных локалей: локализуйте игру UE5 с помощью Localization Dashboard, String Tables, C++, Blueprints и автоматического перевода.

1

FText и конвейер локализации

FText — строковый тип Unreal Engine, учитывающий локализацию. Каждая обращённая к пользователю строка игры — названия элементов интерфейса, диалоги, подсказки и уведомления — должна использовать FText, чтобы участвовать в конвейере локализации. FString предназначен только для внутренней логики.

LOCTEXT требует два аргумента: ключ и исходную строку. Ключ должен быть уникальным в своём пространстве имён. Средство сбора текста UE использует ключи для отслеживания переводов в разных культурах. NSLOCTEXT позволяет явно указать пространство имён, а LOCTEXT использует определённое окружающим макросом LOCTEXT_NAMESPACE.
FText Basics
// FText is UE's localization-aware string type.
// ALWAYS use FText for user-facing text, never FString.

// LOCTEXT: localize a literal string (most common)
FText Title = LOCTEXT("MainMenuTitle", "Start Game");

// NSLOCTEXT: specify namespace explicitly
FText Msg = NSLOCTEXT("UI", "WelcomeMessage", "Welcome, adventurer!");

// INVTEXT: invariant text (never translated — debug/logging only)
FText Debug = INVTEXT("Debug overlay active");

// FText::Format: safe variable interpolation
FText Greeting = FText::Format(
    LOCTEXT("PlayerGreeting", "Hello, {PlayerName}!"),
    FText::FromString(PlayerName)
);
MainMenuWidget.cpp
// In a UMG Widget (C++)
void UMainMenuWidget::NativeConstruct()
{
    Super::NativeConstruct();

    // Bind localized text to UI elements
    if (TitleLabel)
    {
        TitleLabel->SetText(LOCTEXT("GameTitle", "My Epic Game"));
    }

    if (PlayButton)
    {
        PlayButton->SetText(LOCTEXT("PlayButtonLabel", "Play Now"));
    }
}

// IMPORTANT: Always use LOCTEXT for UMG widget text.
// Setting text via FString bypasses the localization pipeline.
Никогда не создавайте обращённый к пользователю текст с помощью FString::Printf или объединения строк. Они полностью обходят конвейер локализации: такой текст невозможно собрать, перевести или правильно отобразить в языках RTL. Всегда используйте FText::Format с шаблонами LOCTEXT.
2

Настроить Localization Dashboard

Localization Dashboard — встроенный инструмент UE для управления переводами. Он собирает все строки LOCTEXT и NSLOCTEXT из исходного кода, экспортирует их в файлы .po для перевода и компилирует результаты в двоичные файлы .locres, которые UE загружает во время выполнения.

Localization Dashboard Workflow
# 1. Open the Localization Dashboard:
#    Window > Localization Dashboard

# 2. Add a localization target (e.g., "Game")

# 3. Add cultures:
#    Click "Add New Culture" > select languages (de, ja, fr, es, ko, zh-Hans...)

# 4. Gather text:
#    Click "Gather Text" — UE scans all LOCTEXT/NSLOCTEXT macros

# 5. Export translations:
#    Click "Export" to generate .po files for each culture

# 6. Import translations:
#    After translating .po files, click "Import"

# 7. Compile translations:
#    Click "Compile" to generate .locres binary files

# 8. Preview:
#    Editor Preferences > Region & Language > Preview Game Language
Запускайте 'Gather Text' после каждого изменения кода, добавляющего или изменяющего макросы LOCTEXT. Иначе новые строки не появятся в файлах .po и переводчики их не увидят. Добавьте этап сбора в автоматизацию сборки.
3

Использовать String Tables для текста на основе данных

String Tables позволяют определять локализованные строки в централизованном ресурсе вместо распределения макросов LOCTEXT по исходным файлам. Они идеально подходят для текста интерфейса, диалогов и любых строк, которые дизайнерам или авторам нужно редактировать без изменения кода. String Tables можно определить как ресурсы UE или импортировать из CSV.

StringTableUsage.cpp
// StringTables provide a data-driven approach to localization.
// Define strings in a CSV asset instead of scattering LOCTEXT across code.

// 1. Create a String Table asset:
//    Content Browser > Right-click > Miscellaneous > String Table

// 2. Or define via CSV (importable into UE):
// Key,SourceString
// MainMenu_Title,Start Game
// MainMenu_Continue,Continue
// MainMenu_Settings,Settings
// MainMenu_Quit,Quit to Desktop
// HUD_Health,Health
// HUD_Ammo,Ammo: {0}
// Dialog_Merchant_Greeting,Welcome to my shop!

// 3. Reference in C++:
FText Title = FText::FromStringTable(
    FName(TEXT("/Game/Localization/ST_MainMenu")),
    TEXT("MainMenu_Title")
);

// 4. Reference in Blueprints:
//    Use the "Make Text from String Table" node
//    Set Table ID and Key
String Tables автоматически собираются Localization Dashboard. Для определённых в String Table строк макросы LOCTEXT не нужны: ссылайтесь на них по идентификатору таблицы и ключу в C++ или Blueprints.
4

Шаблоны локализации C++

В C++ определяйте LOCTEXT_NAMESPACE в начале каждого файла .cpp и используйте LOCTEXT для всех обращённых к пользователю строк. Для динамического содержимого с переменными применяйте FText::Format. Всегда отменяйте определение пространства имён в конце файла, чтобы предотвратить утечки.

MainMenuWidget.cpp
// Define a namespace at the top of each .cpp file
// All LOCTEXT calls in this file use this namespace
#define LOCTEXT_NAMESPACE "MyGame.MainMenu"

#include "MainMenuWidget.h"

void UMainMenuWidget::NativeConstruct()
{
    Super::NativeConstruct();

    // These use the "MyGame.MainMenu" namespace automatically
    TitleText->SetText(LOCTEXT("Title", "Main Menu"));
    PlayText->SetText(LOCTEXT("PlayButton", "Play"));
    SettingsText->SetText(LOCTEXT("SettingsButton", "Settings"));
    QuitText->SetText(LOCTEXT("QuitButton", "Quit"));
}

// CRITICAL: Always undefine at the end of the file
#undef LOCTEXT_NAMESPACE
FText::Format Examples
// FText::Format — the safe way to build localized strings
// NEVER use FString::Printf or string concatenation for user-facing text.

// Named arguments (recommended)
FText ItemPickup = FText::Format(
    LOCTEXT("ItemPickup", "You picked up {ItemName} x{Count}"),
    FText::FromString(ItemName),
    FText::AsNumber(Count)
);

// FText::AsNumber respects locale formatting:
//   English: 1,234,567
//   German:  1.234.567
//   French:  1 234 567

// FText::AsCurrency for prices:
FText Price = FText::AsCurrency(
    9.99,
    TEXT("USD"),
    &FInternationalization::Get().GetCurrentCulture().Get()
);

// FText::AsDate and FText::AsTime for dates:
FText DateStr = FText::AsDate(FDateTime::Now());
Аргументы FText::Format также должны быть FText, а не исходными FString. Используйте FText::FromString() для преобразования значений FString, FText::AsNumber() для форматирования чисел с учётом локали и FText::AsCurrency() для цен. Объединение исходных FString создаёт текст, не соблюдающий правила форматирования локали.
5

Локализация Blueprint

Все свойства Text в Blueprints по умолчанию имеют тип FText, поэтому уже готовы к локализации. Задайте Key и Namespace на панели сведений о свойстве, чтобы строки можно было собирать. Для динамического содержимого с переменными используйте узел Format Text.

Blueprint Localization Patterns
// Blueprint Localization Basics:
//
// 1. All Text properties in Blueprints are FText by default
//    (already localization-ready)
//
// 2. Set the Text property in the Details panel
//    Expand the dropdown to set:
//    - Key: unique identifier for translation
//    - Namespace: grouping for organization
//    - Source String: the text to display/translate
//
// 3. For dynamic text, use the "Format Text" node:
//    Format: "Hello, {PlayerName}!"
//    Connect a "Find" pin named "PlayerName" to your variable
//
// 4. For plurals, use "Text Format with Arguments":
//    Pattern: "{Count}|plural(one=item,other=items)"
//
// 5. Culture switching at runtime:
//    Use "Set Current Culture" node
//    Input: culture code string (e.g., "de", "ja", "fr")
Разверните раскрывающийся список текстового свойства на панели Blueprint Details, чтобы увидеть поля Key, Namespace и Source String. Смысловой Key значительно упрощает переводчикам определение строк в файле .po.
6

Обработать формы множественного числа и род

Unreal Engine поддерживает формат сообщений ICU для множественного числа и текста, зависящего от рода. Определите правила множественного числа в исходных строках, и UE автоматически выберет правильную форму по правилам CLDR активной культуры.

ICU Plural & Gender Rules
// UE uses ICU message format for plurals.
// Define plural rules in your .po or String Table:

// English source:
// "{Count}|plural(one=You have # item,other=You have # items)"

// German translation:
// "{Count}|plural(one=Du hast # Gegenstand,other=Du hast # Gegenstaende)"

// Arabic translation (6 forms):
// "{Count}|plural(zero=لا عناصر,one=عنصر واحد,two=عنصران,few=# عناصر,many=# عنصرًا,other=# عنصر)"

// Japanese (1 form):
// "{Count}|plural(other=アイテム#個)"

// In C++:
FText ItemCount = FText::Format(
    LOCTEXT("ItemCount",
        "{Count}|plural(one=You have {Count} item,other=You have {Count} items)"),
    ItemCount
);

// Gender-dependent text:
// "{Gender}|gender(masculine=Il est,feminine=Elle est) prêt{Gender}|gender(masculine=,feminine=e)"
Никогда не задавайте count == 1 жёстко для определения единственного числа. Во французском 0 считается единственным числом. В русском есть отдельные формы few и many. В арабском 6 форм. Поручите логику правилам ICU: определите все нужные формы, и UE выберет правильную для культуры.
7

Упаковать и протестировать локализацию

Перед выпуском убедитесь, что для всех целевых культур есть скомпилированные файлы .locres, а текст правильно отрисовывается во время выполнения. Используйте предварительный просмотр культуры в редакторе, переопределения культуры из командной строки и автоматические проверки для выявления отсутствующих или нарушенных переводов.

Packaging & Testing Workflow
# Compile and test localization before packaging:

# 1. Editor Preferences > Region & Language > Preview Game Language
#    Set to each target language and verify all text renders correctly.

# 2. Command-line culture override for testing:
MyGame.exe -culture=ja

# 3. Packaging settings:
#    Project Settings > Packaging > Localizations to Package
#    Select all cultures you want to include in the build.

# 4. Verify .locres files exist after packaging:
MyGame/Content/Localization/Game/
├── en/
│   └── Game.locres
├── de/
│   └── Game.locres
├── ja/
│   └── Game.locres
├── fr/
│   └── Game.locres
└── ko/
    └── Game.locres

# 5. Runtime culture switching:
#    FInternationalization::Get().SetCurrentCulture(TEXT("ja"));
#    This reloads all FText strings from the new culture's .locres files.
Если культура не указана в Project Settings > Packaging > Localizations to Package, её файлы .locres исключаются из сборки. Игроки, выбравшие этот язык во время выполнения, увидят резервный текст или пустые строки. Всегда проверяйте соответствие параметров упаковки поддерживаемым культурам.
8

Добавить цепочки резервных локалей

Стандартная локализация Unreal Engine переходит только по иерархии подтегов IETF. Пользователь pt-BR при отсутствии перевода получает английский вместо подходящего pt-PT. locale-chain-ue добавляет настраиваемые боковые цепочки через FTextLocalizationManager, чтобы региональные пользователи всегда видели ближайший доступный перевод.

locale-chain-ue (C++)
// locale-chain-ue: Smart fallback chains for UE5
// Problem: UE falls back to default when a locale is missing.
// pt-BR user gets English instead of pt-PT translations.

// Solution: One function call at startup.
#include "LocaleChain.h"

void UMyGameInstance::Init()
{
    Super::Init();
    ULocaleChain::Configure();  // Load 75 built-in fallback chains
}

// Now resolve strings with per-key fallback:
FString Greeting = ULocaleChain::Resolve(
    TEXT("greeting"), TEXT("MyNamespace")
);
// pt-BR user: tries pt-BR -> pt-PT -> pt -> default

// Custom overrides:
TMap<FString, FString> Overrides;
Overrides.Add(TEXT("pt-BR"), TEXT("pt"));       // Simplify chain
Overrides.Add(TEXT("sv-FI"), TEXT("sv"));        // Add new chain
ULocaleChain::ConfigureWithOverrides(Overrides);

// Full control (C++ only):
TMap<FString, TArray<FString>> Custom;
Custom.Add(TEXT("pt-BR"), {TEXT("pt-PT"), TEXT("pt")});
Custom.Add(TEXT("es-MX"), {TEXT("es-419"), TEXT("es")});
ULocaleChain::ConfigureCustom(Custom, false);
Один раз при запуске вызовите ULocaleChain::Configure(), чтобы загрузить 75 встроенных цепочек для 11 языковых семейств. Для удобной настройки в Blueprint используйте ConfigureWithOverrides, а для полного управления в C++ — ConfigureCustom.

Автоматизировать контроль качества перевода

Выявляйте отсутствующие ключи и нарушенные заполнители до выпуска с помощью i18n-validate. Тестируйте интерфейс с псевдопереводами через i18n-pseudo, пока настоящие переводы ещё не готовы.

Распространённые ошибки

Использование FString для обращённого к пользователю текста

FString полностью обходит конвейер локализации. Текст, созданный через FString::Printf или объединение строк, невозможно собрать, перевести или правильно отобразить в языках RTL. Всегда применяйте FText с макросами LOCTEXT и FText::Format для видимых пользователю строк.

Отсутствует #undef LOCTEXT_NAMESPACE

Если забыть #undef LOCTEXT_NAMESPACE в конце файла .cpp, пространство имён перейдёт в последующие единицы перевода. Это без уведомления назначает неверные пространства имён строкам в других файлах, и переводы появляются в неправильном контексте.

Жёстко заданная логика множественного числа

Запись 'count == 1 ? singular : plural' игнорирует правила CLDR. Во французском 0 считается единственным числом, в русском 4 формы множественного числа, в арабском — 6. Используйте синтаксис ICU в шаблонах FText и поручите UE обработку правил каждой культуры.

Забыли скомпилировать после импорта

Импорт файлов .po обновляет текстовые данные, но не создаёт двоичные файлы .locres. Во время выполнения игра всё ещё загружает старые скомпилированные переводы. После импорта всегда запускайте 'Compile' в Localization Dashboard или добавьте его в автоматизацию сборки.

Рекомендуемая структура проекта

Project Structure
MyUnrealProject/
├── Config/
│   └── Localization/
│       └── Game.ini                  # Localization target config
├── Content/
│   └── Localization/
│       ├── Game/
│       │   ├── Game.manifest         # Gather manifest
│       │   ├── en/
│       │   │   ├── Game.po           # Source strings (.po)
│       │   │   └── Game.locres       # Compiled binary
│       │   ├── de/
│       │   │   ├── Game.po
│       │   │   └── Game.locres
│       │   ├── ja/
│       │   │   ├── Game.po
│       │   │   └── Game.locres
│       │   └── fr/
│       │       ├── Game.po
│       │       └── Game.locres
│       └── StringTables/
│           ├── ST_MainMenu.uasset    # String Table asset
│           └── ST_HUD.uasset
├── Plugins/
│   └── LocaleChain/                  # locale-chain-ue plugin
│       ├── LocaleChain.uplugin
│       └── Source/
│           └── LocaleChain/
├── Source/
│   └── MyGame/
│       ├── UI/
│       │   ├── MainMenuWidget.h
│       │   └── MainMenuWidget.cpp    # LOCTEXT macros here
│       └── MyGameInstance.cpp        # ULocaleChain::Configure()
└── MyUnrealProject.uproject

Попробовать i18n Agent

Перетащите сюда файл перевода

JSON, YAML, PO, XML, CSV, Markdown, Properties

или нажмите, чтобы выбрать

Целевые языки

Регистрация не требуетсяМгновенный расчёт

Часто задаваемые вопросы