Unityを使ってiOS/Androidのマルチプラットフォームアプリを開発している際に難点となるのが機種変対応、いわる「端末引っ越し」への対応です。 iOS→iOSや、Android→Androidならば、それぞれのOSが提供しているサービスを使ってクラウドにデータを保存することは出来るのですが、大概のゲームは両OSに出していますので、これに頼ることはできません。
そこでニフティクラウドmobile backendの登場です。「会員管理」機能を使えば、誰でも簡単にクラウドにセーブデータを保存する機能をゲームに加えることができます。 端末引っ越し時に明示的にクラウドへバックアップするアプローチを作ることもできます。 最初からクラウドセーブにしてしまうことで、端末の突然の死がおきても別の端末から続きが遊べますし、外でiPhone、家ではPCで続きを遊ぶ、みたいなことも可能になります。
Unity PlayerPrefsのおさらい
Unityのユーザーセーブ機能であるPlayerPlefs,便利ですよね。Windowsで動かすと レジスタに値を突っ込むという仕様はさておき、iOS/Androidで共通したセーブの仕組みを手っ取り早く実装できます。
Unity - スクリプトリファレンス: PlayerPrefs
using UnityEngine; using System.Collections; public class UserDataController: MonoBehaviour { //点数を保存// public void SetScore(int score) { PlayerPrefs.SetInt("Score", score); PlayerPrefs.Save(); } //点数を取得// public int GetScore(int score) { return PlayerPrefs.GetInt("Score"); } }
扱える型はint, string, floatです。その他、値を削除するDeleteKeyや存在確認のHasKey、 変更した値を書き込むSaveなどがあります。
この手軽さを保ったままクラウドセーブ対応したい
シンプルな分実装しやすいPlayerPrefsなのでゲームのセーブデータ保存に使っている開発者は多いと思います。 で、冒頭にあげたiOS/Android間の機種変対応をする場合にもこれと同等の使い勝手で実装できたらいいなぁ..というのが発想のスタートです。
NCMBのセットアップと前準備
まずはクイックスタートを参照してもらいまして、Unity SDKの導入とアカウント取得、APIキーの取得等を済ませておいて下さい。
その後、「【Unity】アプリにログイン機能をつけよう!」のチュートリアルを済ませます。
続いて、下記のスクリプトファイルをプロジェクトに追加します。
using UnityEngine; using NCMB; public class NCMBPlayerPrefs : MonoBehaviour { public static int GetInt(string keyName) { //キーが存在する場合は値を取得します// //存在しない場合は defaultValue を返します。// int value; if (NCMBUser.CurrentUser != null) { value = (int)NCMBUser.CurrentUser[keyName]; } else { value = 0; } return value; } public static void SetInt(string keyName, int value) { //キーを保存します// NCMBUser.CurrentUser[keyName] = value; } public static void Save() { //操作結果を保存します// NCMBUser.CurrentUser.SaveAsync(); } public static bool HasKey(string key) { //キーが存在するか確認します// return NCMBUser.CurrentUser.ContainsKey(key); } public static void DeleteKey(string key) { //対応するキー(フィールド)を削除します// NCMBUser.CurrentUser.Remove(key); } }
SetString, SetFloatは実装方法がほとんど一緒なので省略しています。
これで NCMBPlayerPrefs.SetInt()でクラウドセーブが可能になりました。
テスト
「スコアを保存する」というシチュエーションを想定して、今作った機能を試してみましょう。
下記のスクリプトをログイン後のシーンに貼り付け、シーン内にuGUIのInputFieldとButtonを設置します。 「【Unity】アプリにログイン機能をつけよう!」のサンプルの場合はLogOut.unityのシーンが該当します。
using UnityEngine; using UnityEngine.UI; using System; public class SaveTest : MonoBehaviour { public Text scoreInput; public void SaveScore() { Debug.Log("Score "); int scoreInt = Convert.ToInt32(scoreInput.text); NCMBPlayerPrefs.SetInt("Score", scoreInt); NCMBPlayerPrefs.Save(); } }
インスペクタ上でscoreInputにInputFieldのtextの参照を入れ、
ButtonのOnClickイベントからSaveScore()を呼び出すように設定します。
ゲームを起動してログイン後、InputFieldに適当な値を入れてボタンを押しましょう。
その後、管理画面にアクセスして今保存したデータを確認します。
「Score」というフィールドが作られて、値が保存されていれば成功です。
これでNCMBPlayerPrefs.GetInt("Score")とやってやれば、この値を取得することができます。 もちろん他の端末でも、同じIDでログインしていれば同じ値が取得できます。
オフライン時の処理
NCMBPlayerPrefsは非常にシンプルな実装ですが、のこる問題として「モバイルは常にオンラインではない」という点があります。
上記で紹介したコードをそのままゲームに組み込んでしまうと、「オンライン時にしかセーブできない」という無茶苦茶なゲームに...。
ということで、今後は「オフライン時の挙動」を追加したサンプルを作ろうと思います。ただ、その昨日まで含めると冗長になりますので、 前回ご紹介した「UnityでAPIキーをJSONファイルから設定できるようにするには?」の機能も含めた、「NCMB SDK for Unity をもっと便利に使うためのコード集」を現在準備中です。 githubに公開してだれてもお使いいただけるようにする予定です。いましばらく、お待ち下さい~。