BLOGブログ

2025.09.24UE5UE/ C++その他

[UE5]UnrealEngineのローカライズデータを独自データに変更してみる

執筆バージョン: Unreal Engine 5.6

今回はローカライズに関する話題です。

UnrealEngineの標準的なローカライズの仕組みを利用するためには、ローカライゼーションダッシュボードが必須になってきます。
ですが、微妙に使い勝手が合わないケースがあり、外部ツールを使ってPOファイルでやり取りすることも可能ですが、
私個人の範囲での話ですが、翻訳データの管理はエクセルしか使ったことがありません。(他のプロジェクトではどうか分かりませんが…)

UnrealEngineの仕組みを活かしつつ、エクセルなどの一般的なツールで管理できないかとドキュメントを調べてみたところ…
実現できそうな方法が見つかりました。

参考:テキスト ローカライゼーション
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/text-localization-in-unreal-engine C++ の多言語データ
C++ を用いた多言語データは FPolyglotTextData 型によって表され、(FPolyglotTextData::GetText を使用して多言語データをテキスト インスタンスとして解釈して) 直接の使用や FTextLocalizationManager::RegisterPolyglotTextData に転送 (既存のテキスト エントリをパッチ処理するため) することも可能です。

つまり、FTextLocalizationManager::RegisterPolyglotTextData関数を使えば、
UnrealEngineの仕組みを活かし、独自のデータで管理できるローカライズシステムが作れます。
今回はこの方法で、独自ローカライズデータの構築に挑戦します。

ローカライゼーションダッシュボードを利用したローカライズ

まずは、標準のローカライゼーションダッシュボードを使ったローカライズ手順をおさらいします。
UnrealEngineのローカライズ思想としては、以下の2つを想定しているようです。

「author-at-source」アプローチ(ソース直書き方式)
テキストをソースコードやプロパティに直接記述し、そのままローカライズの対象とする方式です。
C++やBlueprintに書かれた文字列をローカライズ収集ツールが自動的にそのテキストを検出し、ローカライズ対象として扱います。
この方式のメリットは、開発者がローカライズを意識せずに開発を進められる点です。
一方で、プロジェクト全体のテキストを厳密に管理したい場合には向いていません。

「author-once-and-reference」アプローチ(1か所で定義して参照する方式)
テキストを一元管理するStringTableを利用し、必要な場所でそのStringTableを参照する方式です。
これにより、テキストの管理や修正が容易になり、大規模なプロジェクトや複数人での開発に適しています。

UnrealEngineの内部的な処理としては、StringTableも「author-at-source」アプローチと同じ仕組みでテキストを検出し、ローカライズ対象にしています。「author-once-and-reference」アプローチでも同じ仕組みで管理できるようになっています。

参考:公式ドキュメント「ローカライゼーションの概要」ローカライゼーション パイプライン
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/localization-overview-for-unreal-engine

 

ローカライゼーションダッシュボードを使った、ローカライズの主な手順は以下の通りです。

  1. ローカライゼーションダッシュボードで翻訳対象を収集
  2. 収集した文字列を翻訳
  3. 翻訳データをコンパイル

簡単に図に表すとこのような感じになります。

独自ローカライズシステム案

今回実装するローカライズの仕組みは以下の内容を想定して実装します。

  • 一か所で管理しやすいStringTableを利用した「author-once-and-reference」アプローチを採用
  • UnrealEngineのローカライズの仕組みを利用
     ・ FText型を利用する
     ・SetCurrentCulture等の関数で言語が切り替わる
  • 元のデータはエクセルで出力できるもの (実際データとして扱うのはCSV形式)
  • ランタイム時にCSVファイルを直接読むのは、ユーザーが簡単に書き換えられてしまうリスクがあるため、データアセット化して管理
  • データアセットをロードしたタイミングで、Engine側にStringTableとFPolyglotTextData(ローカライズテキスト情報)を登録
  • 表示テキストの指定はStringTableを使用し、Keyで指定
  • ローカライゼーションダッシュボードは使わない
  •  

図に表すとこのようになります。

実装

再利用しやすいようにプラグイン化してみました。

このプラグインはGitHubで公開しています。
https://github.com/historia-Inc/LocalizeSystem

処理は大きく分けると以下の通りです。

  • ローカライズテキストデータアセットクラス
  • 起動時のローカライズテキストデータアセットロード処理

ローカライズテキストデータアセットクラス(ULocalizeTextData)

このクラスでは以下の処理を行います。

  • CSVファイルをファイルダイアログボックから選択しインポート
  • ローカライズテキストのアセットデータ管理
  • アセットのロード完了時(PostLoad)に、変更を確認し再インポートを行い、エンジン側にStringTableとローカライズテキストを登録します。
ソースコードはここをクリック

StringTable関連処理

StringTableの情報はFStringTableRegistry::Get()でFStringTableRegistryクラスのインスタンスを取得し、エンジン側に登録します。
StringTableアセットを作成せずにFText型から直接参照できるようになります。

FStringTableRegistryクラス

StringTable作成

void Internal_NewLocTable(const FName InTableId, const FString& InNamespace);

引数
InTableId : StringTableの識別用Id
InNamespace : ローカライズテキストのNamespace(FPolyglotTextDataのNamespaceと一致させる必要があります)

StringTableへkeyとテキストの登録

void Internal_SetLocTableEntry(const FName InTableId, const FString& InKey, const FString& InSourceString);

引数
InTableId : 登録するテキストのStringTableのTableId
InKey : 登録するテキストのKey
InSourceString : 登録するテキスト

ローカライズテキストの登録処理

FPolyglotTextData構造体配列をFTextLocalizationManagerのRegisterPolyglotTextData関数を利用して登録します。

TArray<FPolyglotTextData> RegistLocalizeData; FTextLocalizationManager::Get().RegisterPolyglotTextData(RegistLocalizeData);

FPolyglotTextData構造体

コンストラクタ関数

FPolyglotTextData(const ELocalizedTextSourceCategory& InCategory, const FString& InNamespace, const FString& InKey, const FString& InNativeString, const FString& InNativeCulture)

引数
InCategory : ローカライズカテゴリ(Game,Engine,Editor)
InNamespace : 翻訳するNamespace(StringTableのNamespace名を指定します。)
InKey : 翻訳するKey(StringTableで指定したKeyをここで指定します。)
InNativeString : デフォルト時の文字列
InNativeCulture : デフォルト時の言語地域

ネイティブ言語設定

void SetNativeCulture(const FString& InNativeCulture)

引数
InNativeString : デフォルト時の言語地域

ネイティブ言語文字列設定

void SetNativeString(const FString& InNativeString)

引数
InNativeString : デフォルト時の文字列

各言語の文字列設定

void AddLocalizedString(const FString& InCulture, const FString& InLocalizedString)

引数
InNativeCulture : 設定する言語地域 InNativeString : 翻訳された文字列

起動時のアセットのロード

ローカライズテキストデータアセットのPreLoad時にエンジン側へ登録しているので、アセットをロードするだけでローカライズされたテキストが使えます。
LocalizeTextDataアセットをロードするために、AssetManagerの未初期化の場合もあり、適切なタイミングでロードするために、以下の処理を実装しております。 これらを満たすために、以下の処理を実装しています。

  • AssetManagerの初期化完了後にデリゲートで呼び出し関数を設定
  • LocalizeTextDataアセットのPrimaryAssetTypesが未登録のケースを考え、C++でScanPathForPrimaryAssets関数を利用しPrimaryAssetTypesを登録
ソースコードはここをクリック

テキスト登録の流れ

1. コンテントブラウザで右クリック →[Miscellaneous]→[Data Asset]を選択

2. DataAssetのクラスの指定ダイアログでLocalizeTextDataを選択

3. アセット名を設定(StringTableの名前になります)

4. アセットを開いてImportCsvボタンを押す

         

5. ファイル選択ダイアログが開くのでローカライズテキストのCSVファイルを選択

CSVのフォーマット
一番左の列がStringTableのKeyとなり、他の各列が各言語ごとの翻訳データとなります。
各言語の列名はUnreaEngineが対応している言語名を指定してください。(2 文字の ISO 639-1 言語コード (「zh」など))

 

言語切替方法

PIE(Play In Editor)開始時の言語設定

[Editor Preferences]画面の[General]→[Region and Language] から、 [Preview Game Language] の横にあるドロップダウンリストから言語を選択します。
PIE実行時に指定した言語でテキストが表示されます。

 

UMGエディタ上での言語設定

UMGエディタには各言語のプレビューを行う機能があります。
確認しながらUIのデザインをすることができます。

SetCurrentCulture関数での切り替え(スタンドアローン起動・ランタイム起動時のみ)

スタンドアローン起動・ランタイム起動時のみになりますが、実行中の言語はSetCurrentCulture関数で変更できます。

このとき「key」を指定するとkeyとStringTableの名前がテキストとして表示されます。(どのテキストを指定しているか確認できます。)

注意点として、プレビューの機能はSetCurrentCulture関数で切り替える設定とは別に言語やロケール設定をUnrealEngineが管理しているため、
PIEでは確認できないようになっています。

参考:公式ドキュメント「実行時にアクティブ カルチャを管理する」 ローカライゼーション プレビュー
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/managing-the-active-culture-at-runtime PIE および UMG のプレビューは、言語やロケール設定に影響を与えずにローカライゼーション データのみをロードするため、実行時のプロジェクトの外観を正確に表示できるとは限りません。 正確な表示が必要な場合は、エディタでスタンドアロン インスタンスを実行します (これは、-game でエディタを実行するのと同じです)。

もし、PIE実行中で言語切り替える確認の頻度が多いのであれば、LocalizeTextDataアセットのCategoryを 「Engine」に変更すると、
SetCurrentCulture関数での変更を確認することができます。

ただし、「PIE開始時の言語設定」と「UMGエディタ上での言語設定」で紹介した言語設定が使用できなくなるので注意してください。

SetCurrentCulture関数でエディタの言語が変更される問題の対処

PIE実行時にSetCurrentCulture関数を使用するとエディタ側のテキストが変わってしまいます。 一度変更するとエディタの言語が変わったままのため、PIE終了時に自動で元の言語に戻してあげると便利です。 FEditorDelegatesのEndPIEデリゲートを利用し、PIE終了時に元の言語へ戻す処理を呼び出せます。

まとめ

StringTableとFPolyglotTextDataをUnrealEngine側に定義を渡すだけなので、処理も簡易なものになっています。
今回は簡単に利用できるCSVにしましたが、Googleのスプレッドシートで管理をして、Google Apps Script (GAS) でスプレッドシートからデータを取得したり、プロジェクトDBを用意して、ローカライゼーションダッシュボードを利用せずにローカライズの管理ができそうです。