UE4で変数の値をテキストファイルとして保存する方法

やりたいこと

UE4 でブループリント変数の値をテキストファイルとして保存したい。
私の目的で言えば、アプリ実行中に得られたユーザーの行動データをテキストファイルとして保存したい、ということです(Unreal Engine 4 では SaveGame オブジェクトを使ってデータの保存ができますが、テキストファイルとしてデータを保存しておきたいのでこれは使いたくありません)。

やり方1. VictoryPlugin の SaveStringTextToFile ノードを使う
やり方2. テキストファイル保存を行うブループリント関数ライブラリ用 C++ 関数を自分で作る

1の方法が使えるならそれが簡単だと思います。私の環境だとこのプラグインがなぜかうまく有効化できなかったのでこの記事では2の方法でやることにします。結果的に下記の画像みたいな感じのノードでテキストファイルへの保存ができるようになります。

BP_Save2

動作確認した時のバージョンは UE4.12.5 で、Mac OSX 10.10.5 と Windows 10 で検証しました。

やりかた

Mac なら XCode が、Win なら Visual Studio (Community 2015とか) がインストールされている必要があります。無ければまず入れておきます。Visual Studio をインストールする際は Common Tools for Visual C++ 2015 も合わせてインストールする必要があることに注意してください(参考記事)。

新規にプロジェクトを作成する場合は C++ テンプレートを選んでプロジェクトの新規作成を行います。既存のプロジェクトで、C++プロジェクトではなくブループリントプロジェクトとして作成されたプロジェクト(エディタのビルドボタンの右隣にコンパイルボタンが出現していない場合)に追加したい場合は、プロジェクトファイル(拡張子が .uproject となっているファイル)があるフォルダの中に Source という名前のフォルダをまず作成します。次にC++ プロジェクトを作成します。プロジェクトファイルを右クリックすると、Win の場合はメニューの中に Generate Visual Studio project files というのがあるのでそれをクリックします。Mac の場合はメニューの下部にサービスという項目があるのでその中にある Generate Xcode Project を選びます。

レベルエディタのメニューから「ファイル File」> 「新規C++クラス New C++ Class」を選びます。親クラスは Actor にします。ファイル名は SaveToText とします。公開設定はパブリックを選んでおきます。クラス作成ボタンを押すとしばらくのコンパイル時間の後にヘッダファイルと cpp ファイルが作成され、VS なり Xcode なりが開きます。

C++ のエディタが開いていない場合はコンテンツブラウザの C++ クラス(C++ Classes)フォルダ内にある SaveToText のファイルをダブルクリックします。そして、SaveToText.hと SaveToText.cpp を下記のように書き換えます。

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "SaveToText.generated.h"

/**
 * 
 */
UCLASS()
class プロジェクト名_API ASaveToText : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
    public:

    UFUNCTION(BlueprintCallable, Category = "save")
    static bool FileSaveString(FString SaveTextB, FString FileNameB);
    
    UFUNCTION(BlueprintPure, Category = "save")
    static bool FileLoadString(FString FileNameA, FString& SaveTextA);
    
    UFUNCTION(BlueprintCallable, Category = "save")
    static FString FileLoadAndReturnString(FString FileNameA);
};

クラス名の行(この場合だと10行目)など自動生成されている行は書き換えずにおきます。なので実際には public: の行以下の部分を追加するだけでOKです。

// Fill out your copyright notice in the Description page of Project Settings.
#include "empty.h"
#include "SaveToText.h"

// Load and save text files
bool ASaveToText::FileSaveString(FString SaveTextB, FString FileNameB)
{
    return FFileHelper::SaveStringToFile(SaveTextB, *(FPaths::GameDir() + FileNameB));
}

bool ASaveToText::FileLoadString(FString FileNameA, FString& SaveTextA)
{
    return FFileHelper::LoadFileToString(SaveTextA, *(FPaths::GameDir() + FileNameA));
}

FString ASaveToText::FileLoadAndReturnString(FString FileNameA)
{
    FString myString;
    bool myBool = true;
    myBool = FFileHelper::LoadFileToString(myString, *(FPaths::GameDir() + FileNameA));
    return myString;
}

cpp ファイルも上記のように編集します。以上のコードは https://answers.unrealengine.com/questions/174839/loading-text-to-a-string.html で紹介されているものです(保存以外にもテキストファイルの読み込み関数があります)。ちなみに、クラス名は ASaveToText と先頭に A が付いていますが、これが U であったりする場合もあります。その場合は cpp ファイルの中でクラス名が付いている箇所もそれに合わせるようにしてください。コンパイル時にエラーが出た時はヘッダと cpp ファイルでクラス名が一致していないことが原因だと思われます。

.h と .cpp ファイルを保存したら、UE4 のエディタ上でコンパイルボタン(ビルドボタンの右にある)を押します。コンパイルが成功したら作ったこの関数をブループリントで使えるようになります。

レベルブループリントなどを開いて記事冒頭のようなノードを組みます。そしてゲームを実行すれば、プロジェクトフォルダ内にテキストファイルが保存されています。やりました!

以下は、配列を保存する例です。response と RT という整数配列および float 配列があり、それをコンマで接続して csv 形式で保存したいとします。output は配列長ゼロの文字列配列で、保存処理のために一時的に使うための変数です。response と RT の要素をコンマでつなげてペアにし output の各要素として For ループで追加して行き、完了したら Join String Array ノードで全ての要素をつなげて単一の文字列にします。ただ、テキストファイルに保存された時に要素番号ごとに改行して保存したいので(配列長が10ならデータごとに改行された10行のテキストファイルにしたい)、Format Text ノードを使って改行コードを入れるようにします(Format Text ノードの LB (Line Break の略)入力には「Shift + 改行」を入力しています)。

BP_SaveArray

コメント