[Unity]Runtimeでスプレッドシートの情報をJsonで受け取り反映する

## ○経緯
 - 仕事でアプリのプロトタイプを作る事になりました。
 - パラメータなどはエクセルで用意されていました。
 - 「NPOIとエディタプログラムで作れるから！」と経験もかねて後輩にインポータを作ってもらいました。
 - しかし頻繁にパラメータ調整を行う羽目になりつつありました。
 - 逐一反映とかの手順踏むのめんどくさい。
 - サーバーサイドの上司が簡易なWeb画面を用意してくれました。
 - けどアプリ起動時にスプレッドシートのデータ取り込めばええやんと、業務後に家でのんびりやり方を模索する事にしました。

## ○環境
 - Windows64bit、Unity 5.5.0f3、無料の外部アセット([Json.NET Converters - Simple compatible solution](https://www.assetstore.unity3d.com/jp/#!/content/58621))
 - Androidの実機テストは後ほどやる予定です。iOSに関しては家にMacが無いので…(´・ω・｀)
 - もしかするとビルド設定や動的コンパイルなどで引っかかるかもしれません…。

## ○先に結論
 - GoogleAppsScriptで簡易なWebAPI用意すればイケそうでした。([Google SpreadSheet のデータを JSON 形式で取得する Web API をサクッと作る](http://qiita.com/takatama/items/7aa1097aac453fff1d53))
 - JsonのデシリアライズはAssetStoreに良さそうなアセットがありました。([Json.NET Converters - Simple compatible solution](https://www.assetstore.unity3d.com/jp/#!/content/58621))

## ○成果物
 - Githubにあります。[https://github.com/cyber1496/GAS](https://github.com/cyber1496/GAS)
 - サンプルの実行方法などは付属のREADMEを見てください。
 - GoogleDrive上のスプレッドシートにアクセスする必要があるためいくつか手順を踏む必要があります。

## ○事前準備
 - [Google SpreadSheet のデータを JSON 形式で取得する Web API をサクッと作る](http://qiita.com/takatama/items/7aa1097aac453fff1d53)を参考にスプレッドシートを用意、Webアプリとして公開する必要があります。
 - 大まかな手順については[成果物のリポジトリ](https://github.com/cyber1496/GAS)にあるREADMEに記載しました。

## ○細かな実装など
#### ◆呼び出し
シートごとにデータの構造を変えることを考慮しシート名を指定させてます。
ジェネリックで型を指定し、通信処理が終わったらActionが呼び出されるようにしました。

```
StartCoroutine(
    GetData<データ型>(シート名,
        dataArray =>
        {
            foreach (var data in dataArray)
            {
                Debug.Log(data.ToString()));
            }
        }
    )
);
```
#### ◆データ取得
UnityWebRequestを使いました。
Json.NET Convertersがとても気持ちよく使えて良かったですね。

```
IEnumerator GetData<T>(string sheetName, System.Action<T> action)
{
    var request = CreateRequestGetSheetJson(sheetName);
    if (request == null)
    {
        yield break;
    }
    yield return request.Send();
    if (request.isError)
    {
        Debug.LogError(request.error);
    }
    else
    {
        action(JsonConvert.DeserializeObject<T>(request.downloadHandler.text));
    }
}
```
### ◆通信リクエスト
ひとまず GETで欲しいシート名渡せればええやろ…と

```
UnityWebRequest CreateRequestGetSheetJson(string sheetName)
{
    return UnityWebRequest.Get(
        string.Format("{0}?{1}&{2}",
                        WebAPIのURL,
                        Param("sheetId", スプレッドシートのID),
                        Param("sheetName", sheetName))
        );
}
string Param(string key, string param)
{
    return string.Format("{0}={1}", key, param);
}
```

### ◆(追記)スプレッドシート側のGoogleAppsScript
記事のタグにGoogleAppsScriptを付けているにも関わらず触れておりませんでした。
[Google SpreadSheet のデータを JSON 形式で取得する Web API をサクッと作る](http://qiita.com/takatama/items/7aa1097aac453fff1d53)で掲載されていらっしゃる内容を流用させて頂いています。

```
function getData(id, sheetName) {
  var sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);
  var rows = sheet.getDataRange().getValues();
  var keys = rows.splice(0, 1)[0];
  return rows.map(function(row) {
    var obj = {}
    row.map(function(item, index) {
      obj[keys[index]] = item;
    });
    return obj;
  });
}
function doGet(e) {
  var id = e.parameter.sheetId;
  var data = getData(id, e.parameter.sheetName);
  return ContentService.createTextOutput(JSON.stringify(data, null, 2))
  .setMimeType(ContentService.MimeType.JSON);
}
```



以上です。