【コピペで実装】Unityで作ったゲームにランキング機能を追加してみた

# 概要

Unityで作ったアプリにランキング機能を追加する方法を紹介します👌 
コピペで実装できるので初心者の方でも簡単に実装できます👫

# 使うサービス
* **ニフクラ mobile backend（Unity SDK）**

**無料**で利用可能できるサービスで、簡単にバックエンドの開発ができるニフクラ mobile backendを利用してランキング機能を実装していきます。
以下より会員登録を行うと、**環境構築する必要なし**にすぐ利用できます👩‍💻👨‍💻

##### 会員登録

https://mbaas.nifcloud.com/

Unity SDKのドキュメントは[こちら](https://mbaas.nifcloud.com/doc/current/#/Unity)です👀
ニフクラ mobile backendのサービスの概要は[こちら](https://mbaas.nifcloud.com/)をご参照ください👀

# Unityとの連携方法
ニフクラ mobile backendの[クイックスタート](https://mbaas.nifcloud.com/doc/current/introduction/quickstart_unity.html)で画像を用いながらわかりやすく説明しているので 是非以下を参考に連携させてみてください😃✨

▼イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492105/9743e2cb-7601-791d-9bfd-f6e226557cf9.png)

##### クイックスタート
https://mbaas.nifcloud.com/doc/current/introduction/quickstart_unity.html

# ランキング機能の実装手順
ランキング機能を実装するためには

* データストア（DB）にユーザー名とスコアを保存
* データストアに保存されているデータをスコア降順で5件取得
* ユーザーネームとスコアを画面表示

という順番で実装していきます。

このアプリは、ログイン中のユーザー（カレントユーザー）を認識してゲームで遊んでいるため、ユーザーはログインしている必要があります。
Unityで作ったアプリにログイン機能を追加する方法は別途ブログで公開していますので まだ実装されていない方はそちらからご覧ください👩‍💻👨‍💻

https://qiita.com/itominami/items/a4a86309504fa269e824

## データストア（DB）にユーザー名とスコアを保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492105/1e3f3be1-c931-72dd-9685-2a0d96fdcb6e.png)

私は今回ブロック崩しゲームにランキング機能を付けました。 定義は以下です。

* ブロックが1個ボールに当たるごとに点数が+100点
* 成功しても失敗しても**「data」クラス**にスコアとユーザーネームが保存される
* データストアにデータ（ユーザーネームとスコア）を保存する場合のコードは以下です。

（★の部分が今回ニフクラ mobile backendのコードです。他の箇所はゲームの処理です。）

```c#
using System;
using UnityEngine;
using NCMB;

public class Ball : MonoBehaviour
{
    Rigidbody rigid;
    GameManager manager;

    public string currentUserName;
    
    [SerializeField]
    int speed = default;
    //スコアは0からスタート
    int score = 0;
    // ★クラスのNCMBObject（data）を作成
    NCMBObject data = new NCMBObject("data");

    void Start()
    {
        //ゲームの中身
    }

    void OnCollisionEnter(Collision collision)
    {
        // ボールの移動速度を一定にする処理など
        // ボールがブロックに衝突した場合
        if (collision.gameObject.name.StartsWith("Block", StringComparison.Ordinal))
        {
            // ブロックを削除
            Destroy(collision.gameObject);
            GameManager.Instance.BlockCount--;
            //点数を追加
            score += 100;
        }
         
            // クリアした場合
            if (manager.IsClear()){
                manager.EndGame("Game Clear!");

                // ★カレントユーザーの確認
                NCMBUser currentUser = NCMBUser.CurrentUser;
                   if (currentUser != null) {
                        UnityEngine.Debug.Log ("ログイン中のユーザー: " + currentUser.UserName);
                    } else {
                        UnityEngine.Debug.Log ("未ログインまたは取得に失敗");
                    }
                    // ★UserNameとscoreを「data」クラスに保存する
                    data["score"] = score;
                    data["UserName"] = currentUser.UserName;
                    // ★データストア（「data」クラス）への登録
                    data.SaveAsync();

            return;
            }

        // ゲームオーバーの場合も同じ
        if (manager.IsGameOver()){
            //失敗した際の処理を書く
            //★ニフクラ mobile backendの処理は上と同じ
        }
    }
}
```

ニフクラ mobile backendのデータストア（「data」クラス）にも保存されていることを確認できました💮
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492105/e1db7930-ae6f-f2d5-2a09-b2ad96f6d48a.png)

## データストアに保存されているデータをスコア降順で5件取得して表示させる

* データストアに保存されているデータをスコア降順で5件取得
* ユーザーネームとスコアを画面表示

は1ファイルにまとめて書いています。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NCMB;
using System.Linq;
using UnityEngine.UI;

public class RankingHyoji : MonoBehaviour

{
    public Text targetText; 
    void Start () {
        //順位のカウント
        int count = 0;
        string tempScore = "";
        //★ データストアの「data」クラスから検索
        NCMBQuery<NCMBObject> query = new NCMBQuery<NCMBObject>("data");
        //★Scoreフィールドの降順でデータを取得
        query.OrderByDescending ("score");
        //★検索件数を5件に設定
        query.Limit = 5;
        query.FindAsync ((List<NCMBObject> objList ,NCMBException e) => {
                if (e != null) {
                  UnityEngine.Debug.Log ("ランキング取得失敗");
                } else {
                    //検索成功時の処理
                    UnityEngine.Debug.Log ("ランキング取得成功");
                        // 値とインデックスのペアをループ処理
                        foreach (NCMBObject obj in objList)
                        {
                            count++;
                             //★ユーザーネームとスコアを画面表示
                            tempScore += count.ToString() + "位：" + "：ユーザーネーム：" + obj ["UserName"] + "：スコア：" + obj ["score"] + "\r\n";
                        }
                        targetText.GetComponent<Text>().text = tempScore;
                }                     
         });
    }
}
```

# 結果

以上で、ランキング機能が追加できました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492105/7384819e-c2b8-c646-3859-e35b05005ec5.png)

不明点があれば[ユーザーコミュニティ](https://github.com/NIFCLOUD-mbaas/UserCommunity)へ質問してみてください！(無料プランから利用可能)
有償プランを契約している方は[テクニカルサポート](https://portal.support.nifcloud.com/hc/ja/articles/1500006058861)で個別にサポートしていただけます！