チュートリアル(Unity)
ハイスコアをサーバーに保存する
概要
このページでは、mobile backendを使ってハイスコアをサーバー(データストア)に保存する方法を学びます。
配布されているサンプルプロジェクトの元の状態では、ハイスコアは端末内のファイルに書き込まれて保存されています。ハイスコアを管理しているのは、「Score」というクラスです。そこで今回は、ハイスコアをファイルではなくデータストアに保存するように、「Score.cs」を書き換えていきます。
なお、ログイン機能を実装していない場合は、「ログイン機能を作る」を先に済ませておいてください。
HighScoreクラスを定義する
今回は、mobile backendとやりとりしてハイスコアの保存と取得を行うクラスを先に定義していきましょう。
Scriptsフォルダの中に「HighScore.cs」という名前のC#スクリプトを新規作成し、下記の内容を記述してください。
using NCMB;
using System.Collections.Generic;
namespace NCMB
{
public class HighScore
{
public int score { get; set; }
public string name { get; private set; }
// コンストラクタ -----------------------------------
public HighScore(int _score, string _name)
{
score = _score;
name = _name;
}
// サーバーにハイスコアを保存 -------------------------
public void save()
{
// データストアの「HighScore」クラスから、Nameをキーにして検索
NCMBQuery<NCMBObject> query = new NCMBQuery<NCMBObject> ("HighScore");
query.WhereEqualTo ("Name", name);
query.FindAsync ((List<NCMBObject> objList ,NCMBException e) => {
//検索成功したら
if (e == null) {
objList[0]["Score"] = score;
objList[0].SaveAsync();
}
});
}
// サーバーからハイスコアを取得 -----------------
public void fetch()
{
// データストアの「HighScore」クラスから、Nameをキーにして検索
NCMBQuery<NCMBObject> query = new NCMBQuery<NCMBObject> ("HighScore");
query.WhereEqualTo ("Name", name);
query.FindAsync ((List<NCMBObject> objList ,NCMBException e) => {
//検索成功したら
if (e == null) {
// ハイスコアが未登録だったら
if( objList.Count == 0 )
{
NCMBObject obj = new NCMBObject("HighScore");
obj["Name"] = name;
obj["Score"] = 0;
obj.SaveAsync();
score = 0;
}
// ハイスコアが登録済みだったら
else {
score = System.Convert.ToInt32( objList[0]["Score"] );
}
}
});
}
}
}
ハイスコアの取得と保存には、NCMBQueryクラスを用います。WhereEqualToメソッドで条件を指定したあと FindAsyncメソッドでレコードを取得、というのが基本的な流れになっています。条件の指定方法は、今回用いたWhereEqualTo以外にも色々なものが用意されています。詳しくはSDKリファレンスをご覧下さい。
ソースコードをアタッチせずに使う
今回は、このHighScore.csをGame Objectにアタッチしないで使いましょう。ゲームオブジェクトにアタッチせずに使う利点は、以下のようなものがあります。
- Unityに依存しない (Startメソッドなどを実装しない) コードを書くことができる
- 他のシーンでも、そのクラスを使うことができる
今回実装したHighScoreクラスは、MVCデザインパターンでいうモデルクラスにあたります。その場合、このようにUnityに依存しない形でコードを書くほうがよいでしょう。実際このクラスは、Unityを使わずに単体テストを行うことができます。
Scoreクラスを修正する
それでは次に、既存のScoreクラスを修正して、先ほど定義したHighScoreクラスを使ってハイスコアを管理するようにしていきましょう。同時に、サーバーへの通信(ハイスコアの取得と保存)ができるだけ少なくなるようなロジックも盛り込んでいきます。
Score.csを開き、highScoreフィールドの定義を以下のように修正します。
// ハイスコア
// 以下の行を削除
// private int highScore;
// 代わりに以下の2行を追加
private NCMB.HighScore highScore;
private bool isNewRecord;
// PlayerPrefsで保存するためのキー
// もうローカルには保存しないので、以下の行は削除
// private string highScoreKey = "highScore";
次に、Updateメソッドを以下のように修正します。
先ほど定義したHighScoreクラスのscoreプロパティを参照するようにします。
void Update ()
{
// スコアがハイスコアより大きければ
if (highScore.score < score) {
isNewRecord = true; // フラグを立てる
highScore.score = score;
}
// スコア・ハイスコアを表示する
scoreGUIText.text = score.ToString ();
highScoreGUIText.text = "HighScore : " + highScore.score.ToString ();
}
つづいて、StartメソッドとInitializeメソッドを修正します。ローカルファイルからハイスコアを読み込む代わりに、サーバーから取得する(先ほど定義したHighScore.fetchメソッドを使う)ように変更します。ただし、Initializeメソッドはゲームオーバーのたびに呼び出されている(Manager.csを参照)ので、スコアの取得はInitializeメソッドではなくStartメソッドで行うようにします。
void Start ()
{
Initialize ();
// ハイスコアを取得する。保存されてなければ0点。
string name = FindObjectOfType<UserAuth>().currentPlayer();
highScore = new NCMB.HighScore( 0, name );
highScore.fetch();
}
private void Initialize ()
{
// スコアを0に戻す
score = 0;
// フラグを初期化する
isNewRecord = false;
}
最後に、Saveメソッドを以下のように修正し、ハイスコアをサーバーに保存するようにします。
// ハイスコアの保存
public void Save ()
{
// ハイスコアを保存する(ただし記録の更新があったときだけ)
if( isNewRecord )
highScore.save();
// ゲーム開始前の状態に戻す
Initialize ();
}
動作確認
ここまでできたら、1度動作確認をしてみましょう。以下のことが確認できるはずです。ただし、動作確認はLogInシーンを開いてから行ってください。
- ログインしてゲームを遊ぶと、mobile backendの管理画面内「データストア」メニューに「HighScore」クラスが作成され、ハイスコアが記録されている
- 一度ログアウトして再度ログインすると、保存したハイスコアがゲーム画面右下に表示される
お探しの内容が見つからなかった場合はユーザーコミュニティ
もご活用ください。(回答保証はいたしかねます)
なお、 Expertプラン以上のお客様はテクニカルサポートにてご質問を承らせて頂きます。
推奨画面サイズ1024×768px以上