25
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Azure PlayFabのとても便利なランキング機能を使ってみた&ついでにランキング報酬も配ってみた

まえがき

オンラインゲームにかかせないランキング機能、自分で作るのは少し面倒ですよね。
PlayFab にはユーザーのランキングを管理したり、ランキングに応じて報酬を配ったりできる機能があります。

試しに使ってみたところ、とても便利な機能だったので記事に残しておこうと思います。

成果物

※ゲームプレイ後に超簡易的なランキング画面が表示されます。
JumpRope.gif

使用する PlayFab の API

1. 事前準備

1.1. クライアントから PlayFab への統計情報のポストを許可しておく

PlayFab は統計情報(スコアなど)をクライアントから送信することをデフォルトでは禁止しています。

チート対策のために基本的にはサーバー側で処理してね、とのことですが今回は個人制作の趣味のゲームですし、クライアントからサクッと値を送信したいと思います。

そのために GameManager の設定画面で クライアントにプレイヤー統計情報のポストを許可する を有効にします。
image.png

これを忘れるとクライアントから統計情報を送信したときに下記のエラーがでるので注意してください。
image.png

1.2. ランキングの定義を作成しておく

GameManager で新しいランキングを作成します。
image.png

続いてどのようなランキングを作成するか決めます。
image.png

  • 統計情報名
    わかりやすい名前ならなんでも大丈夫です。
    一度決めると変更できないので慎重に。

  • リセット頻度
    今回は手動にしますが、毎時/毎日/毎週/毎月なども選べます。
    ランキングリセットの際は自動で報酬を配布したりすることもできます。(後述)

  • 集計方法
    今回はプレイヤーごとの最多ジャンプ成功数をランキング表示したいので 最大 にしておきます。

1.3. ユーザーの DisplayName を登録しておく

ランキングにユーザー名を表示するためにはユーザーの DisplayName を登録しておく必要があります。
ゲーム内でユーザー名を設定する画面を作り、以下のようなコードで PlayFab へ登録しておきましょう。

    private void SetUserName(string userName)
    {
        var request = new UpdateUserTitleDisplayNameRequest
        {
            DisplayName = userName
        };

        PlayFabClientAPI.UpdateUserTitleDisplayName(request, OnSuccess, OnError);

        void OnSuccess(UpdateUserTitleDisplayNameResult result)
        {
            Debug.Log("success!");
        }

        void OnError(PlayFabError error)
        {
            Debug.Log($"{error.Error}");
        }
    }

ちなみに登録した DisplayName は GameManager のプレイヤー一覧などにも自動的に表示されます。
地味に嬉しいですね!
image.png

2. ランキングの実装

2.1. 統計情報(スコア)の送信

以下のようなコードで統計情報を送信することができます。

    private void SendPlayScore(int score)
    {
        var statisticUpdate = new StatisticUpdate
        {
            // 統計情報名を指定します。
            StatisticName = "JumpCount",
            Value = score,
        };

        var request = new UpdatePlayerStatisticsRequest
        {
            Statistics = new List<StatisticUpdate>
            {
                statisticUpdate
            }
        };

        PlayFabClientAPI.UpdatePlayerStatistics(request, OnSuccess, OnError);

        void OnSuccess(UpdatePlayerStatisticsResult result)
        {
            Debug.Log("success!");
        }

        void OnError(PlayFabError error)
        {
            Debug.Log($"{error.Error}");
        }
    }

※送信した統計情報がランキングに反映されるまで1~2秒かかる場合があります。
※ですので送信後すぐにランキングを取得するような設計は控えましょう。
こちらの記事で詳しく解説されています。

2.2. ランキングの取得

以下のようなコードでランキングを取得することができます。

    private void GetRanking()
    {
        var request = new GetLeaderboardRequest
        {
            StatisticName = "JumpCount", // 統計情報名を指定します。
            StartPosition = 0, // 何位以降のランキングを取得するか指定します。
            MaxResultsCount = 100 // ランキングデータを何件取得するか指定します。最大が100です。
        };

        PlayFabClientAPI.GetLeaderboard(request, OnSuccess, OnError);

        void OnSuccess(GetLeaderboardResult leaderboardResult)
        {
            // 実際は良い感じのランキングを表示するコードにします。
            foreach (var item in leaderboardResult.Leaderboard)
            {
                // Positionは順位です。0から始まるので+1して表示しています。
                Debug.Log($"{item.Position + 1}位: {item.DisplayName} - {item.StatValue}回");
            }
        }

        void OnError(PlayFabError error)
        {
            Debug.Log($"{error.Error}");
        }
    }

実行すると以下のような結果が得られます。
これを良い感じに UI に組み込むだけでランキングの完成です!
image.png

ちなみにランキングのデータは GameManager で確認することが可能です。便利ですね。
image.png

そういえば今回は1位からのランキングを取得/表示しましたが、実際は自分の+-5位のランキングを表示したかったりすると思います。

その場合は GetLeaderboard の代わりに GetLeaderboardAroundPlayer を使います。
コードは殆ど同じです。

    private void GetRanking()
    {
        var request = new GetLeaderboardAroundPlayerRequest
        {
            StatisticName = "JumpCount", // 統計情報名を指定します。
            MaxResultsCount = 11 // 自分と+-5位をあわせて合計11件を取得します。
        };

        PlayFabClientAPI.GetLeaderboardAroundPlayer(request, OnSuccess, OnError);

        void OnSuccess(GetLeaderboardAroundPlayerResult leaderboardResult)
        {
            // 実際は良い感じのランキングを表示するコードにします。
            foreach (var item in leaderboardResult.Leaderboard)
            {
                // Positionは順位です。0から始まるので+1して表示しています。
                Debug.Log($"{item.Position + 1}位: {item.DisplayName} - {item.StatValue}回");
            }
        }

        void OnError(PlayFabError error)
        {
            Debug.Log($"{error.Error}");
        }
    }

ゲーム内の実装の話はここまでです。
最後にランキング報酬を配ってみましょう。

3. ランキング報酬の配布

GameManager でランキングを開きます。
image.png

プライズテーブルを開いて、新しいプライズテーブルを作成します。
image.png

ランキング1~5位には魔法石10個、6~10位には魔法石5個を配る設定を作ってみました。
画面が直感的に操作できて素敵です。(スクショが長くてごめんなさい)
image.png
※アイテムは複数種類を一度に配布することも可能です。
※無料プランではランキング10位までしか報酬を配れないので注意してください。
※$99.99課金すると1000位まで配れるようになります。
※報酬を配る以外にも、ランキングに応じてメールを送信する、プッシュ通知を送る、自分で書いたスクリプトを実行するなどの処理が可能です。

JumpCount のランキング表示に戻って、今すぐリセットを押します。
イベントが終わったらポチッとリセットする感じの運用ですね。
image.png

確認画面が表示されるのでリセットしてください。
これでランキングがリセットされて、同時に報酬が配布されます。
image.png

先程1位だったNishiさんのインベントリを覗いてみると、ちゃんと魔法石が配布されていますね。
image.png

あとがき

ゲームにランキングを簡単に実装できると聞いて試してみましたが、想像以上に簡単で驚きました。
報酬の配布もとても便利で最高ではないでしょうか。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
25
Help us understand the problem. What are the problem?