Amazon GameSparks for Unityを触ってみた

# Amazon GameSparksとは

Amazonが昨年買収したゲーム向けBaaS（Backend as a service)です。
AWS、GCPなどのIaaSより上のレイヤーで展開するサービスで、サーバーインスタンスが隠蔽されたマネージドサービス系になります。

![gamesparksロゴ.png](https://qiita-image-store.s3.amazonaws.com/0/19010/07a2ae02-b0d2-0d2d-ae16-fbc6b030cf47.png)
https://www.gamesparks.com/

GameSparksはデータベース、ユーザー認証、マルチプレイ、アナリティクスなど包含するサービス範囲が広いことが特徴です。また、管理画面上でのテストの実行や、ゲーム専用の管理画面を自分で設計できるAPI、クラウド側でjsを実行できる環境など、広いカスタマイズ性があります。

最近こうしたBaaSはGoogleのFirebase, MicrosoftのPlayfab, FJCTのNCMBなど大手IaaSベンダー各社が展開しており群雄割拠という雰囲気です。
AmazonはMSについでBaaS後発組でして、どうするのかな？と思っていたのですが、AWSの上で展開していた会社を買収する形で自社サービスとして擁立となりました。
今後はAmazon Game Techとの等号が今後進み、機能拡充がますます期待できるといえるでしょう。

プラットフォームはPC, Mac, iOS, Androidに加え、PS4, Xbox One, Switchなど各コンソールゲーム機にも対応しています。
私の事業が主にSteam・コンソールゲーム機向けのインディーゲームの開発ですので、ゲーム機タイトルでの実績があることが決め手となり、今回の評価に踏み切りました。

![7daystodie.png](https://qiita-image-store.s3.amazonaws.com/0/19010/c23c865d-1653-74f4-435b-8d968aec96ae.png)

ゲームエンジンにはUnity, Unreal, Corona, Construct 2に対応しています。Amazon Game TechといえばLumberyardですが、今のところは対応していないようで、今後対応が進むかと思われます（LumberyardにはGemsがあるので大丈夫そう？）

料金体系ですが、企業の場合は要相談みたいです。インディーライセンスがあり、専門学校の学生や3人以下で作っているゲームなら2セント/MAU、最初の100,000/月 は無料だそうです。
https://www.gamesparks.com/pricing/

以前からGameSparksの存在は知っていましたが、先日の「[Amazon Game Tech Night #5](https://togetter.com/li/1217739)」で改めて興味を持ち、このエントリを書きました。
同じタイミングで、Amazonのゲーム開発者向け最新情報の発信役として [@AmznGameTechJp](https://twitter.com/amzngametechjp)　が最近開設されました。

ちなみに日本のゲームメディアGameSparkとは何も関係がありません。ややこしい。

# 準備編

## アカウントの取得

まずは何はともあれアカウントを取得します。
https://auth.gamesparks.net/register.htm

終わったら、管理ページ内で新規プロジェクトを作成します。GameSparks内では「Game」という単位になります。「Add New Game」から作っていきます。

![新規Gameの作成.png](https://qiita-image-store.s3.amazonaws.com/0/19010/57f0f2d4-026c-cf48-6b8c-a1d17d9befcf.png)

ここではプロジェクト名、セッションが自動切断される時間（設定をスキップすることもできる）を設定。

次に利用する機能と連携したいプラットフォームを選びます。

![機能とプラットフォームの選択.png](https://qiita-image-store.s3.amazonaws.com/0/19010/9613a215-1472-a771-7cf9-8df98040b0c7.png)

テスト目的ならとりあえず機能は全部オンでいいと思います。プラットフォームは自分がタイトルリリースしそうな部分のみで。（おそらく後から変えられると思います。）

最後に、アクセスを拒否する国を選んで、、Createをクリックして完了です。
日本からのみアクセスを許可したい場合、→→を押して全部の国を拒否にした後、japanだけ「Access Allowed」に残しておく感じです。

![サービスを運用するリージョンを選択.png](https://qiita-image-store.s3.amazonaws.com/0/19010/bd78e58e-35a8-c9c9-56de-97b5d0900468.png)

（国の中にChinaがあるけど使えるのかしら）

## プラグインパッケージのインポート

unitypackageは以下からダウンロード可能です。
https://docs.gamesparks.com/sdk-center/unity.html

しばらく前まで、Unity Asset Storeの一等地に超でかい広告を出していたのですが、GDCを境にひっこめてしまったようです。

いつものようにUnityで新規プロジェクトを作り、Assets→Imports Packageから入れてしまいましょう。
すると、GameSparksの専用メニューが追加されます。

![追加されたメニュー.png](https://qiita-image-store.s3.amazonaws.com/0/19010/2f86aa3a-1b63-68ba-59c3-caf9ec8da4b9.png)

ここからUnityのProjectとGameSparks側のプロジェクトを紐づけます。Edit Settingsを開くと、GameSparks側の設定をするScriptable Objectがインスペクタに表示されます。

![Unity内でのGameSparksの設定.png](https://qiita-image-store.s3.amazonaws.com/0/19010/ed793b52-c87a-374c-5aad-607aa80154a6.png)

ここに、管理画面に表示されているAPI KeyとAPI Secretを入れていきます。
「Credential」はGameSparksへのアクセス制限プロファイルみたいなやつで、デフォルトは「device」に設定されています。
（独自の管理画面作ったりする際に利用する？調査中。。）

![Credential.png](https://qiita-image-store.s3.amazonaws.com/0/19010/f2caa79a-55f8-2a4c-9f35-5ce2969e6362.png)

API KeyとAPI Secretをいれたら、「Debug Build」にチェックを入れて「Test Configration」をクリックします。
するとエディタ再生が走り、テスト画面が自動で実行されます。
GameSparksには公寿酢する「Test Harness」と呼ばれるテスト機能を管理画面に持つのですが、同様のテストをUnityエディタ上で実行できる仕組みになります。

![TEST UI.png](https://qiita-image-store.s3.amazonaws.com/0/19010/5e44dab2-89d9-fd10-9ac8-177d322dde17.png)

左上に「Available」と表示されていれば、ひとまず接続成功です。

# リーダーボード(ランキング) にデータを送ってみる

手始めとして、リーダーボード（ランキング）機能を触っていくことにします。参考にしたドキュメントは次のものです。
https://docs.gamesparks.com/documentation/configurator/leaderboards/

## Eventの作成

GameSparksと通信を行う時は、Eventと呼ばれる関数を管理画面内で作成し、それをUnity側から叩く手順になります。
まずは、リーダーボードにスコアを送信するためのEventを作ってみましょう。

管理画面でConfigurator -> Eventを開き、「Add」ボタンから新規のEventを作成します。
一番上の「Short Code」は、Unityから通信するときのユニークな名前です。管理画面内の名前、説明文を書いてSaveを押すと作成されます。

![SENDSCOREイベント.png](https://qiita-image-store.s3.amazonaws.com/0/19010/2062ca56-0461-6d57-e53b-5e822d73a7fc.png)

続いて、このEventsがどんなデータを持つことができるのかを「Attributes」に設定していきます。「Attributes」の右端にあるAddボタンをクリックして、新規に作成します。

![アトリビュートの設定.png](https://qiita-image-store.s3.amazonaws.com/0/19010/7eef59e5-5290-3b66-55d0-3ba726d6d65d.png)

名前「Score」、コード内で呼び出すときのユニーク名は「SCORE」、値の方は数値、デフォルト値は0、集計するときのデフォルト設定はMaximum(Group by的なことをやろうとするときの設定？）にしておきます。
Save And Closeをクリックすると設定を保存してEvent一覧に戻ります。

## リーダーボードの作成

管理画面でConfigurator -> Leaderboardsに移動し、「Add」から新しいリーダーボードを作成してみましょう。

![Leaderboardに新規作成.png](https://qiita-image-store.s3.amazonaws.com/0/19010/1e183541-21c2-97f1-3a5b-9a24cd19444e.png)

とりあえすShort Codeは同じく「SCORE」で設定していきます。
リーダーボードに対しては週ごと・日ごとにランキングをリセットしたり、ハイスコアの際に津位置したりといった設定ができます。
Saveでいったん保存しましょう。

Eventの作成がうまくいっていれば、Fieldsの右端に「Add」ボタンが見えています。
Send Scoreイベントを選び、Save and Closeでリーダーボード一覧に戻ります。

## リーダーボードのテスト

作成したイベントが意図したとおりに機能するかどうか、管理画面の「Test Harness」でテストできます。
左メニュの「Test Harness」をクリックするとテスト画面が表示されます。

リーダーボードの機能を試すには、何らかの手段でユーザー認証しておく必要があります。とりあえずRequests下のAuthenticationから「RegistrationRequest」を選択し、ユーザー名・パスワード認証でユーザーを作成します。

![TestHarnessでユーザーを作成.png](https://qiita-image-store.s3.amazonaws.com/0/19010/efc484c7-f2f8-8661-ef0b-ac1391fb4ff8.png)

緑のSend Requestをクリックしてデバイスによる認証をしておきます。Connection欄にAuth Token、Player IDに値が入っていれば成功です。

次にRequests下の「Log Events」を選択します。「Send Score」と先ほど作成したEventが見えていると思いますので、クリックしてみましょう。

![TestHarnessのSendScore.png](https://qiita-image-store.s3.amazonaws.com/0/19010/d30c3eb3-c2b6-6cda-3fb9-f54ae8681f18.png)

JSONリクエスト内のSCOREの数値を自由に変えて、Send Requestをクリックします。これで、リーダーボードに値が保存されまいた。

逆にリーダーボードから値を取得してみましょう。JSONリクエスト欄に次の値を記入し、Send Requestをかけます。

```JSON
{
  "@class": ".LeaderboardDataRequest",
  "entryCount": 100,
  "leaderboardShortCode": "SCORE"
}
```

![リーダーボードの値の取得.png](https://qiita-image-store.s3.amazonaws.com/0/19010/03715a18-671c-22d5-2b30-f9b63dbfec55.png)

これでリーダーボード内のデータの取得ができることが確認できました。

## Unity Editorからスコアを送信

では、このリーダーボードにUnity Editorから書き込みを行ってみましょう。

初めに空のシーンを用意し、空のオブジェクトを作って「GameSparksUnity.cs」をアタッチします。
アタッチしたら、インスペクタのSettingフィールドに、先ほどAPIKEYなどを設定したScriptable Object「GameSparksSettings」の参照をいれます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19010/2aba40b1-5b15-09c6-054f-1f0803d7c72b.png)

なおこのオブジェクトはシーンに居続ける必要がありますが、Don'tdestroyonloadやシングルトン化が **されていません**　。
シーンが切り替わる際はGameSparksUnityがかぶったり消えたりしないようにしましょう。

続いてからのスクリプトを用意し、「ログイン」と「スコアの送信」を行うスクリプトを記述します。

```csharp

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameSparks.Api.Requests;

public class GameSparksLeadboardTest : MonoBehaviour
{
    private void Start()
    {
        new AuthenticationRequest().SetUserName("Testman").SetPassword("123456").Send((response) => {
            if (!response.HasErrors)
            {
                Debug.Log("Player Authenticated...");
                PostScore();
            }
            else
            {
                Debug.Log("Error Authenticating Player...");
            }
        });
    }

    private void PostScore()
    {
        new LogEventRequest().SetEventKey("SEND_SCORE").SetEventAttribute("SCORE", "1234").Send((response) => {
            if (!response.HasErrors)
            {
                Debug.Log("Score Posted Successfully...");
            }
            else
            {
                Debug.Log("Error Posting Score...");
            }
        });
    }
}

```

かなり雑ですが、Start()時にログイン処理を行い、成功したらPostScore()を呼びます。
ログイン時には「SetUserName」に先ほとTest Harnessで作成したユーザー名、「SetPassword」にパスワードを使用します。

PostScore()内では「SetEventKey」にEventで作成したShortCodeである「SEND_SCORE」を指定し、アトリビュートにSCORE、値は適当に設定します。
これでエディタ実行を行うと、ログイン処理とリーダーボードへのスコア送信が行われます。


![スコアデータのポスト成功.png](https://qiita-image-store.s3.amazonaws.com/0/19010/47a4035e-f088-48db-d7b7-4220ca86c25f.png)

コンソールにSuccessfullyと表示されたら、管理画面に戻ってデータが保存されているか確認してみましょう。
先ほどと同じようにTest Harnessからリクエストして確認することもできますが、今回は「Data Explorer」という機能から、リーダーボードにどんなデータが突っ込まれているかを直接確認しましょう。

左メニューから「Data Explorer」を選び、しばらく待つかCollectionsのリロードボタンをクリックします。
表示された「Leaderboards」から自分で作成したリーダ－ボードを選択します。

データが大量にある場合はここでクエリ（検索条件）やらを指定しますが、いまは2つ3つだと思うのでFindをクリックします。
すると、リーダーボード内に入っている生データがガバッと表示されます。

![DataExplorer.png](https://qiita-image-store.s3.amazonaws.com/0/19010/1960f3cc-3228-d17a-0793-99fd1f864e45.png)

先ほどUnityから送信したデータが確認できたら、成功です！

# とりあえず触ってみて

ひとまずデータを出し入れしただけですが、実装難易度の高さはFirebase > GameSparks > NCMBという順かなと感じました。
データを送るために何段階か手数は必要ですが、そのかわり自由度の高い運用ができそうです。

他のBaaSにない魅力として、リアルタイムのマルチプレイをサポートしている点が個人的に気になっています。
次回はリーダーボードのUnityEditor上での表示か、マルチプレイ回り調査してみようと思います。

ただjsまったく分からないマンなので、Cloud Codeを使ったサーバー側機能開発とかは誰か書いてもらえると嬉しい。。。

追記：続き書きました。ランキングデータのアプリでの取得とサインイン処理について書いています。　https://qiita.com/Takaaki_Ichijo/items/9249999aad5b0bfdaf2b