LoginSignup
4
2

More than 3 years have passed since last update.

UE4 StringTableについてのメモ(Commandletでのインポートエクスポート)

Posted at

概要

UnrealEngineでのStringTableについてのメモ書きと、コマンドレットを使ってcsvファイルからのインポートとcsvファイルへのエクスポートコード例です。

環境

Windows10
Visual Studio 2017
UnrealEngine 4.25

参考

以下を参考にさせて頂きました、ありがとうございます。

UE4公式 : UCommandlet
UE4公式 : Commandlets
UE4公式 : 文字列テーブル
[UE4] String Tableの紹介

関連ソース

"Engine\Source\Runtime\Engine\Classes\Commandlets\Commandlet.h"

ストリングテーブルについて

ローカライズ用アセットとして使うことができる文字列テーブルです。KeySourceStringが設定でき、Keyに紐づいたSourceStringを表示することによってアセット切り替え(言語切り替え)を行っても表示側の処理を変えずに表示文字列を切り替えることができます。

StringTable.jpg

データの追加はストリングテーブルエディタの下部にて追加もできますが、CSVファイルでのインポートなどもできます。

BPノード例

GetStringTableEntrySourceString

GetStringTableEntrySourceStringはストリングテーブルに登録されている文字列を取得できます。Table Idにストリングテーブルのアセットのパス Keyにキーを指定します。

GetStringTableEntrySourceString.jpg

IsStringTableEntryRegistered

IsStringTableEntryRegisteredはストリングテーブルに指定のキーが登録されているかを調べるノードです。Table Idにストリングテーブルのアセットのパス Keyにキーを指定します。

IsStringTableEntryRegistered.jpg

C++コード例

上記BPをC++で書くと以下の様になります。
ストリングテーブルアセットは別途どこかでロードする必要があります。

コードサンプル
#include "Kismet/KismetStringTableLibrary.h"

FString _String = UKismetStringTableLibrary::GetTableEntrySourceString(FName("/Game/StringTable/ST_Test.ST_Test"), FString(TEXT("StringKey01")) );

bool _IsRegist = UKismetStringTableLibrary::IsRegisteredTableEntry(FName("/Game/StringTable/ST_Test.ST_Test"), FString(TEXT("StringKey99")) );

関連エンジンソース

"Engine\Source\Runtime\Engine\Classes\Kismet\KismetStringTableLibrary.h"

コマンドレットでの操作

コマンドレットでインポート/エクスポートが可能です。

インポート

Test.csv というCSVファイルから ストリングテーブル ST_Test へインポートする処理です。

インポート処理
// アセットデータ
FAssetData _AssetData  = AssetRegistry.GetAssetByObjectPath(TEXT("/Game/StringTable/ST_Test.ST_Test"));
// ストリングテーブル
UStringTable* _StringTable = Cast<UStringTable>(_AssetData.GetAsset());

// インポート元のcsv
FString _OutFiles = FString(TEXT("../../../app/Content/Localization/Test.csv"));

_StringTable->Modify();
bool _Ret = _StringTable->GetMutableStringTable()->ImportStrings(_OutFiles);

エクスポート

ストリングテーブルST_TestからCSVファイルTest.csvへエクスポートする処理です。

エクスポート処理
// アセットデータ
FAssetData _AssetData  = AssetRegistry.GetAssetByObjectPath(TEXT("/Game/StringTable/ST_Test.ST_Test"));
// ストリングテーブル
UStringTable* _StringTable = Cast<UStringTable>(_AssetData.GetAsset());

// エクスポート先のcsv
FString _OutFiles = FString(TEXT("../../../app/Content/Localization/Test.csv"));

_StringTable->GetStringTable()->ExportStrings(_OutFiles);

クラス例

コマンドレットクラスは以下の様になります。
コード例では入出力ファイルが直値になっているので実際に使用する際はコマンドラインのオプション等で指定できると良いかと思います。(変換が面倒ですが:sweat_smile:

StringTableProcCommandlet.h
#pragma once

#include "CoreMinimal.h"
#include "Commandlets/Commandlet.h"
#include "StringTableProcCommandlet.generated.h"

class UStringTable;

// ストリングテーブル処理コマンドレットクラス
UCLASS()
class UStringTableProcCommandlet : public UCommandlet
{
    GENERATED_BODY()


public:
    UStringTableProcCommandlet(const FObjectInitializer& ObjectInitializer);

    virtual int32 Main(const FString& CmdLineParams) override;

};
StringTableProcCommandlet.cpp
#include "StringTableProcCommandlet.h"
#include "AssetRegistry/Public/AssetData.h"             
#include "AssetRegistry/Public/AssetRegistryModule.h"
#include "AssetRegistry/Public/AssetRegistryHelpers.h"
#include "CoreUObject/Public/UObject/ConstructorHelpers.h"
#include "Internationalization/StringTable.h"
#include "Internationalization/StringTableCore.h"
#include "Internationalization/StringTableCoreFwd.h"

DEFINE_LOG_CATEGORY_STATIC(LogTextSTProcCommandlet, Log, All);

UStringTableProcCommandlet::UStringTableProcCommandlet(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
    LogToConsole = true;
}

int32 UStringTableProcCommandlet::Main(const FString& CmdLineParams)
{
    FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(FName("AssetRegistry"));
    IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();

    TArray<UPackage*>   _PackagesToSave;
    bool                _IsImport = false;
    bool                _IsExport = false;

    // CSVファイルパス
    const TArray<const TCHAR*> _ImportCsvFiles = {
        TEXT("../../../app/Content/Localization/ST_Test1.csv"),
    };
    const TArray<const TCHAR*> _ExportCsvFiles = {
        TEXT("../../../app/Content/Localization/ST_Test2.csv"),
    };

    // アセットデータ
    FAssetData _AssetData  = AssetRegistry.GetAssetByObjectPath(TEXT("/Game/StringTable/ST_Test.ST_Test"));

    // ストリングテーブル
    UStringTable* _StringTable = Cast<UStringTable>(_AssetData.GetAsset());
    // アセットデータチェック
    if (!_AssetData.IsValid() || _StringTable == nullptr) {
        UE_LOG(LogTextSTProcCommandlet, Display, TEXT("File Not Found."));
        return(1);
    }


    TArray<FString> Tokens;
    TArray<FString> Switches;
    ParseCommandLine(*CmdLineParams, Tokens, Switches);

    // オプションチェック
    for(const auto& _It : Switches){
        if( _It.Equals(TEXT("import"), ESearchCase::CaseSensitive)){
            _IsImport = true;
        }else
        if( _It.Equals(TEXT("export"), ESearchCase::CaseSensitive)){
            _IsExport = true;
        }
    }
    if( !_IsImport && !_IsExport){
        UE_LOG(LogTextSTProcCommandlet, Display, TEXT("NotFound SwitchOption(-Import or -Export)"));
        return(0);
    }


    //---------------------
    // インポート処理
    if(_IsImport){
        _StringTable->Modify();
        bool _Ret = _StringTable->GetMutableStringTable()->ImportStrings(_ImportCsvFiles[0]);

        _PackagesToSave.Add(_AssetData.GetPackage());
    }

    // アセットセーブ
    for (const auto& _It : _PackagesToSave) {
        // 保存ファイル名
        const auto _FileName = FString::Printf(TEXT("../../../app/Content/StringTable/ST_Test.uasset"));

        // パッケージ保存
        UPackage::SavePackage(_It, nullptr, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *_FileName);
    }


    //---------------------
    // エクスポート処理
    if(_IsExport){
        _StringTable->GetStringTable()->ExportStrings(_ExportCsvFiles[0]);
    }


    return(0);

}

実行コマンドは以下の様になります(引数で分岐しているだけですのでエクスポートもほぼ一緒です)。
オプションでファイル名等を指定できるようにすればより扱いやすくなるかと思います。

コマンド例
# インポート
> {エンジンパス}\Binaries\Win64\UE4Editor-Cmd.exe {プロジェクトパス}\MyProject.uproject -run=StringTableProc -import

まとめ

ローカライズ文字列をストリングテーブルを使って管理する際に、コマンドレットでのインポートを使うと捗ると思います。特にローカライゼーションダッシュボードを使ったローカライズ処理ではストリングテーブル使用が必須の様です。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2