まずはじめに
こちらUnityのWebGL出力に簡単に無料でグローバルランキングを実装できる仕組みを考えてみた の補足(追加)に記事になります。
できれば先にそちらをどうぞ。
調べたところ
正式な情報がどこに書いてあるかわからないんですが、とあるところにGoogleSpreadSheetの1セルに書ける文字列の長さが50000文字って書いてあったんですよね。
ということは・・・。 よほど大きいデータじゃなければ、BASE64で文字列にして格納すれば結構なサイズのbyteデータもアップロードできるのでは!? というひらめき(?)
ということで、以前作った某ゲームのクローンのグローバルなリプレイ機能を追加してみました。
https://unityroom.com/games/1umines
なお、byte[]からBase64文字列への変換、およびBase64文字列からbyte[]への変換には
System.Convert.ToBase64String( byte[] )
と System.Convert.FromBase64String(string )
を使用しました。ラクちんだなぁ。
そこで分かった問題点
ただ、一つ問題があります。
普通にランキングの箇所にBASE64でリプレイデータを付けてしまうと、リプレイが必要ない場合(ただランキングが表示したい場合など)に無駄なデータが大量に降ってきてしまう事です。
そのため、ほしいデータだけを先に指定してあげる機能が必要です。
すなわちSQLで言うところのSelect構文を追加することにしました。
追加① Select機能
Select(params string[] selects);
をSpreadSheetQuery
に追加しました。
var query = new SpreahSheetQuery("scoreRank");
query.Select("id,name,hiscore");
のように返却してほしい列の列名を,区切りで列挙する感じです。
なお、
query.Select("id","name,hiscore");
のようにしても解釈されるようにしてあります。
このSelect機能を使うことで、とりあえずのランキング取得ではreplayDataを省いた列名だけを列挙してFindAsyncして、リプレイ再生するときにはidを指定してまたFindAsyncする。といった使い方ができるわけです。ベンリー。
追加② Distinct機能
ついでに前からほしいと思っていたDistinct機能も追加しました。
これはざっくり言うと「重複を省く」機能です。
Distinct(string distinctKey);
をSpreadSheetQuery
に追加しました。
var query = new SpreahSheetQuery("scoreRank");
query.Distinct("id");
のようにしておくと、返却されるデータで同じidがある場合は先頭データのみ取得されます。
例えばランキング処理で
id | score | date |
---|---|---|
0001 | 100 | 20170512 |
0001 | 120 | 20170601 |
0005 | 80 | 20170505 |
0001 | 140 | 20170404 |
0005 | 99 | 20170504 |
0004 | 30 | 20170504 |
のように1ユーザーがスコアを複数登録している場合、scoreのTOP3を出そうとした場合全てid=0001が取れてしまうわけです。
時にそれが望ましい場合もありますが、ユーザーの重複を除いたTop3が欲しいという事は普通にありうるとおもいます。
そんな時に
Distinct("id");
と指定してあげることで、idの重複がなくなり、socreやdateは上から見ていって先に見つかったほうを使用するので
id | score | date |
---|---|---|
0001 | 100 | 20170512 |
0005 | 80 | 20170505 |
0004 | 30 | 20170504 |
このようなデータが返却されることになります。
これではTOP3ではなくなってしまうので、通常は何かしらをキーに整列させたものが対象になるはずです。
例えば、各人のhiscoreのTop3なのであれば
var query = new SpreahSheetQuery("scoreRank");
query.OrderByDescending("score").Distinct("id");
とすれば、
id | score | date |
---|---|---|
0001 | 140 | 20170404 |
0005 | 99 | 20170504 |
0004 | 30 | 20170504 |
のように、id=0001のデータは最高点である140点のScoreになりますし、Scoreはどうでもいいから、各ユーザーの最新(一番最後のデータ)がほしい。という場合は
var query = new SpreahSheetQuery("scoreRank");
query.OrderByDescending("date").Distinct("id");
のように日付(date)を指定すればよいということです。
よかったら使ってみてください。