前提
1つのシートをUnityで取得するのは、SpreadSheetのデータをcsvで取得すれば良いので簡単。しかし、複数まとめて取得するのはcsvではできなかった。
やったこと
スプレッドシートのデータをMasterDataSet.cs
に格納します。
KeyValue.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace CA2.Data.MasterData
{
[System.Serializable]
public class KeyValue{
public string key;
public string value;
}
}
MasterDataSet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace CA2.Data.MasterData{
[System.Serializable]
public class MasterDataSet{
public List<KeyValue> keyValueList;
public List<Item> itemList;
}
}
リポジトリ
メニューのTools > ConvinientToolsでWindowを開いて、AnyTestボタンを押すことで動作を確認することができます。
流れ
- GASでシートのデータをJson形式で公開する。
- Unity側でJsonUtilityを用いてMasterDataSetに突っ込む
ポイント1 GASでシートのデータをJson形式で公開する。
Loader.gs
var SPREAD_SHEET_ID = "スプレッドシートのIDを入れる";
function onOpen(e){
var subMenus = [
{name: "LogMasterData", functionName: "LogMasterData"}
];
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.addMenu("Tools", subMenus)
}
function logMasterData(){
var dataJson = JSON.stringify(getAllMasterData(SPREAD_SHEET_ID));
Logger.log(dataJson);
Browser.msgBox(dataJson);
}
function doGet(e) {
var contents= getAllMasterData(SPREAD_SHEET_ID);
// Jsonをレスポンスとして返す
return ContentService.createTextOutput(JSON.stringify(contents)).setMimeType(ContentService.MimeType.JSON)
}
var snakeToCamel = function(p){
//_+小文字を大文字にする(例:_a を A)
return p.replace(/_./g,
function(s) {
return s.charAt(1).toUpperCase();
}
)}
function getAllMasterData(sheetId){
var sheets = SpreadsheetApp.openById(sheetId).getSheets();
var sheetsData = {}
sheets.map(function(sheet){ // 各シートごとにデータを生成し
var rows = sheet.getDataRange().getValues();
// rowsの0インデックス目から2つ取り除き、除いたものを返す
var keys = rows.splice(0, 2)[0]; // 0: カラム名 1: コメント
var sheetData = rows.map(function(row) {
var obj = {}
row.map(function(item, index) {
obj[keys[index]] = item;
});
return obj;
})
sheetsData[snakeToCamel(sheet.getName()) +"List"] = sheetData;
})
return sheetsData;
}
(1) getSheets()
を使うと全てのシートを取得することができる。
(2) MasterDataSetの変数名と一致させる
ポイント2 Unity側でJsonUtilityを用いてMasterDataSetに突っ込む
MasterDataLoader.cs
using System;
using System.Collections;
using System.Collections.Generic;
using CA2.Data.MasterData;
using UniRx;
using UnityEngine;
namespace CA2.Data {
public class MasterDataLoader {
public IObservable<MasterDataSet> Load (string url) {
return ObservableWWW.Get (url, null, new ProgressLogger())
.Do(t => Debug.Log(t))
.Select (x => {
try {
return JsonUtility.FromJson<MasterDataSet> (x);
} catch (System.Exception) {
throw;
}
});
}
public class ProgressLogger : IProgress<float> {
public void Report (float value) {
Debug.Log (value);
}
}
}
}
適切な形でJsonをもらえればJsonUtilityで簡単にデータを格納することが可能。
KeyValue.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace CA2.Data.MasterData
{
[System.Serializable]
public class KeyValue{
public string key;
public string value;
}
}
KeyValueのvalueは本当はobject型にしたかったのですが、JsonUtilityで値が入らなかったのでstringにしています。
まとめ
ここからさらにScriptableObject
として保存した後、AssetBundle化して配信することでいい動きができるんじゃないかと思っています。
スクリプト自動生成、AssetBundle化して配信までを1ボタンでできるようにしていければいいなと思います。