Amazon GameSparksでUnityゲームにランキング機能を実装する

# はじめに

GameSparksは、Amazonが昨年買収したゲーム向けBaaS（Backend as a service)です。
サーバー処理が必要だったユーザーアカウント管理や、データベース、マルチプレイなどのゲーム機能がマネージドサービスとして提供されています。
これまでサーバー側の知識が必要だった上記機能を、比較的簡単にゲームに導入することができます。
Unity SDKが提供されており、本稿ではUnity WebGLで動作するデモゲームをベースに紹介します。

アカウント取得やログイン、リーダーボード機能のセットアップについては次の投稿をご覧ください。
「Amazon GameSparks for Unityを触ってみた」
https://qiita.com/Takaaki_Ichijo/items/b47f8bfd41d9bb4c9a3f

## デモゲーム
「Cube Tower」という、上から降ってくるキューブをトレーで受け止め続ける虚無ゲーを作りました。

![20180528-190013.png](https://qiita-image-store.s3.amazonaws.com/0/19010/93356983-b46b-c536-d4c4-3031036c5d2f.png)

こちらから遊べます。
https://unityroom.com/games/cubetower

始めて遊ぶ場合はユーザーネームとパスワードを入れて「Sign in」をクリックするとゲームがスタートします。

## ユーザーの新規登録をアプリから行う

前回の記事では管理画面内でテスト用のログインアカウントを作っていたのですが、Unityアプリの中からアカウントを作れるようにしてみましょう。
GameSparks.Api.RequestsにあるResigtrationRequestクラスを使ってアカウントを新規作成できます。

```csharp:PlayerAuth.cs
using GameSparks.Api.Requests;

    private void Signin(string userName, string password, Action<bool> callback)
    {
        new RegistrationRequest()
            .SetDisplayName(userName)
            .SetUserName(userName)
            .SetPassword(password)
            .Send((response) =>
        {
            if (!response.HasErrors)
            {
                callback(true);
            }
            else
            {
                Debug.Log("error " + response.Errors.ToString());
                callback(false);
            }
        });
    }

```

ユーザーネームとパスワードを入力するフォームを作り、「Signin」をクリックされた際にこのメソッドを呼ぶようにイベントに紐づけます。

![20180528-185950.png](https://qiita-image-store.s3.amazonaws.com/0/19010/24498a49-653a-5a6c-a5af-f78c00340453.png)

なおGameSparksにはTwitterやFacebookなどの外部SNSアカウントでログインする方法も提供されています。
そちらはいずれ紹介したいと思います。

## アプリからLeaderboard情報を取得する

つづいて、GameSparksの中に格納されたデータを取り出します。
GameSparks.Api.Responsesに、特定のデータ形式を受け取る場合のクラスが用意されています。
今回はランキング用ですので、「LeaderboardDataResponse」を使用してデータを引っ張ってきてみましょう。

```csharp:GetLeaderBoard.cs

using GameSparks.Api.Responses;


    public void GetScores(Action<string> callback)
    {
        string leaderBoard = string.Empty;

        new LeaderboardDataRequest().SetLeaderboardShortCode("SCORE").SetEntryCount(10).Send((response) =>
        {
            if (!response.HasErrors)
            {
                Debug.Log("Found Leaderboard Data...");
                foreach (LeaderboardDataResponse._LeaderboardData entry in response.Data)
                {
                    int rank = (int)entry.Rank;
                    string playerName = entry.UserName;
                    string score = entry.JSONData["SCORE"].ToString();
                    Debug.Log("Rank:" + rank + " Name:" + playerName + " \n Score:" + score);

                    leaderBoard += rank + ": " + playerName + "  " + score + " squares \n";
                }

                callback(leaderBoard);
            }
            else
            {
                Debug.Log("Error Retrieving Leaderboard Data..." + response.Errors.ToString());
            }
        });
    }
```

ショートコード名「SCORE」のリーダーボードから10件のデータを取得しています。

データはLeaderboardDataResponse._LeaderboardDataクラスに格納さます。
今回は非常に単純な実装として、ランキング表示を文字列で組み立ててしまいます。
上記の例では、デフォルトのフィールドであるrank,userNameのほか、カスタムデータとして「SCORE」の値をJSONDataプロパティから取得しています。

![20180528-190017.png](https://qiita-image-store.s3.amazonaws.com/0/19010/dc23fba9-7d7a-db4b-d008-5b75ee885188.png)

本格的に管理するならば、ランキングデータ格納用のstruct也を作ってデータを詰め、UI表示メソッドに渡す構造が良いかと思います。

## 本番モードと利用ライセンス

スクリーンショットには「Preview mode」とありますが、これはその名の通り機能プレビューモードになります。
GameSparksを使ったゲームを公開するためには、商用ライセンスの承認を得てから、本番モード(Live)にしなくてはなりません。

### ライセンスを取得する

個人や小規模のゲーム開発者向け、学生や教育機関向けには無料ライセンスがあります。
ひと月当たりのアクティブユーザーが100,000人を超えなければ無料です。それ以降はMAUあたり2セントになります。
（2¢ per MAU (first 100,000 per month free)）

https://www.gamesparks.com/pricing/

ライセンスの取得には、「Appry Now」からGameSparksサポートにメールを送る必要があります。
会社規模によってやり取りは変わると思うのですが、個人の場合は「どんなゲームに利用するか」「なんというチーム名か」「どのくらいの利用者数を見込んでいるか」などの質問に答える必要があります。
英語ですが、メールで1回返事すれば2日ほどでライセンスを発行してくれます。

### 管理画面でLiveモードをスタートする

サポートからライセンス開通の連絡が来たら、管理画面でゲームをLiveモードに移行します。
まずは、現在の設定をスナップショットとして保存します。
Game Overview画面に「Snapshots」の欄がありますので、「Create」ボタンからスナップショットを作成します。

![Test2 - GameSparks Portal - Google Chrome 2018-06-01 16.24.14.png](https://qiita-image-store.s3.amazonaws.com/0/19010/d3b64a62-4aa8-3920-620d-7c9b927d13cf.png)

スナップショットにはこの設定をゲーム用に公開する「Publish」ボタンがあるので、これをクリックします。

![publsih.png](https://qiita-image-store.s3.amazonaws.com/0/19010/f49ca619-4353-7e6a-9b9a-01569175639b.png)

公開前に中心となる地域(Primary Region)を聞かれますので、私はAsiaを選びました（インスタンスの紐づけと関係があるっぽい）

なお、本番モードのデータを管理画面から見るには、Data Exploerで右上の「Preview」ボタンを「Live」に切り替える必要があります。

![CubeTower - GameSparks Portal - Google Chrome 2018-06-01 16.48.38.png](https://qiita-image-store.s3.amazonaws.com/0/19010/2a98ca4c-c05f-9559-4d33-adf696255673.png)


### Unity内の設定からpreview buildのチェックを外す

つづいてアプリ側の設定です。Unity EditoryでGameSparksSettingsスクリプタブルオブジェクトにて、「Preview Mode」のチェックを外します。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f31393031302f65643739336235322d633837612d333734632d356161642d3630376161383031353461362e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/19010/71704300-21ee-1d1d-81f9-9a15cd980d19.png)


一応Editor内で挙動を確認してから、ビルドを行いましょう。これで公開設定は完了です。

# おわりに

GameSparksについてはCredentials関連など、まだ挙動を把握しきれていないのですが、設定事項がそれなりにある代わりに、運用の柔軟性が高いシステムと言えるでしょう。
AWSのイベントでAmazon Game Techの担当の方に聞いたところ、現在マニュアルの日本語化を進めているそうです。

次回はアプリのせっていをリモートで変更する機能か、マルチプレイ関連を調査したいともいます。
（Cloud Codeの解説してくれる人募集中！）