ローカライゼーションのCommandlet紹介
使用バージョン:UE4.24.3
はじめに
UE4のローカライゼーションダッシュボードを利用してローカライズ対応を行う場合があるかと思います。
通常はテキストの追加や編集を行った際にローカライゼーションダッシュボードからテキスト収集やpoファイルのインポート、コンパイルを行うかと思いますが、これらの操作についてはCommandlet
が用意されているため、まとめて実行することで操作を簡略化することができます。
ローカライゼーションについては下記の資料が大変参考になります。
下記のコード中に出てくるExecuteCommandlet
の実装については以下を参照ください。
準備
以下のモジュールを依存関係として追加する必要があります。
Localization
UnrealEd
GatherTextCommandlet
GatherText
というCommandlet
があり、このCommandlet
から各操作を行います。
実行する際に引数として、{ProjectDir}/config/Localization
以下に生成されるゲームターゲットのiniファイルを指定します。
この時に指定するiniファイル内の設定を元に内部で適したCommandlet
が実行されます。
iniファイル | 動作 |
---|---|
[ゲームターゲット]_Gather.ini | テキスト収集 |
[ゲームターゲット]_Import.ini | poファイルインポート |
[ゲームターゲット]_Export.ini | poファイルエクスポート |
[ゲームターゲット]_GenerateReports.ini | WordCountやStatus等のレポート生成 |
[ゲームターゲット]_Compile.ini | コンパイル |
iniファイルパスの取得
LocalizationConfigurationScript
に各iniファイルを相対パスで取得する関数があります。
しかし、取得したパスをそのままCommandlet
の引数へ渡すと、相対パスだった場合はプロジェクトもしくはエンジンのパスが付与されてしまうため、絶対パスに変換してから渡します。
テキスト収集
#include "Misc/Paths.h" #include "LocalizationModule.h" #include "LocalizationTargetTypes.h" #include "LocalizationConfigurationScript.h" #include "Commandlets/GatherTextCommandletBase.h" void GatherText(const FString& GameTargetName) { // ゲームターゲット名からLocalizationTargetを取得. ILocalizationModule& LocalizationModule = ILocalizationModule::Get(); ULocalizationTarget* LocalizationTarget = LocalizationModule.GetLocalizationTargetByName(GameTargetName, false); check(::IsValid(LocalizationTarget)); // [ゲームターゲット]_GatherText.iniの相対パスを取得. FString ConfigPath = LocalizationConfigurationScript::GetGatherTextConfigPath(LocalizationTarget); // 相対パス->絶対パス. ConfigPath = FPaths::ConvertRelativePathToFull(ConfigPath); // Commandlet実行. ExecuteCommandlet(TEXT("GatherTextCommandlet"), FString::Format(TEXT("-config=\"{0}\""), { ConfigPath })); }
poファイルインポート
#include "Misc/Paths.h" #include "LocalizationModule.h" #include "LocalizationTargetTypes.h" #include "LocalizationConfigurationScript.h" #include "Commandlets/GatherTextCommandletBase.h" void ImportPO(const FString& GameTargetName, const TOptional<FString> CultureName) { // ゲームターゲット名からLocalizationTargetを取得. ILocalizationModule& LocalizationModule = ILocalizationModule::Get(); ULocalizationTarget* LocalizationTarget = LocalizationModule.GetLocalizationTargetByName(GameTargetName, false); check(::IsValid(LocalizationTarget)); // [ゲームターゲット]_Import.iniの相対パスを取得. FString ConfigPath = LocalizationConfigurationScript::GetImportTextConfigPath(LocalizationTarget, CultureName); // 相対パス->絶対パス. ConfigPath = FPaths::ConvertRelativePathToFull(ConfigPath); // Commandlet実行. ExecuteCommandlet(TEXT("GatherTextCommandlet"), FString::Format(TEXT("-config=\"{0}\""), { ConfigPath })); }
poファイルエクスポート
#include "Misc/Paths.h" #include "LocalizationModule.h" #include "LocalizationTargetTypes.h" #include "LocalizationConfigurationScript.h" #include "Commandlets/GatherTextCommandletBase.h" void ExportPO(const FString& GameTargetName, const TOptional<FString> CultureName) { // ゲームターゲット名からLocalizationTargetを取得. ILocalizationModule& LocalizationModule = ILocalizationModule::Get(); ULocalizationTarget* LocalizationTarget = LocalizationModule.GetLocalizationTargetByName(GameTargetName, false); check(::IsValid(LocalizationTarget)); // [ゲームターゲット]_Export.iniの相対パスを取得. FString ConfigPath = LocalizationConfigurationScript::GetExportTextConfigPath(LocalizationTarget, CultureName); // 相対パス->絶対パス. ConfigPath = FPaths::ConvertRelativePathToFull(ConfigPath); // Commandlet実行. ExecuteCommandlet(TEXT("GatherTextCommandlet"), FString::Format(TEXT("-config=\"{0}\""), { ConfigPath })); }
コンパイル
#include "Misc/Paths.h" #include "LocalizationModule.h" #include "LocalizationTargetTypes.h" #include "LocalizationConfigurationScript.h" #include "Commandlets/GatherTextCommandletBase.h" void Compile(const FString& GameTargetName, const TOptional<FString> CultureName) { // ゲームターゲット名からLocalizationTargetを取得. ILocalizationModule& LocalizationModule = ILocalizationModule::Get(); ULocalizationTarget* LocalizationTarget = LocalizationModule.GetLocalizationTargetByName(GameTargetName, false); check(::IsValid(LocalizationTarget)); // [ゲームターゲット]_Compile.iniの相対パスを取得. FString ConfigPath = LocalizationConfigurationScript::GetCompileTextConfigPath(LocalizationTarget, CultureName); // 相対パス->絶対パス. ConfigPath = FPaths::ConvertRelativePathToFull(ConfigPath); // Commandlet実行. ExecuteCommandlet(TEXT("GatherTextCommandlet"), FString::Format(TEXT("-config=\"{0}\""), { ConfigPath })); }
翻訳済みテキスト数を更新してWord Count
に反映
#include "Misc/Paths.h" #include "LocalizationModule.h" #include "LocalizationTargetTypes.h" #include "LocalizationConfigurationScript.h" #include "Commandlets/GatherTextCommandletBase.h" void UpdateWordCount(const FString& GameTargetName) { // ゲームターゲット名からLocalizationTargetを取得. ILocalizationModule& LocalizationModule = ILocalizationModule::Get(); ULocalizationTarget* LocalizationTarget = LocalizationModule.GetLocalizationTargetByName(GameTargetName, false); check(::IsValid(LocalizationTarget)); // [ゲームターゲット]_GenerateReports.iniの相対パスを取得. FString ConfigPath = LocalizationConfigurationScript::GetWordCountReportConfigPath(LocalizationTarget); // 相対パス->絶対パス. ConfigPath = FPaths::ConvertRelativePathToFull(ConfigPath); // Commandlet実行. ExecuteCommandlet(TEXT("GatherTextCommandlet"), FString::Format(TEXT("-config=\"{0}\""), { ConfigPath })); // 生成したレポートを元に更新. LocalizationTarget->UpdateStatusFromConflictReport(); LocalizationTarget->UpdateWordCountsFromCSV(); }
実行例
上記の処理をまとめて呼び出す例です。
※テキスト収集の前に収集対象のStringTable
等を更新すると自動化が捗ります。
void Example(const FString& GameTargetName) { // テキスト収集. GatherText(GameTargetName); // POファイルをインポート. ImportPO(GameTargetName); // コンパイル. Compile(GameTargetName); // WordCount更新. UpdateWordCount(GameTargetName); }
おまけ
GatherText
の引数は;
区切りで複数のiniファイルを指定することができるようになっているようです。
個別に実行した場合はソースコントロールに関する処理が都度呼ばれるだけのようです。
特に問題がないようなら都合のよいやり方を選択して構わないと思います。
最後に
最初にゲームターゲットの設定をしてしまえば、それ以降の追加や更新の作業については簡略化することが可能となり確認作業がしやすくなります。
また、会社によっては自社でテキスト管理ツールを作成されているところもあるかと思います。
そういった場合にも少しの作業で連携することが可能になるのではないかと思います。