ぼっちプログラマのメモ

UE4とかVRとかについて書いたり書かなかったり。

UE4エディタ上で、Googleスプレッドシートの内容をDataTableに反映してみた

はじめに

UE4にはDataTableという機能があり、この機能を活用することで大量のデータを効率よく管理することができます。そして、csvjsonとの連携機能を持っているため、
「みんな大好きExcelで編集」
→ 「UE4エディタが変更を検出して自動インポート( Auto-Import )」
→ 「DataTableに反映」
というフローが一般的になっています。
データ駆動型のゲームプレイエレメント | Unreal Engine ドキュメント
[UE4] CSVデータを扱う方法 DataTable編|株式会社ヒストリア
【UE4】DataTableの使い方-その① ~基本編~【★~★★】 - キンアジのブログ

ただExcelを毎回開くのが少し面倒です(環境によってはExcelがそもそもインストールされてないことも)。
また、Excelをインポート → DataTableに反映という流れの都合上、パッケージで動作中にExcelを使ったパラメータ編集をするのは難しいです。そのため、Excelを編集するたびにパッケージを作成し…という手間がありました。

なんか良い手はないかなぁと思っていた時に…

「うちはGoogleスプレッドシートからデータ抽出してるよ。そのおかげでパッケージでもデータをガンガン編集できるよ」

という講演をどこかで聞き、おお!これは実装してみよう!…と思ったのが約2年前。やっと実装してみました。

www.youtube.com
Googleスプレッドシートの内容がDataTableに無事反映されています。素晴らしい。

ということで、やってみたことを自分用メモを兼ねて書いていきます。なお、この辺りに関しては完全に初心者なのでもっといい方法があるかもしれません。ご存知の方はこそっと教えて下さい!

Googleスプレッドシートからデータを抽出する方法を調べてみた

まずはWeb上にあるGoogleスプレッドシートから各データを引っ張ってくる処理について検索してみると、特定のURLから取得する方法、又はGoogle Sheets APIを使う方法のどちらかになるようです。

公式ドキュメント
Reading & Writing Cell Values  |  Sheets API  |  Google Developers
Method: spreadsheets.values.get  |  Sheets API  |  Google Developers
参考ブログ記事
Google Sheets API v4を適当に叩いて適当にデータをJSONで取得する - taiki-t's diary
[PHP] Google Sheets API を使ってスプレッドシートに値を書き込む | AgoHack

厳密にするのなら後者の方法が良いみたいですが、今回はサクッと実装したかったので前者の方法を試してみました。

やったことは以下の通り。詳細は上記の参考ブログを見てくださいまし。

  1. Google Cloud Platform に登録・プロジェクトを作成し、APIキーを作成 https://console.developers.google.com/apis/credentials
  2. Google Sheets APIを ↑ で作成したプロジェクトに登録 https://console.developers.google.com/flows/enableapi?apiid=sheets.googleapis.com
  3. 使用するスプレッドシートを公開 ( リンクを知っている全員が閲覧可能 という設定でOK )

これでWebブラウザで以下の形式のURLにアクセスすると、Json形式でデータを取得できるようになります。
https://sheets.googleapis.com/v4/spreadsheets//values/?key=

f:id:pafuhana1213:20191012210740p:plain

f:id:pafuhana1213:20191012210800p:plain

UE4エディタ上で、HTTP経由でGoogleスプレッドシートからデータを抽出してみた

次は、UE4エディタ上で先程試したことを同じことをします。なお、使用するノードの関係で、Editor Utility Widget上で実装を行います。
[UE4]エディタ上で動作するツール・エディタ拡張をUMGで簡単に作れる Editor Utility Widget について - Qiita


UE4にはFHttpModule というHTTP通信をするための機能が用意されています。
UE4.10 How To Make HTTP GET Request in C++ - Epic Wiki
[UE4] HTTP通信 その1 ~基本編~|株式会社ヒストリア
UE4 で http 通信を行う - お茶漬けびより
UE4: FHttpModule 系の HTTP リクエスト機構を使い "同期処理" する方法 - C++ ときどき ごはん、わりとてぃーぶれいく☆
UE4/C++: http(s) リクエストに FHttpModule 系を使う場合の OnProcessRequestComplete/FHttpRequestCompleteDelegate の成否フラグの注意どころ - C++ ときどき ごはん、わりとてぃーぶれいく☆

しかし、残念ながらBPでは用意されていません。また、これを試していた時の僕は C++ を書く気分ではありませんでした。

なので、金で解決しました。Money is Powerです
f:id:pafuhana1213:20191012211703p:plain
LE Http Request:Low Entry:Code Plugins - UE4 マーケットプレイス

そんなこんなでサクッと実装し…
f:id:pafuhana1213:20191012213642p:plain


Get GoogleSparedSheet Data using HTTP > BlueprintUE.com | PasteBin For Unreal Engine 4


サクッと取得できました。大人って汚いですね。f:id:pafuhana1213:20191012214126p:plain
f:id:pafuhana1213:20191012212052p:plain

Googleスプレッドシートから抽出したJsonデータから更に必要な箇所だけ抽出してみた

あとは抽出したデータをDataTableに反映するだけなのですが、そのためにはまずJsonデータから必要なデータ(values)だけを抽出する必要があります。

UE4にはJsonデータを扱うための機能が用意されています。
[UE4][C++]FJsonSerializebleマクロを使ってみる|株式会社ヒストリア
Unreal Engine4 でローカルにあるJsonをパースする。 - LIFULL Creators Blog
Unreal Engine4でJsonデータをパースしてみた | SystemTelescope

しかし、残念ながらBPでは用意されていません。また、これを試していた時の僕は C++ を書く気分ではありませんでした。

なので、金で解決しました。金は力です

f:id:pafuhana1213:20191012213458p:plain
LE Json:Low Entry:Code Plugins - UE4 マーケットプレイス

そんなこんなでサクッと実装し…
f:id:pafuhana1213:20191012214126p:plain

サクッと取得できました。大人はこういうことを平気でする
f:id:pafuhana1213:20191012214312p:plain

抽出したデータ(values)をDataTableに反映する

最後は抽出したデータをDataTableに反映します。軽く調べた所、DataTableにまとまったデータを反映するには UE4.23 時点ですと Fill Data Table from CSV / JSON String ノードが役に立ちそうです。
f:id:pafuhana1213:20191012214753p:plain

今回の場合、Fill Data Table from CSV Stringを使う場合は

---,MaxWalkSpeed,GravityScale,Jump Z Velocity,Air Control
Default,"550.000000","3.000000","800.000000","1.000000"
Boost,"550.000000","3.000000","800.000000","1.000000"

Fill Data Table from JSON Stringを使う場合は

[
	{
		"Name": "Default",
		"MaxWalkSpeed": 550,
		"GravityScale": 3,
		"Jump Z Velocity": 800,
		"Air Control": 1
	},
	{
		"Name": "Boost",
		"MaxWalkSpeed": 550,
		"GravityScale": 3,
		"Jump Z Velocity": 800,
		"Air Control": 1
	}
]

という感じの形式に整形する必要がありそうです。(DataTableアセットの右クリックメニューからCSV, Jsonを出力すればどういう形式のデータにするべきか確認できます。)
f:id:pafuhana1213:20191012215311p:plain

今後の拡張性を考慮するならJson形式に整形すべきかと思うのですが、今回はとにかく楽に実装したかったのでCSV形式にしました。
以下の順番で各文字列が来るので、改行と","を挟むだけなので超ラクです。

---
MaxWalkSpeed
GravityScale
Jump Z Velocity
Air Control
Default
550
3
800
2
Boost
550
3
800
1

で、実際にはこんな感じのノードになりました。
f:id:pafuhana1213:20191012215926p:plain


Pickup Json data f and convert to DataTable > BlueprintUE.com | PasteBin For Unreal Engine 4

最後に

これでGoogleスプレッドシートの内容をDataTableに反映することができました。あとは、反映されたタイミングでその結果を各キャラ・システムなどに反映すればOKです。または一定時間毎にDataTableを見に行くという開発用機能を各キャラ・システムに組み込むのも良いかと思います。

ただし、Fill Data Table from CSV / JSON String ノードはエディタ専用の機能なので、PIEでは動作しますがパッケージでは動作しません。そのため、パッケージの場合でもGoogleスプレッドシートの内容を反映させたい場合はDataTableを経由せずに直接対象のパラメータを変更する処理にする必要があるかと思います。また試してませんが、DataAssetを活用するといい感じになる予感がギュンギュンします
[UE4][C++] ユーザー定義オブジェクトのアセット化で楽をする|株式会社ヒストリア
UE4 c++を用いたデータテーブルを使った独自データアセットの作成 - Qiita
【UE4】手軽に独自のデータアセットを作成する 【★★】 - キンアジのブログ



おしまい