Blog

[UE4]C++不要!便利なBlueprintのNodeを追加する「Victory Plugin」でRuntimeでのCSV ImportとExportをする

執筆: HK

はじめに

Unreal Engine 4のBlueprintでは、そのままでも様々なNodeが利用可能ですがプロジェクトごとの要件を満たすために追加で機能が欲しくなることも多いです。今回はCSV ImportとExportをRuntimeで実行したいと思っていた時に見つけた「Victory Plugin」を、実際にRuntimeでCSV ImportとExportができるように例を示しつつ紹介します。

Victory PluginのライセンスはMIT Licenseですので、著作権表示とライセンスに関しての通知についての条件を満たせば商用利用も可能です。

セットアップをする

環境

手順

  1. GamesカテゴリーのProjectを作成します。
  1. First Person Templateを使用します。
  1. 下記設定でProjectを作成します。
    1. Project名は「CSVImportExport」とします。
  1. プロジェクト作成時に起動するUnreal Editorを終了します。
  2. VictoryPlugin26.zipをダウンロードします。
    1. 他のUnreal Engineバージョン用のPluginはUnreal Engine Forumsで案内されております。
  3. VictoryPlugin26.zipを展開します。
  4. \UE_4.26\Engine\PluginsフォルダにVictoryPlugin26フォルダを移動します。
    1. Pluginsフォルダが存在しない場合は作成します。
  1. 以上で、VictoryPluginのBlueprint Nodeが使用できるようになります。

実装する

今回実装するもの

  1. CSVファイルで敵の名前を体力を設定し、CSV Importを実行すると名前と体力が反映された敵(に見立てた箱)をSpawnする機能
  1. 敵を撃って弾が当たるとHPが1減る機能
  1. CSV Exportを実行すると敵の名前と体力の情報がCSVファイルで書き出される機能

実装手順

敵に見立てる箱「EnemyCube」の実装

EnemyCubeのBlueprint Classの作成

  1. ContentBrowserにてContent直下で右クリックします。
  2. Create Basic AssetよりBlueprint Classを選択します。
  3. 親クラスとしてActorを選択します。
  4. 作成したBlueprint Classの名前を「EnemyCube」とします。

EnemyCubeのComponent「Cube」の設定

  1. EnemyCubeのComponentsよりAdd Component\Basic Shapes\Cubeを追加します。
  2. DefaultSceneRootの子Componentとして設定します。

EnemyCubeのComponent「TextRender_Name」の設定

  1. 敵の名前を表示するためにEnemyCubeのComponentsよりAdd Component\Rendering\Text Renderを追加します。
  2. Cubeの子Componentとして設定します。
  3. 追加したTextRenderの名前を「TextRender_Name」とします。
  4. Details\TransformよりLocationをX: -60,Y: -30, Z: 20、RotationをX: 0.0°,Y: 0.0°、Z: 180.0°とします。
  5. 文字色を黒色にするためにDetails\Text\TextRenderColorよりHex Linearを000000FF、Hex sRGBを000000FFとします。
  6. Details\Text\Textを「Name」とします。

EnemyCubeのComponent「TextRender_Health」の設定

  1. 敵の体力の数値を表示するためにEnemyCubeのComponentsよりAdd Component\Rendering\Text Renderを追加します。
  2. Cubeの子Componentとして設定します。
  3. 追加したTextRenderの名前を「TextRender_Health」とします。
  4. Details\TransformよりLocationをX: -60,Y: -10, Z: -20、RotationをX: 0.0°,Y: 0.0°、Z: 180.0°とします。
  5. 文字色を黒色にするためにDetails\Text\TextRenderColorよりHex Linearを000000FF、Hex sRGBを000000FFとします。
  6. Details\Text\Textを「Health」とします。

EnemyCubeのComponent「TextRender_HP」の設定

  1. TextRender_Health」が敵の体力表示であることを示すためにEnemyCubeのComponentsよりAdd Component\Rendering\Text Renderを追加します。
  2. Cubeの子Componentとして設定します。
  3. 追加したTextRenderの名前を「TextRender_HP」とします。
  4. Details\TransformよりLocationをX: -60,Y: -10, Z: -20、RotationをX: 0.0°,Y: 0.0°、Z: 180.0°とします。
  5. 文字色を黒色にするためにDetails\Text\TextRenderColorよりHex Linearを000000FF、Hex sRGBを000000FFとします。
  6. Details\Text\Textを「HP:」とします。

ここまでの手順で下の画像のようなComponentの構造になっていればOKです。

また、Viewportでは下の画像のように見えるようになります。

EnemyCubeの変数「Name」の設定

EnemyCubeのVariablesにString型の変数「Name」を追加します。

EnemyCubeの変数「Health」の設定

EnemyCubeのVariablesにInteger型の変数「Health」を追加します。

ここまでの変数の設定でEnemyCubeのVariablesが下の画像のようになっていればOKです。

EnemyCubeの関数「UpdateName」の実装

下記のように、変数「Name」と「TextRender_Name」のTextを更新する関数「UpdateName」を実装します。

ちなみに、TextRenderではなくUMGのウィジェットを使用するとプロパティのバインディングが可能であり、今回のような関数を作ることなく変数が更新されたら表示されるTextも変更されるような設定も可能なので興味のある方はUMGについても調べてみましょう。

EnemyCubeの関数「UpdateHealth」の実装

下記のように、「変数Health」と「TextRender_Health」のTextを更新する関数「UpdateHealth」を実装します。

EnemyCubeのEvent Hitの実装

下記のように、EnemyCubeのEvent GraphにFirstPersonTemplateで使用されている弾のActorが当たった場合にHealthが減る処理を実装します。

以上でEnemyCubeへの実装は完了です。

FirstPersonExampleMapのLevel BlueprintへのCSVのImportとExport関連機能の実装

EnemyCubeのSpawn位置を指定するためのTargetPointを配置する

  • Level EditorのPlace ActorsよりTargetPointをLevelに配置します。
    • このあと実装する関数でEnemyCubeをSpawnさせる位置を指定するために使用します。
  • LocationはX: 200,Y: -1100, Z: 420とします。

Level Blueprintの変数「FileName」の設定

FirstPersonExampleMapのLevel BlueprintのVariablesにString型の変数「FileName」を追加します。

Level Blueprintの関数「SetEnemyData」の実装

下記のように、CSVの列ごとの文字列を受け取ってParseし、EnemyCubeに情報を設定する関数「SetEnemyData」を実装します。

Level Blueprintの関数「SpawnEnemyFromCSV」の実装

下記のように、CSVのFile Pathを受け取ってLoadし、行ごとにParseしたあとCSVのHeader行を除いた有効なデータのある行数分のEnemyCubeをSpawnさせる関数「SpawnEnemyFromCSV」を実装します。

EnemyCube 1コのSpawnごとに、Y+方向に200 cmずつSpawn位置をずらしていくことによりEnemyCube同士が重ならないようにしています。

Level Blueprintのイベント「ImportEnemyFromCSV」の実装

下記のように、CSVファイルから敵を読み込むCustomEvent「ImportEnemyFromCSV」を実装し「I」キーで実行されるように実装します。

連続で敵をCSVから読み込んだ際にEnemyCubeが重なってSpawnされないように、読み込みの度に既存のEnemyCubeがDestroyされる処理も含めています。

Level Blueprintの関数「SaveEnemyToCSV」の実装

下記のように、EnemyCubeの情報を取得しCSVを作成する関数「SaveEnemyToCSV」を実装します。

SaveEnemyToCSVのLocalVariablesにString型のFileNameを追加し、DefaultValueに「Name,Health」の値を設定しています。

Level Blueprintのイベント「ExportEnemyToCSV」の実装

下記のように、CSVファイルへ敵の情報を保存するCustomEvent「ExportEnemyToCSV」を実装し「E」キーで実行されるように実装します。

以上でFirstPersonExampleMapのLevel Blueprintへの変数・関数・イベントの追加は完了です。

Packagingする

PluginによってはPIEやDevelopment Buildでしか動かないものも多いですが、Victory Pluginの機能はShipping Buildでも使用できますのでShippingでPackagingして動作確認をしていきましょう。

Level EditorからFile\Package Project\Build Configuration\Shippingをクリックします。

次にLevel EditorからFile\Package Project\Build Configuration\Windows(64-bit)をクリックします。

Packageの置き場所には適当なディレクトリを指定し、Packagingしましょう。

このときにVisual Studioが要求されることがあります。Unreal Engine 用に Visual Studio をセットアップするを参考に、自分の条件に合ったエディションのVisual Studioを使用しましょう。

動作確認をする

\WindowsNoEditor\CSVImportExport.exeをクリックして動作確認をしましょう。

「E」キーを押すと\WindowsNoEditor\CSVImportExport\CSVData.csvにCSVファイルが作成されます。

CSVData.csvの内容をExcelなどで編集し、保存とExcelの終了をします。その後CSVImportExport.exeで「I」キーを押せばCSVData.csvの内容が反映されたEnemyCubeが配置されます。

データの行数を増やしたり、CSVImportExport.exe側でEnemyCubeを減らしたりしてCSVとの連携の挙動を確認してみましょう。

おわりに

Shipping BuildでもRuntimeでCSVの情報を読み書きできるようにする基本的な実装を紹介いたしました。

今回は、敵の名前と体力という限られた情報しか扱いませんでしたが、応用していくとCSVベースで編集可能なマップエディタやキャラクターエディタなどの実装やプレイヤーの行動ログのExportができそうですね。

Level Blueprintへの実装の一部でParserのようなものを書きましたが、このままだとCSVの列を増やすたびに複数箇所の編集が必要など少し労力がかかってしまいます。CSVの内容の変更に少ない労力で対応できるようにするという部分が課題でありますね。

今回は紹介しませんが、有料PluginでもCSV関連の機能を追加するものが販売されておりますので色々と試してみるといいかもしれません。

Victory Pluginではファイルの入出力以外にも、便利な機能がたくさん使えるようになります。興味を持たれた方は関連リンクからUE4 Forumを覗いたり、GitHubでソースコードを見てみましょう!

関連リンク