Skip to main content

Ang Kumpletong Gabay sa Unreal Engine Localization

Mula sa FText macro hanggang sa locale fallback chain: i-localize ang inyong UE5 game gamit ang Localization Dashboard, String Tables, C++, Blueprints, at automated translation.

1

FText at ang Localization Pipeline

Ang FText ang localization-aware na string type ng Unreal Engine. Kailangang gumamit ng FText ang bawat user-facing na string sa inyong laro — mga UI label, dialog, tooltip, notification — para makasali sa localization pipeline. Para lamang sa internal logic ang FString.

Nangangailangan ang LOCTEXT ng dalawang argumento: isang key at isang source string. Kailangang natatangi ang key sa loob ng namespace nito. Ginagamit ng text gatherer ng UE ang mga key na ito para masubaybayan ang mga pagsasalin sa iba’t ibang culture. Pinapahintulutan kayo ng NSLOCTEXT na tukuyin ang namespace nang hayagan; ginagamit ng LOCTEXT ang namespace na itinakda ng nakapaligid na LOCTEXT_NAMESPACE macro.
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.
Huwag kailanman bumuo ng user-facing na text gamit ang FString::Printf o string concatenation. Ganap nitong bina-bypass ang localization pipeline — hindi mako-kolekta, maisasalin, o maipapakita nang tama ang resultang text sa mga RTL language. Sa halip, palaging gamitin ang FText::Format na may mga LOCTEXT pattern.
2

I-set Up ang Localization Dashboard

Ang Localization Dashboard ang built-in na tool ng UE para sa pamamahala ng mga pagsasalin. Kinokolekta nito ang lahat ng LOCTEXT at NSLOCTEXT string mula sa inyong source code, ine-export ang mga ito bilang .po file para sa pagsasalin, at kino-compile ang resulta sa mga .locres binary file na nilo-load ng UE sa runtime.

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
Patakbuhin ang 'Gather Text' pagkatapos ng bawat pagbabago sa code na nagdaragdag o nagbabago ng mga LOCTEXT macro. Kapag nalaktawan ninyo ito, hindi lalabas ang mga bagong string sa inyong .po file at hindi ito makikita ng mga tagasalin. Magdagdag ng gather step sa inyong build automation para awtomatiko itong mahuli.
3

Gumamit ng String Tables para sa Data-Driven Text

Pinapahintulutan kayo ng String Tables na magtakda ng mga localized string sa isang centralized na asset sa halip na ikalat ang mga LOCTEXT macro sa mga source file. Mainam ito para sa UI text, dialog, at anumang string na kailangang i-edit ng mga designer o writer nang hindi humahawak ng code. Maaaring idefine ang String Tables bilang UE asset o i-import mula sa 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
Awtomatikong gina-gather ng Localization Dashboard ang String Tables. Hindi ninyo kailangan ang mga LOCTEXT macro para sa mga string na tinukoy sa isang String Table — i-reference lang ang mga ito sa pamamagitan ng table ID at key sa C++ o Blueprints.
4

Mga Pattern sa C++ Localization

Sa C++, magdeklara ng LOCTEXT_NAMESPACE sa itaas ng bawat .cpp file at gamitin ang LOCTEXT para sa lahat ng user-facing na string. Gamitin ang FText::Format para sa dynamic content na may mga variable. Laging i-#undef ang namespace sa dulo ng file upang maiwasan ang mga leak.

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());
Dapat FText din ang mga argumento ng FText::Format, hindi raw FString. Gamitin ang FText::FromString() upang i-convert ang mga value ng FString, FText::AsNumber() para sa locale-aware na pag-format ng numero, at FText::AsCurrency() para sa mga presyo. Ang raw FString concatenation ay lumilikha ng text na hindi sumusunod sa mga tuntunin ng locale formatting.
5

Lokalisasyon ng Blueprint

Lahat ng Text property sa Blueprints ay FText bilang default, kaya localization-ready na ang mga ito. I-set ang Key at Namespace sa property details panel upang maging gatherable ang mga string. Gamitin ang Format Text node para sa dynamic content na may mga variable.

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")
Palawakin ang text property dropdown sa Blueprint Details panel upang makita ang mga field na Key, Namespace, at Source String. Ang pag-set ng makahulugang Key ay mas nagpapadali para sa mga tagasalin na matukoy ang mga string sa .po file.
6

Pangasiwaan ang Plurals at Gender

Sinusuportahan ng Unreal Engine ang ICU message format para sa plurals at text na nakadepende sa gender. I-define ang mga plural rule sa inyong source string at awtomatikong pipiliin ng UE ang tamang anyo batay sa mga CLDR rule ng aktibong culture.

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)"
Huwag kailanman i-hardcode ang count == 1 para sa pagtukoy ng singular. Itinuturing ng French na singular ang 0. May hiwalay na mga anyo ang Russian para sa 'few' at 'many'. May 6 na plural form ang Arabic. Hayaan ang ICU plural rules na humawak ng logic — i-define ang lahat ng kinakailangang anyo at pipiliin ng UE ang tama ayon sa bawat culture.
7

I-package at Subukan ang Lokalizasyon

Bago mag-ship, tiyakin na ang lahat ng target culture ay may compiled na .locres file at na tama ang pag-render ng text sa runtime. Gamitin ang culture preview ng Editor, command-line culture overrides, at automated checks upang matukoy ang mga nawawala o sira na pagsasalin.

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.
Kapag hindi nakalista ang isang culture sa Project Settings > Packaging > Localizations to Package, hindi isasama sa build ang mga .locres file nito. Makakakita ang mga player na pumipili ng wikang iyon sa runtime ng fallback text o mga walang laman na string. Palaging tiyaking tumutugma ang inyong packaging settings sa mga sinusuportahan ninyong culture.
8

Magdagdag ng Locale Fallback Chains

Ang default localization ng Unreal Engine ay nagfa-fallback lamang ayon sa IETF subtag hierarchy. Kapag kulang ang pagsasalin ng isang pt-BR user, English ang makikita niya sa halip na ang maayos na pt-PT translation. Nagdaragdag ang locale-chain-ue ng configurable lateral fallback chains sa pamamagitan ng FTextLocalizationManager upang ang mga user sa rehiyon ay laging makakita ng pinakamalapit na available na pagsasalin.

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);
Tawagin ang ULocaleChain::Configure() nang isang beses sa startup upang i-load ang 75 built-in fallback chains na sumasaklaw sa 11 language family. Gamitin ang ConfigureWithOverrides para sa Blueprint-friendly na customization, o ConfigureCustom sa C++ para sa ganap na kontrol sa fallback behavior.

I-automate ang Kalidad ng Pagsasalin

Matukoy ang mga nawawalang key at sirang placeholder bago mag-ship gamit ang i18n-validate. Subukan ang inyong UI gamit ang pseudo-translations sa i18n-pseudo bago dumating ang mga tunay na pagsasalin.

Mga Karaniwang Pagkakamali

Paggamit ng FString para sa Text na Nakikita ng User

Binabypass ng FString ang buong localization pipeline. Ang text na binuo gamit ang FString::Printf o string concatenation ay hindi mako-kolekta, maisasalin, o maipapakita nang tama sa mga RTL language. Palaging gumamit ng FText na may LOCTEXT macros at FText::Format para sa mga string na nakikita ng user.

Nawawalang #undef LOCTEXT_NAMESPACE

Ang pagkalimot na i-#undef ang LOCTEXT_NAMESPACE sa dulo ng isang .cpp file ay nagdudulot na lumusot ang namespace papunta sa mga kasunod na translation unit. Tahimik nitong ina-assign ang maling namespace sa mga string sa ibang file, kaya lumalabas ang mga pagsasalin sa maling konteksto.

Hardcoded na Plural Logic

Ang pagsulat ng 'count == 1 ? singular : plural' ay binabalewala ang mga CLDR rule. Itinuturing ng French na singular ang 0, may 4 na plural form ang Russian, at may 6 ang Arabic. Gamitin ang ICU plural syntax sa inyong FText pattern at hayaan ang UE na pangasiwaan ang mga rule ayon sa bawat culture.

Nakalimutang Mag-compile Pagkatapos ng Import

Ang pag-import ng mga .po file ay nag-a-update ng text data ngunit hindi gumagawa ng mga .locres binary. Patuloy na nilo-load ng laro ang lumang compiled translations sa runtime. Palaging patakbuhin ang 'Compile' sa Localization Dashboard pagkatapos mag-import, o idagdag ito sa inyong build automation.

Inirerekomendang Istruktura ng Proyekto

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

Subukan ang i18n Agent Ngayon

I-drop dito ang inyong translation file

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

o i-click para mag-browse

Mga target language

Hindi kailangan ang signupInstant na estimate

Mga Madalas Itanong