Skip to main content

Unreal Engine 本地化完整指南

從 FText 宏到地區設定回退鏈:使用 Localization Dashboard、String Table、C++、Blueprint 和自動化翻譯本地化 UE5 遊戲。

1

FText 與本地化管線

FText 是 Unreal Engine 可識別本地化的字串類型。遊戲中每個面向用戶的字串(UI 標籤、對話、工具提示、通知)都必須使用 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 語言中正確顯示。請始終改用帶 LOCTEXT 模式的 FText::Format。
2

設定 Localization Dashboard

Localization Dashboard 是 UE 內置的翻譯管理工具。它從源程式碼中收集所有 LOCTEXT 和 NSLOCTEXT 字串,將其匯出為 .po 檔案供翻譯,再將結果編譯為 UE 在執行階段載入的 .locres 二進制檔案。

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
每次程式碼更改新增或修改 LOCTEXT 宏後,都應執行 'Gather Text'。漏掉此步驟意味着新字串不會出現在 .po 檔案中,譯者也看不到它們。將收集步驟新增到構建自動化,以自動發現此問題。
3

使用 String Table 管理數據驅動文字

String Table 讓你在集中式資源中定義本地化字串,而不是將 LOCTEXT 宏分散在來源檔案中。它們非常適合 UI 文字、對話,以及設計師或文案人員需要在不接觸程式碼的情況下編輯的任何字串。String Table 可定義為 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
Localization Dashboard 會自動收集 String Table。對於在 String Table 中定義的字串,無需使用 LOCTEXT 宏,只需在 C++ 或 Blueprint 中通過表 ID 和鍵引用。
4

C++ 本地化模式

在 C++ 中,於每個 .cpp 檔案頂部定義 LOCTEXT_NAMESPACE,並對所有面向用戶的字串使用 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 本地化

Blueprint 中的所有 Text 屬性預設都是 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(),載入涵蓋 11 個語系的 75 條內置回退鏈。使用 ConfigureWithOverrides 進行便於 Blueprint 使用的自訂,或在 C++ 中使用 ConfigureCustom 完全控制回退行為。

自動保證翻譯質素

使用 i18n-validate 在發佈前發現缺失鍵和損壞的預留位置。真實譯文完成前,可使用 i18n-pseudo 產生偽譯文來測試 UI。

常見問題

對面向用戶的文字使用 FString

FString 會繞過整個本地化管線。使用 FString::Printf 或字串串聯構建的文字無法被收集、翻譯,也無法在 RTL 語言中正確顯示。請始終對用戶可見字串使用帶 LOCTEXT 宏和 FText::Format 的 FText。

缺少 #undef LOCTEXT_NAMESPACE

忘記在 .cpp 檔案末尾使用 #undef LOCTEXT_NAMESPACE,會導致命名空間洩漏到後續翻譯單元。這會在無提示的情況下為其他檔案中的字串分配錯誤命名空間,使翻譯出現在錯誤上下文中。

硬編碼複數邏輯

編寫 'count == 1 ? singular : plural' 會忽略 CLDR 規則。法語將 0 視為單數,俄語有 4 種複數形式,阿拉伯語有 6 種。請在 FText 模式中使用 ICU 複數語法,讓 UE 按區域性處理規則。

匯入後忘記編譯

匯入 .po 檔案會更新文字數據,但不會產生 .locres 二進制檔案。遊戲在執行階段仍會載入舊的已編譯翻譯。匯入後請始終在 Localization Dashboard 中執行 '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

或點擊選擇檔案

目標語言

無需註冊即時估價

常見問題