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. Не са Ви необходими макроси LOCTEXT за низовете, определени в String Table — просто се обръщайте към тях чрез идентификатора на таблицата и ключа в 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 като единствено число. Руският има отделни форми за „малко“ и „много“. Арабският има 6 форми за множествено число. Оставете правилата за множествено число на ICU да управляват логиката — определете всички необходими форми и UE ще избере правилната за всяка култура.
7

Пакетирайте и тествайте локализацията

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

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 езикови семейства. Използвайте ConfigureWithOverrides за удобно персонализиране чрез Blueprint или ConfigureCustom в C++ за пълен контрол върху резервното търсене.

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

Откривайте липсващи ключове и повредени заместители преди публикуването чрез 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

или натиснете, за да изберете файл

Целеви езици

Не се изисква регистрацияНезабавна оценка

Често задавани въпроси