- 必要なもの
- Googleのアカウント
・GoogleSpreadSheetのページへ行く https://www.google.com/intl/ja_jp/sheets/about/
・シートの画面が開くので、「ツール」→「スクリプトエディタ」
・function myFunction() {} は消して、コードをペタっとな (最新はこちら→https://github.com/divide-by-zero/GSSA/blob/master/projects/Assets/GSSA/GoogleAppsScript/GSSA.gs)
・ 「公開」→「Webアプリケーションとして導入...」 → プロジェクト名の編集 (好きな名前を。そのままでも良いです)
・プロジェクトバージョンは「新規作成」 アプリケーションにアクセスできるユーザーは「全員(匿名ユーザーを含む)」にして「導入」
・「許可が必要です」のダイアログが表示されるので、「許可を確認」→ 自分のGoogleアカウントを選んで「許可」
・「現在のウェブアプリケーションのURL」 をコピーして取っておいてください。
GoogleSpreadSheet上の作業は以上です。 簡単に。というわりに手順が多めですが最初の1回だけですし、あまり迷うところがないのでそんな苦じゃないかと。
github(https://github.com/divide-by-zero/GSSA) のReleaseフォルダから GSSA.unitypackage をダウンロード(直リンク:https://github.com/divide-by-zero/GSSA/raw/master/Release/GSSA.unitypackage) し、 使いたいプロジェクトにインポートしてください。 (メニューのAssets→Import Package→Custom PackageからGSSA.unitypackageを選択してImportするか、プロジェクトを起動した状態でGSSA.unitypackageダブルクリックでも大丈夫(なはず))
1番最初のシーンにGSSA/Prefabs/SpreadSheetSetting prefabを配置 ※空のGameObjectを配置して、GSSA/Scripts/SpreadSheetSettingsを自分でアタッチしても良いです
inspectorのurlの枠に↑でコピーしておいた**「現在のウェブアプリケーションのURL」**をセット
Is Debug Log Output はチェックを入れると微妙に通信のログが出力されます。デバッグ時にどうぞ。 Default Sheet Name はとりあえず入れなくても良いです(後述)
これで準備完了です! さぁ使いましょう。
NiftyのmBasSに似た感じになってます(ちょっと参考にしつつ、不要だと思ったところをそぎ落としたので似ているだけです)
例えば、空のGameObjectに適当なScriptをアタッチして、Startにでもこんな感じで書きます
using UnityEngine;
using GSSA;
public class GSSATest : MonoBehaviour {
void Start ()
{
var so = new SpreadSheetObject("Chat");
so["name"] = "かつーき";
so["message"] = "たべないでください!";
so.SaveAsync();
}
}
これで実行をすると、先ほど作ったスプレッドシートに「Chat」というタブが追加され、1行目にnameとmessageとcreateTime(これだけは勝手に作られます)、2行目にそれぞれプログラムで指定した文字列と作成日時の数字が記入されているはずです。
もうお分かりですね。 GoogleSpreadSheetを使って簡易なKey-Value-Storeを用意しました。 Google Apps ScriptにはdoPostかdoGetというメソッドを用意することで、Webサービス風にふるまう事が出来るので、それをインタフェースにSpreadSheetを操作しているだけです。
なお、これではSpreadSheetにデータを追加しているだけなので、取得もやってみます。
using System.Linq;
using UnityEngine;
using GSSA;
public class GSSATest : MonoBehaviour {
void Start()
{
var query = new SpreadSheetQuery("Chat");
query.Where("name", "=", "かつーき");
query.FindAsync(list => {
foreach (var so in list)
{
Debug.Log(so["name"] + ">" + so["message"]);
}
});
}
}
これまたNiftyのmBasSよろしく、Query発行のためにSpreadSheetQuery
クラスをnewしています。
なお、コンストラクタに渡しているのはシート名なんですが、「2.Unity側準備」でセットアップしたSpreadSheetSettingsのDefault Sheet Nameに基本的に使用するシート名を記述しておけば省略(nullを指定)した場合そちらが使われます(SpreadSheetObjectも同じです。 無事伏線回収)
また、Whereメソッド
で絞り込みができます。 AND条件のみ対応しており、その場合にはAndWhereメソッド
を使ってください。それぞれのメソッドが自分自身を返すのでメソッドチェーンで書く事も出来ます。
<例>
query.Where("name","=","かつーき").AndWhere("message","!=","もがもが").FindAsync(list=>{});
(なおOR条件はややこしくなるので省きました。要望があれば追加する・・?かも・・・?)
ソースがくっついているので、詳しくはソース見てね!って感じもしますが、一応補足。 Whereの第一引数はKeyになる項目。 第二引数は比較式です。=,==,<,<=,>,>=,!=,<> あたりだけ対応しています。
他には
Limit(int count)
… 返却されるリストの先頭から指定した数を上限として取得Skip(int count)
… 返却されるリストの先頭から指定した数を飛ばして取得OrderByAscending(string key)
… 返却されるリストを指定したkeyで昇順にソートOrderByDescending(string key)
… 返却されるリストを指定したkeyで降順にソート
があります。
FindAsyncの引数にはcallbackでAction<List<SpreadSheetObject>>
が書けるようになっており、戻ってきたListに対しての処理をラムダ式で記述する感じです。
そして、何気にFindAsync(SaveAsyncも)はTaskのasync-awaitのように、コルーチンの中であればyield return で待機可能になっています。 具体的には↓な感じ
using System.Collections;
using System.Linq;
using UnityEngine;
using GSSA;
public class GSSATest : MonoBehaviour {
void Start ()
{
StartCoroutine(ChatLogGetIterator());
}
private IEnumerator ChatLogGetIterator()
{
var query = new SpreadSheetQuery("Chat");
query.Where("name", "=", "かつーき");
yield return query.FindAsync();
foreach (var so in query.Result)
{
Debug.Log(so["name"] + ">" + so["message"]);
}
}
}
この場合はQueryオブジェクトのResult
にList<SpreadSheetObject>
が格納されます。(こっちの方が使い良いかも?)
なお、Listの件数はQueryオブジェクトのCountに格納されます。
使っても使わなくてもなんですが、SpreadSheetQueryにはCountAsync
メソッドも用意してあり、こっちは件数だけを返却してくれるので、自分のスコアが何位なのか、などをそれなり高速に調べるのに使えます。
データの更新はどうするのか。 というと、SpreadSheetQueryで取得できたSpreadSheetObjectに対して値をセットして、SaveAsyncを呼ぶだけです。
using System.Collections;
using System.Linq;
using UnityEngine;
using GSSA;
public class GSSATest : MonoBehaviour
{
void Start()
{
StartCoroutine(ChatLogGetIterator());
}
private IEnumerator ChatLogGetIterator()
{
var query = new SpreadSheetQuery("Chat");
query.Where("name", "=", "かつーき");
yield return query.FindAsync();
var so = query.Result.FirstOrDefault();
if (so != null)
{
so["message"] = "たべないよ!";
yield return so.SaveAsync();
}
}
}
内部的にはobjectIdというid(というか、SpreadSheetでの行番号)を持っていてそれの有り無しで新規か更新か分岐している感じです。