【Unity】NCMBを使ってサーバにデータを保存、取得する方法
Unity1Weekというゲームジャムで、以下の動画のような「敵に見つからないように壁に文章を書き残す」「書き残した文章は他のプレイヤーの画面に表示される」というシステムのゲームを作成しました。
その際「書き残された文章をサーバに保存して」「サーバに保存された文章を取得して表示する」という処理をするのに、NCMB(ニフティ クラウド モバイル バックエンド)というサービスを利用したので、使い方をまとめておきます。

なお、作ったゲームは以下のリンクからプレイできますので、実際の見え方を知りたい場合は試してみてください。
ゲームはこちらからプレイできます環境
- Unity 2018.1.2f1
このページの構成
ポイント
- NCMBはゲームアプリなどのサーバ側の処理(データの保存・取得やプッシュ通知など)を簡単に行うことができるようになるサービス(いわゆるmBaaS)
- 自分でサーバを用意しなくてもよく、ある程度のアクセスまでは無料で利用できる
- 「データの保存」では「サーバからデータ登録件数を取得」「登録件数に+1したIDを作成」「IDとテキストをセットでサーバに保存」という処理を説明
- 「データの取得」では「サーバからデータ登録件数を取得」「ランダムなIDを複数生成」「該当するIDのテキストを取得」という処理を説明
事前準備
NCMBの準備
まずはNCMBを利用できるようにしないといけないので、アカウントの登録やらアプリの登録やらをしておきます。
以下の公式リファレンスで丁寧に手順が説明されてますので、こちらを参考に「APIキーの設定とSDKの初期化」まで進めてください。
ちなみに料金等については以下のリンクをご覧ください。APIリクエスト200万回/月まで無料で使えるなど、個人で使う分にはほぼ問題ないんじゃないかなと思います。
料金サーバにテキストを保存する
処理の流れ
はじめに、ここで説明している処理の流れを簡単に説明しておきます。
- ① プレイヤーがInput Fieldにテキストを入力して送信ボタンを押す
- ② サーバからデータの登録件数を取得する
- ③ 登録件数に+1して連番のIDを作成する
- ④ IDと入力されたテキストをセットにしてサーバに保存する
Unityの準備
プレイヤーがテキストを入力する欄とボタンを用意します。
「create」-「UI」から「Input Field」と「Button」を作成してください。

適当でいいのですが、ここでは上記の画像のような感じで「Input Field」と「Button」を作成しました。それぞれ名前を”RakugakiField”と”RakugakiButton”という名前にしています。
ボタンとフィールドを「UI_Input」というオブジェクトの子要素にしてまとめていますが、特に必要ではないので、まとめなくても大丈夫です。
それでは次のセクションで「サーバに保存する文章を書く」のところに書かれたテキストを、「サーバに保存する」ボタンを押した時に保存する処理を作っていきます。
サーバーにテキストを保存する
サーバにデータを保存する処理を追加していきます。
以下のスクリプトを作成したInput Fieldにアタッチしてください。ここでは”InputController”という名前でスクリプトを作成しています。最初の”using〜”のところに色々追加しているので忘れないように注意してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; using UnityEngine.UI; using NCMB; using System; public class InputController : MonoBehaviour { // 入力されたテキストへの参照保存用 private Text _rakugakiText; // NCMBを利用するためのクラス private NCMBObject _testClass; private NCMBQuery<NCMBObject> _query; void Start () { // Input Fieldの子要素のText(=入力されたテキスト)への参照を保存 _rakugakiText = transform.Find("Text").GetComponent<Text>(); } public void SaveRakugaki() { var message = _rakugakiText.text; // 何も入力されていなければ処理しない if(message == "") return; // ここからデータの保存処理開始 // 検索にはNCMBQueryを使う _query = new NCMBQuery<NCMBObject> ("TestClass"); // 保存されているデータ件数を取得 _query.CountAsync((int count , NCMBException e )=>{ if(e != null){ //件数取得失敗時の処理 Debug.Log("件数の取得に失敗しました"); }else{ //データ件数が取得できていたらサーバにデータを送る SendRakugakiData(count); } }); } void SendRakugakiData(int count) { // ここで指定したクラス名(=RakugakiClass)でNCMBのデータストアに登録される // データストアにそのクラスがなければNCMB側で新規作成してくれる // データを送る時に、newしておかないと追加ではなく上書き保存されるので注意 _testClass = new NCMBObject("TestClass"); // NCMBオブジェクトに値を設定する // [ ]内に設定した項目名でデータストアに登録される _testClass["id"] = count + 1; // データ保存件数に+1して連番のidを作成 _testClass["message"] = _rakugakiText.text; // 入力されたテキストをセットで設定 // データストアへデータを登録する _testClass.SaveAsync ((NCMBException e) => { if (e != null) { //件数取得失敗時の処理 Debug.Log("データの保存に失敗しました"); } else { //成功時の処理 Debug.Log("データの保存に成功しました"); } }); } } |
ボタンのオンクリックイベントにこのスクリプトの”SaveRakugaki”を指定すれば準備は完了です。
ゲームを再生し、何か入力してボタンをクリックしてみてください。

上の動画のように、ログに”データの保存に成功しました”というメッセージが表示されていればOKです。
NCMBのダッシュボードを開き、「データストア」から先ほどのスクリプトで指定したクラス名のデータを開いてください。入力したテキストが表示されていると思います。

サーバに保存された文章を取得する
Unityの準備
次に、サーバから保存したテキストを取得して表示する処理を追加していきます。
サーバから取得したデータを表示するUIを追加します。「create」-「UI」から「Text」を作成してください

こちらも適当でいいのですが、ここでは上記の画像のような感じで「UI_Output」というパネルの子要素としてTextを作成しました。
こちらも見やすいように、という以外の意味はないので、Panelはなくても大丈夫です。
サーバーからテキストを取得する
サーバからデータを取得する処理を追加していきます。
以下のスクリプトを先ほど作成したTextにアタッチしてください。ここでは”OutputController”という名前でスクリプトを作成しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; using UnityEngine.UI; using NCMB; using System; public class OutputController : MonoBehaviour { // 取得したデータ表示用のテキストへの参照保存用 private Text _outputText; // NCMBを利用するためのクラス private NCMBQuery<NCMBObject> _query; // データを最大何個取得するか private const int MAX = 3; void Start () { _outputText = GetComponent<Text>(); // テキストの取得を開始する LoadText(); } void LoadText() { _query = new NCMBQuery<NCMBObject> ("TestClass"); // 保存されているデータ件数を取得 _query.CountAsync((int count , NCMBException e )=>{ if(e != null){ //件数取得失敗時の処理 Debug.Log("件数の取得に失敗しました"); }else{ //ラクガキを取得 GetTextData(count); } }); } //テキストをMAX個ランダムに実際に取得する void GetTextData(int dataNum) { // ランダムな番号をmax個作る var ary = Enumerable.Range(1, dataNum).OrderBy(n => Guid.NewGuid()).Take(MAX).ToArray(); // 取得するidのリストを作成 List<int> request = new List<int>(); // データベースに保存されている文章の数がMAXに満たない場合 if(dataNum < MAX) { for(int i=0; i<dataNum; i++) { request.Add(ary[i]); } } else // テキストが十分にある場合 { for(int i=0; i<MAX; i++) { request.Add(ary[i]); } } //リストを元にRakugakiClassからデータを取得する _query.WhereContainedIn ("id", request); //データを検索し取得 _query.FindAsync ((List<NCMBObject> objectList,NCMBException e) => { //取得失敗 if(e != null){ //エラーコード表示 Debug.Log("データの取得に失敗しました"); return; } //取得した全データのmessageを表示 foreach (NCMBObject ncbObject in objectList) { var text = ncbObject ["message"].ToString(); ShowText(text); } }); } // テキストを表示する void ShowText(string text) { _outputText.text += text; } } |
ここまで完了したらゲームを再生してみてください。
サーバに保存されたテキストが追加して表示されていると思います。
