Skip to main content

Повний посібник із локалізації Unreal Engine

Від макросів FText до ланцюжків резервних локалей: локалізуйте свою гру на UE5 за допомогою панелі керування локалізацією, таблиць рядків, C++, Blueprint та автоматизованого перекладу.

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 або конкатенації рядків. Вони повністю оминають процес локалізації, тому отриманий текст неможливо зібрати, перекласти чи правильно відобразити мовами з письмом справа наліво. Натомість завжди використовуйте FText::Format із шаблонами LOCTEXT.
2

Налаштування панелі керування локалізацією

Панель керування локалізацією — вбудований інструмент 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

Використання таблиць рядків для тексту на основі даних

Таблиці рядків дають змогу визначати локалізовані рядки в централізованому ресурсі замість розміщення макросів LOCTEXT у різних вихідних файлах. Вони ідеально підходять для тексту інтерфейсу, діалогів та будь-яких рядків, які дизайнери чи автори мають редагувати без змін у коді. Таблиці рядків можна створювати як ресурси 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
Панель керування локалізацією автоматично збирає таблиці рядків. Для рядків, визначених у таблиці рядків, макроси LOCTEXT не потрібні — просто звертайтеся до них за ідентифікатором таблиці та ключем у C++ або Blueprint.
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 у Blueprint за замовчуванням мають тип 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. Змістовний ключ значно полегшує перекладачам пошук і розпізнавання рядків у файлі .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 або конкатенації рядків, неможливо зібрати, перекласти чи правильно відобразити мовами з письмом справа наліво. Для видимих користувачу рядків завжди використовуйте 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» на панелі керування локалізацією або додайте цей етап до автоматизації складання.

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

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

або натисніть, щоб вибрати

Цільові мови

Реєстрація не потрібнаМиттєвий розрахунок

Поширені запитання