ゲーム開発
Unity
UnrealEngine
C++
Blender
ゲーム数学
ゲームAI
グラフィックス
サウンド
アニメーション
GBDK
制作日記
IT関連
ツール開発
フロントエンド関連
サーバサイド関連
WordPress関連
ソフトウェア設計
おすすめ技術書
音楽
DTM
楽器・機材
ピアノ
ラーメン日記
四コマ漫画
その他
おすすめアイテム
おもしろコラム
  • ゲーム開発
    • Unity
    • UnrealEngine
    • C++
    • Blender
    • ゲーム数学
    • ゲームAI
    • グラフィックス
    • サウンド
    • アニメーション
    • GBDK
    • 制作日記
  • IT関連
    • ツール開発
    • フロントエンド関連
    • サーバサイド関連
    • WordPress関連
    • ソフトウェア設計
    • おすすめ技術書
  • 音楽
    • DTM
    • 楽器・機材
    • ピアノ
  • ラーメン日記
    • 四コマ漫画
      • その他
        • おすすめアイテム
        • おもしろコラム
      1. ホーム
      2. 20201201_01

      【Unity】第三回 ソーシャルゲームを作る 〜JSONファイルでのマスタ管理〜 【AWS x Laravel】

      UnityLaravelサーバサイド関連AWSソーシャルゲーム
      2020-12-07

      マイケル
      マイケル
      みなさんこんにちは!
      マイケルです!!
      エレキベア
      エレキベア
      クマ〜〜〜〜〜!!
      マイケル
      マイケル
      前回に引き続いて、ソシャゲ作成を進めていくぞ!
      エレキベア
      エレキベア
      前回はユーザ登録処理まで実装したクマね
      マイケル
      マイケル
      うむ!
      今回は JSONファイルを使用したマスタデータの管理
      を実装していくぞ!
      エレキベア
      エレキベア
      クマ〜〜〜〜〜〜

      参考書籍

      マイケル
      マイケル
      参考書は引き続き、こちらを参考に進めていきます!

      エレキベア
      エレキベア
      お馴染みクマ〜〜〜〜

      JSONファイルでのマスタ管理

      マイケル
      マイケル
      まずはマスタ管理の方法について!
      マイケル
      マイケル
      マスタデータは直接DBを参照せずに、
      別ファイルに切り出して管理することも多いです。
      マイケル
      マイケル
      今回はマスタバージョンは定数クラスに設定し、
      下記のようにJSONファイルとしてバージョンごとに切り出して管理します。

      ↑JSONファイルを使用してマスタデータを管理する
      エレキベア
      エレキベア
      なんで別ファイルに切り出す必要があるクマ??
      マイケル
      マイケル
      ユーザ側とサーバ側が参照するデータを一致させるためと、
      全マスタテーブルのバージョンを揃えるためだよ。
      DBを直接参照するようだと、ユーザで表示している内容と実際のマスタ内容が食い違ってしまう可能性があるからね。
      マイケル
      マイケル
      クライアントとサーバで参照しているバージョンが違う場合には
      「アップデートしてください。」というメッセージを表示するようにするんだ!
      エレキベア
      エレキベア
      なるほどクマ
      ユーザ側で100円で購入しようとしたら
      実は500円引かれてたりしたら大問題クマね
      マイケル
      マイケル
      そういう自体が起きないようにするんだね。
      マイケル
      マイケル
      それじゃさっそく実装していこう!!
      エレキベア
      エレキベア
      クマ〜〜〜〜〜〜〜〜〜

      サーバ側の実装

      マイケル
      マイケル
      サーバ側から実装していこう!
      マスタテーブルの作成からJSONファイルの作成まで行います!
      エレキベア
      エレキベア
      やったるクマ〜〜〜〜〜

      マスタテーブルの作成

      マイケル
      マイケル
      今回は下記のような クエスト情報を管理するマスタ を作成します!

      ↑master_questテーブル
      マイケル
      マイケル
      作成コマンドは以下になります!
      テーブルの作成方法については下記記事で解説しているので
      内容がわからない場合はご参照ください!


      【Laravel】第一回 自動販売機システムを作ろう! 〜全体設計とテーブル作成〜

      エレキベア
      エレキベア
      なつかしクマね〜〜〜〜
      php artisan make:migration create_master_quest
      ↑マイグレーションファイルの作成
      <?php
      
      use Illuminate\Database\Migrations\Migration;
      use Illuminate\Database\Schema\Blueprint;
      use Illuminate\Support\Facades\Schema;
      
      class CreateMasterQuest extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('master_quest', function (Blueprint $table) {
                  $table->unsignedInteger('quest_id')->default(0);
      			$table->string('quest_name')->charset('utf8');
      			$table->string('quest_detail')->charset('utf8');
      			$table->Integer('quest_star')->default(0);
                  $table->timestamp('open_at')->default(DB::raw('CURRENT_TIMESTAMP'));
                  $table->timestamp('close_at')->default(DB::raw('CURRENT_TIMESTAMP'));
      			$table->unsignedInteger('item_type')->default(0);
      			$table->unsignedInteger('item_count')->default(0);
      			$table->primary('quest_id');
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::dropIfExists('master_quest');
          }
      }
      
      ↑マイグレーションファイルの記述
      php artisan migrate
      ↑マイグレーション実行
      php artisan make:model MasterQuest
      ↑Modelクラスの作成
      <?php
      
      namespace App;
      
      use Illuminate\Database\Eloquent\Model;
      
      class MasterQuest extends Model
      {
          protected $table = 'master_quest';
      	public $incrementing = false;
      	protected $primaryKey = 'quest_id';
      	public $timestamps = false;
      }
      
      ↑Modelクラスの記述

      JSONファイル作成処理

      マイケル
      マイケル
      テーブルを作成したら、JSONファイル作成の処理を作成していきましょう!
      下記 MasterDataServiceクラス を作成します!
      マイケル
      マイケル
      それぞれ、

      GenerateMasterData()メソッド → JSONファイルの作成処理
      GetMasterData()メソッド → JSONファイルからの取得処理
      CheckMasterDataVersion()メソッド → マスタデータバージョンチェック処理

      の処理内容になります!
      <?php
      
      namespace App\Libs;
      use App\MasterQuest;
      
      class MasterDataService
      {
          /**
           * マスタデータ作成処理
           * 
           * @param version マスタバージョン
           */
          public static function GenerateMasterData($version)
          {
              // 指定バージョンのファイルを作成
              touch(__DIR__ . '/' . $version);
              chmod(__DIR__ . '/' . $version, 0666);
      
              // master_dataを追加
              $master_data_list = array();
              $master_data_list['master_quest'] = MasterQuest::all();
      
              // JSONファイルを作成
              $json = json_encode($master_data_list);
              file_put_contents(__DIR__ . '/' . $version, $json);
          }
      
          /**
           * マスタデータ取得処理
           * 
           * @param data_name 取得データ名
           */
          public static function GetMasterData($data_name)
          {
              // ファイル取得
              $file = fopen(__DIR__ . '/' . config('constants.MASTER_DATA_VERSION'), "r");
              if (!$file) {
                  return false;
              }
      
              // データ取得
              $json = array();
              while ($line = fget($file)) {
                  $json = json_decode($line, true);
              }
              if (!array_key_exists($data_name, $json)) {
                  return false;
              }
      
              return $json[$data_name];
          }
      
          /**
           * マスタバージョンチェック処理
           * 
           * @param client_master_version マスタバージョン(クライアント)
           */
          public static function CheckMasterDataVersion($client_master_version)
          {
              return config('constants.MASTER_DATA_VERSION') <= $client_master_version;
          }
      }
      ↑マスタデータ管理のServiceクラス
      マイケル
      マイケル
      マスタバージョンは下記のように定数クラスで管理します!
      <?php
      
      return array(
          'MASTER_DATA_VERSION' => 1,
          'BANANA_DEFAULT' => 0,
          'BANANA_FREE_DEFAULT' => 10,
          'FRIEND_COIN_DEFAULT' => 0,
          'TUTORIAL_START' => 0,
      );
      
      マイケル
      マイケル
      そして作成済のModelクラスに、
      Serviceクラスを使用した取得処理を記述しましょう!
      <?php
      
      namespace App;
      
      use Illuminate\Database\Eloquent\Model;
      use App\Libs\MasterDataService;
      
      class MasterQuest extends Model
      {
          protected $table = 'master_quest';
      	public $incrementing = false;
      	protected $primaryKey = 'quest_id';
          public $timestamps = false;
          
          public static function GetMasterQuest()
          {
              $master_data_list = MasterDataService::GetMasterData('master_quest');
              return $master_data_list;
          }
      
          public static function GetMasterQuestByQuestId($quest_id)
          {
              $master_data_list = self::GetMasterQuest();
              foreach ($master_data_list as $master_data) {
                  $master_quest = new MasterQuest;
      			$master_quest->quest_id = $master_data['quest_id'];
      			$master_quest->quest_name = $master_data['quest_name'];
      			$master_quest->quest_detail = $master_data['quest_detail'];
      			$master_quest->quest_star = $master_data['quest_star'];
      			$master_quest->open_at = $master_data['open_at'];
      			$master_quest->close_at = $master_data['close_at'];
      			$master_quest->item_type = $master_data['item_type'];
      			$master_quest->item_count = $master_data['item_count'];
      			if ($quest_id == $master_quest->quest_id) {
      				return $master_quest;
                  }
                  
              }
              return null;
          }
      }
      
      ↑Serviceクラスを用いたデータ取得処理の追加
      エレキベア
      エレキベア
      これでメソッドを呼び出せばデータ取得ができるわけクマね
      マイケル
      マイケル
      その通りだ!!

      Artisanコマンドの登録

      マイケル
      マイケル
      そしてJSONクラス生成処理はコマンドから呼び出せるようにしましょう!
      下記のようにCommandクラスを作成してKernelクラスに登録します!
      php artisan make:command GenerateMasterData
      ↑Commandクラスの作成
      <?php
      
      namespace App\Console\Commands;
      
      use Illuminate\Console\Command;
      use App\Libs\MasterDataService;
      
      class GenerateMasterData extends Command
      {
          /**
           * The name and signature of the console command.
           *
           * @var string
           */
          protected $signature = 'command:generate_master_data {version}';
      
          /**
           * The console command description.
           *
           * @var string
           */
          protected $description = 'Generate master data -version';
      
          /**
           * Create a new command instance.
           *
           * @return void
           */
          public function __construct()
          {
              parent::__construct();
          }
      
          /**
           * Execute the console command.
           *
           * @return mixed
           */
          public function handle()
          {
              $version = $this->argument("version");
              MasterDataService::GenerateMasterData($version);
          }
      }
      
      ↑Commandクラスの記述
          protected $commands = [
              Commands\GenerateMasterData::class,
          ];
      ↑Kernel.phpへの登録
      マイケル
      マイケル
      これでArtisanコマンドを使用してJSONファイルを作成できるようになります!
      エレキベア
      エレキベア
      はやく実行したいクマ〜〜〜〜〜

      JSONファイル作成

      マイケル
      マイケル
      それではDBにマスタデータ追加後、

      「php artisan command:generate_master_data 【マスタバージョン】」

      で実行してみましょう!

      ↑マスタデータの登録
      php artisan command:generate_master_data 1
      ↑JSONファイル作成コマンド実行
      マイケル
      マイケル
      するとこのようにバージョン番号の名前でJSONクラスが作成されます!

      ↑JSONクラスが作成される
      エレキベア
      エレキベア
      すごいクマ〜〜〜〜〜〜!!!

      Controllerクラス作成

      マイケル
      マイケル
      あとはクライアント側から呼び出されるように、
      Controllerクラスを作成しておきましょう!
      マイケル
      マイケル
      それぞれ、

      Chk()メソッド → マスタバージョンチェック処理
      Get()メソッド → マスタデータ取得処理

      になります!
      php artisan make:controller MasterDataController
      ↑Controllerクラスの作成
      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      use App\Libs\MasterDataService;
      use App\MasterQuest;
      
      class MasterDataController extends Controller
      {
          public function Chk(Request $request)
          {
              // マスターデータチェック
              $client_master_version = $request->client_master_version;
              if (!MasterDataService::CheckMasterDataVersion($client_master_version)) {
      			return config('error.ERROR_MASTER_DATA_UPDATE');
              }
              $response = array('message' => '正常終了');
              return $response;
          }
      
          public function Get(Request $request)
      	{
      		//クライアント側に送信したいマスターデータだけを選択
      		$master_quest = MasterQuest::GetMasterQuest();
      
      		$response = array(
      			'master_data_version' => config('constants.MASTER_DATA_VERSION'),
      			'master_quest' => $master_quest,
      		);
      
      		return json_encode($response);
      	}
      }
      
      ↑Controllerクラスの記述
      Route::get('master_data', 'MasterDataController@Get');
      Route::get('master_data_chk', 'MasterDataController@Chk');
      ↑Routeの登録
      マイケル
      マイケル
      以上でサーバ側の実装は完了です!
      エレキベア
      エレキベア
      ひと段落クマ〜〜〜〜〜

      クライアント側の実装

      マイケル
      マイケル
      それじゃクライアント側も実装していこう!
      サーバ側にマスタ取得リクエストを送って
      帰ってきたデータを保存する処理

      になるよ!
      エレキベア
      エレキベア
      あともうひと踏ん張りクマね

      Modelクラス作成

      マイケル
      マイケル
      サーバ側と同様、クライアント側にもModelクラスを作成しましょう!

      CreateTable()メソッド → テーブル作成処理
      Set()メソッド → データ登録処理
      GetMasterQuest()メソッド → データ取得処理

      になります!
      using System;
      using System.Collections.Generic;
      
      [Serializable]
      public class MasterQuestModel
      {
          public int quest_id;
          public string quest_name;
          public string quest_detail;
          public int quest_star;
          public string open_at;
          public string close_at;
          public int item_type;
          public int item_count;
      }
      
      public static class MasterQuest
      {
          public enum ItemType
          {
              Banana = 1,
              BananaFree = 2,
              FriendCoin = 3,
          }
      
          public static void CreateTable()
          {
              string query = "create table if not exists master_quest (quest_id int, quest_name text, quest_detail text, quest_star text, open_at text, close_at text, item_type int, item_count int, primary key(quest_id))";
              SqliteDatabase sqlDB = new SqliteDatabase(GameUtil.Const.SQLITE_FILE_NAME);
              sqlDB.ExecuteQuery(query);
          }
      
          public static void Set(MasterQuestModel[] master_quest_model_list)
          {
              foreach (MasterQuestModel masterQuestModel in master_quest_model_list)
              {
                  string query = "insert or replace into master_quest (quest_id, quest_name, quest_detail, quest_star, open_at, close_at, item_type, item_count) values(" +
                      masterQuestModel.quest_id + ", \"" +
                      masterQuestModel.quest_name + "\", \"" +
                      masterQuestModel.quest_detail + "\", \"" +
                      masterQuestModel.quest_star + "\", \"" +
                      masterQuestModel.open_at + "\", \"" +
                      masterQuestModel.close_at + "\", " +
                      masterQuestModel.item_type + ", " +
                      masterQuestModel.item_count + ")";
                  SqliteDatabase sqlDB = new SqliteDatabase(GameUtil.Const.SQLITE_FILE_NAME);
                  sqlDB.ExecuteNonQuery(query);
              }
          }
      
          public static Dictionary<int, MasterQuestModel> GetMasterQuest()
          {
              Dictionary<int, MasterQuestModel> masterQuestListModel = new Dictionary<int, MasterQuestModel>();
              string query = "select * from master_quest";
              SqliteDatabase sqlDB = new SqliteDatabase(GameUtil.Const.SQLITE_FILE_NAME);
              DataTable dataTable = sqlDB.ExecuteQuery(query);
              foreach (DataRow dr in dataTable.Rows)
              {
                  MasterQuestModel masterQuestModel = new MasterQuestModel();
                  masterQuestModel.quest_id = int.Parse(dr["quest_id"].ToString());
                  masterQuestModel.quest_name = dr["quest_name"].ToString();
                  masterQuestModel.quest_detail = dr["quest_detail"].ToString();
                  masterQuestModel.quest_star = int.Parse(dr["quest_star"].ToString());
                  masterQuestModel.open_at = dr["open_at"].ToString();
                  masterQuestModel.close_at = dr["close_at"].ToString();
                  masterQuestModel.item_type = int.Parse(dr["item_type"].ToString());
                  masterQuestModel.item_count = int.Parse(dr["item_count"].ToString());
                  masterQuestListModel.Add(masterQuestModel.quest_id, masterQuestModel);
              }
              return masterQuestListModel;
          }
      
          public static MasterQuestModel GetMasterQuest(string quest_id)
          {
              MasterQuestModel masterQuestModel = new MasterQuestModel();
              string query = "select * from master_quest where quest_id = " + quest_id;
              SqliteDatabase sqlDB = new SqliteDatabase(GameUtil.Const.SQLITE_FILE_NAME);
              DataTable dataTable = sqlDB.ExecuteQuery(query);
              foreach (DataRow dr in dataTable.Rows)
              {
                  masterQuestModel.quest_id = int.Parse(dr["quest_id"].ToString());
                  masterQuestModel.quest_name = dr["quest_name"].ToString();
                  masterQuestModel.quest_detail = dr["quest_detail"].ToString();
                  masterQuestModel.quest_star = int.Parse(dr["quest_star"].ToString());
                  masterQuestModel.open_at = dr["open_at"].ToString();
                  masterQuestModel.close_at = dr["close_at"].ToString();
                  masterQuestModel.item_type = int.Parse(dr["item_type"].ToString());
                  masterQuestModel.item_count = int.Parse(dr["item_count"].ToString());
              }
              return masterQuestModel;
          }
      }
      
      ↑Modelクラスの作成

      マスタバージョンチェック処理

      マイケル
      マイケル
      そして次はマスタバージョンのチェック処理を実装します!
      クライアント側とサーバ側のバージョンが異なっている場合には
      マスタ更新のダイアログを表示

      させるようにしましょう!

      ↑マスタ更新ダイアログ
      マイケル
      マイケル
      まずはマスタバージョンの設定クラスを作成します!
      こちらはPreyerPrefsを使って管理を行います!
      using UnityEngine;
      
      public static class LocalDataManager
      {
          public static void SetMasterDataVersion(int version)
          {
              PlayerPrefs.SetInt(GameUtil.Const.SAVE_KEY_MASTER_VERSION, version);
          }
      
          public static int GetMasterDataVersion()
          {
              return PlayerPrefs.GetInt(GameUtil.Const.SAVE_KEY_MASTER_VERSION, 0);
          }
      }
      
      ↑マスタバージョン管理クラスの作成
      マイケル
      マイケル
      そしてテーブル作成とチェック処理の呼び出しを記述します!
      起動時にチェックするようにしたいので、今回はタイトル画面のクラスに記述しました。
      using System;
      using System.IO;
      using UnityEngine;
      using UnityEngine.UI;
      using UnityEngine.SceneManagement;
      
      public class TitleManager : MonoBehaviour
      {
      
      ・・・略・・・
      
          private void Awake()
          {
      
      ・・・略・・・
      
              // マスタデータ作成
              MasterQuest.CreateTable();
          }
      
          void Start()
          {
      
      ・・・略・・・
      
              // マスターデータチェック処理
              StartCoroutine(CommunicationManager.ConnectServer("master_data_chk", "", null));
          }
      
      ・・・略・・・
      
      }
      
      ↑テーブル作成とチェック処理の呼び出しを追加
      using System.Collections;
      using UnityEngine;
      using UnityEngine.Networking;
      using System;
      using System.Linq;
      
      [Serializable]
      public class ResponseObjects
      {
      	public int master_data_version;
      	public UserProfileModel user_profile;
      	public MasterQuestModel[] master_quest;
      }
      
      public class CommunicationManager : MonoBehaviour
      {
      
      	/** UI部品 */
      	private const string MASTER_UPDATE_CANVAS = "MasterUpdateCanvas";
      	private static GameObject masterUpdateCanvas;
      
      
      	private void Awake()
      	{
      		// ゲーム内に一つだけ保持
      		if (FindObjectsOfType<CommunicationManager>().Length > 1)
      			Destroy(gameObject);
      		else
      			DontDestroyOnLoad(gameObject);
      
      
      		// マスタ更新Canvasの取得
      		masterUpdateCanvas = GameObject.Find(MASTER_UPDATE_CANVAS);
      		masterUpdateCanvas.SetActive(false);
      
      	}
      
      	public static IEnumerator ConnectServer(string endpoint, string paramater, Action action = null)
          {
      		// *** リクエストの送付 ***
      		UnityWebRequest unityWebRequest = UnityWebRequest.Get(GameUtil.Const.SERVER_URL + endpoint + "?client_master_version=" + LocalDataManager.GetMasterDataVersion() + paramater);
      		yield return unityWebRequest.SendWebRequest();
      		// エラーの場合
      		if (!string.IsNullOrEmpty(unityWebRequest.error))
      		{
      			Debug.LogError(unityWebRequest.error);
      			yield break;
      		}
      
      		// *** レスポンスの取得 ***
      		string text = unityWebRequest.downloadHandler.text;
      		Debug.Log("レスポンス : " + text);
      		// エラーの場合
      		if (text.All(char.IsNumber))
      		{
      			switch (text)
      			{
      				case GameUtil.Const.ERROR_MASTER_DATA_UPDATE:
      					Debug.LogError("マスタの状態が古いでやんす。[マスタバージョン不整合]");
      					masterUpdateCanvas.SetActive(true);
      					break;
      				case GameUtil.Const.ERROR_DB_UPDATE:
      					Debug.LogError("サーバーでエラーが発生しました。[データベース更新エラー]");
      					break;
      				default:
      					Debug.LogError("サーバーでエラーが発生しました。[システムエラー]");
      					break;
      			}
      			yield break;
      		}
      
      		// *** SQLiteへの保存処理 ***
      		ResponseObjects responseObjects = JsonUtility.FromJson<ResponseObjects>(text);
      		if (responseObjects.master_data_version != 0)
      			LocalDataManager.SetMasterDataVersion(responseObjects.master_data_version);
      		if (responseObjects.master_quest != null)
      			MasterQuest.Set(responseObjects.master_quest);
      		if (!string.IsNullOrEmpty(responseObjects.user_profile.user_id))
      			UserProfile.Set(responseObjects.user_profile);
      		// 正常終了アクション実行
      		if (action != null)
      		{
      			action();
      			action = null;
      		}
      	}
      }
      
      ↑マスタバージョンエラーの場合の記述を追加
      マイケル
      マイケル
      このようにマスタバージョンエラーの場合には
      マスタ更新ダイアログ(masterUpdateCanvas)を表示させるようにします!
      エレキベア
      エレキベア
      前回作ったクラスに処理を加えたクマね

      マスタデータ更新処理

      マイケル
      マイケル
      そしてマスタ更新ダイアログに下記スクリプトをアタッチします!
      using System;
      using UnityEngine;
      using UnityEngine.UI;
      
      public class MasterUpdateManager : MonoBehaviour
      {
          /** UI部品 */
          private const string MASTER_UPDATE_CANVAS = "MasterUpdateCanvas";
          private const string MASTER_UPDATE_TEXT = "MasterUpdateText";
          private const string MASTER_UPDATE_OK_BUTTON = "MasterUpdateOKButton";
          private GameObject masterUpdateCanvas;
          private Text masterUpdateText;
          private GameObject masterUpdateOKButton;
      
          private void OnEnable()
          {
              masterUpdateCanvas = GameObject.Find(MASTER_UPDATE_CANVAS);
              masterUpdateText = GameObject.Find(MASTER_UPDATE_TEXT).GetComponent<Text>();
              masterUpdateOKButton = GameObject.Find(MASTER_UPDATE_OK_BUTTON);
              masterUpdateOKButton.SetActive(true);
          }
      
          private void Awake()
          {
              // ゲーム内に一つだけ保持
              if (FindObjectsOfType<MasterUpdateManager>().Length > 1)
                  Destroy(gameObject);
              else
                  DontDestroyOnLoad(gameObject);
          }
      
          // --------------- ボタン押下時処理 ---------------
          public void PushMasterUpdateOKButton()
          {
              // ボタン非表示
              masterUpdateOKButton.SetActive(false);
              // マスタデータ更新
              masterUpdateText.text = "更新中...";
              Action action = () =>
              {
                  masterUpdateText.text = "更新完了!";
                  Invoke("HideMasterUpdateCanvas", 1.0f);
              };
              StartCoroutine(CommunicationManager.ConnectServer("master_data", "", action));
          }
      
          // MasterUpdateCanvas非表示
          private void HideMasterUpdateCanvas()
          {
              masterUpdateCanvas.SetActive(false);
          }
      }
      
      マイケル
      マイケル
      これでOKボタンを押下した時に「master_data」リクエストを送って
      マスタデータの更新処理を行うようになりました!
      エレキベア
      エレキベア
      やったクマ〜〜〜〜!!!

      マスタデータ取得処理

      マイケル
      マイケル
      これでSQLiteにマスタデータが登録されたので、
      取得処理も行ってみましょう!
      マイケル
      マイケル
      下記のようにModelクラスから取得します!
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      using UnityEngine.UI;
      using UnityEngine.EventSystems;
      using UnityEngine.SceneManagement;
      using UniRx;
      
      public class ScrollContentManager : MonoBehaviour
      {
          /** 設定値 */
          public GameObject questItemPrefab;
      
          /** 定数 */
          private const string QUEST_ITEM_ID_HEAD = "QuestItem_";
          private const string QUEST_NAME_TEXT = "QuestNameText";
          private const string QUEST_STAR_LABEL = "label";
          private const string QUEST_STAR_TEXT = "QuestStarText";
          private const string QUEST_START_BUTTON = "QuestStartButton";
          private const string QUEST_DETAIL_TEXT = "QuestDetailText";
      
          /** 変数 */
          private GameObject questStartButton;
          private GameObject questDetailText;
          private string selectQuestId;
      
          void OnEnable()
          {
              questDetailText = GameObject.Find(QUEST_DETAIL_TEXT);
              questStartButton = GameObject.Find(QUEST_START_BUTTON);
              // 初期化処理
              questDetailText.GetComponent<Text>().text = "";
              questStartButton.GetComponent<Button>().interactable = false;
              // 子オブジェクトを削除
              foreach (Transform n in transform)
              {
                  Destroy(n.gameObject);
              }
          }
      
          private void Update()
          {
              // クエストが選択されたら活性
              if (!string.IsNullOrEmpty(selectQuestId))
                  questStartButton.GetComponent<Button>().interactable = true;
          }
      
          // スクロールアイテム設定処理
          public void SetScrollItem()
          {
              // MasterQuestデータを取得
              Dictionary<int, MasterQuestModel> masterQuestListModel = MasterQuest.GetMasterQuest();
              foreach (var element in masterQuestListModel)
              {
                  MasterQuestModel masterQuestModel = masterQuestListModel[element.Key];
                  GameObject item = Instantiate(questItemPrefab);
                  item.GetComponent<RectTransform>().SetParent(transform, false);
                  // 名前を設定
                  item.name = QUEST_ITEM_ID_HEAD + masterQuestModel.quest_id;
                  // クエスト名を設定
                  Text questName = item.GetComponent<Transform>().Find(QUEST_NAME_TEXT).GetComponent<Text>();
                  questName.text = masterQuestModel.quest_name;
                  // クエスト星を設定
                  Text questStar = item.GetComponent<Transform>().Find(QUEST_STAR_LABEL).Find(QUEST_STAR_TEXT).GetComponent<Text>();
                  questStar.text = ConvQuestStar(masterQuestModel.quest_star);
                  // イベントトリガー追加(引数:クエストID)
                  EventTrigger eventTrigger = item.AddComponent<EventTrigger>();
                  eventTrigger.triggers = new List<EventTrigger.Entry>();
                  EventTrigger.Entry entry = new EventTrigger.Entry();
                  entry.eventID = EventTriggerType.PointerDown;
                  entry.callback.AddListener((x) => PushQuestItem(masterQuestModel.quest_id.ToString()));
                  eventTrigger.triggers.Add(entry);
              }
          }
      
          // クエスト星に変換する
          private string ConvQuestStar(int count)
          {
              string star = "";
              for (int i = 0; i < count; i++)
              {
                  if (star.Length != 0)
                      star += " ";
                  star += "★";
              }
              return star;
          }
      
          // クエストアイテム押下時
          void PushQuestItem(string id)
          {
              selectQuestId = id;
              // IDに紐づくクエスト詳細を取得
              MasterQuestModel masterQuestModel = MasterQuest.GetMasterQuest(id);
              questDetailText.GetComponent<Text>().text = masterQuestModel.quest_detail;
              Debug.Log("SELECT:" + id);
          }
      
          // スタートボタン押下時
          public void PushStartButton()
          {
              // バトルシーンに遷移
              SceneManager.LoadSceneAsync(GameUtil.Const.SCENE_BUTTLE).AsObservable()
                  .Subscribe(_ =>
                  {
                      ButtleManager buttleManager = FindObjectOfType<ButtleManager>();
                      buttleManager.questId = selectQuestId;
                  });
          }
      }
      
      ↑マスタデータの取得
      マイケル
      マイケル
      このようにちゃんと登録されていることが確認できるはずです!
      エレキベア
      エレキベア
      やっと全て繋がったクマ〜〜〜〜〜〜〜

      おわりに

      マイケル
      マイケル
      というわけで今回はマスタデータの管理についてでした!
      どうだったかな?
      エレキベア
      エレキベア
      大変だったけどサーバとクライアントで連携できて
      感動だったクマ〜〜〜〜〜
      マイケル
      マイケル
      クライアントだけで動くアプリとは桁違いに大変だよね
      マイケル
      マイケル
      でもその分複雑なこともたくさんできそうだね!
      今後もがんばっていこう!!
      エレキベア
      エレキベア
      やったるクマ〜〜〜〜〜

      【Unity】第三回 ソーシャルゲームを作る 〜JSONファイルでのマスタ管理〜 【AWS x Laravel】 〜完〜


      UnityLaravelサーバサイド関連AWSソーシャルゲーム
      2020-12-07

      関連記事
      【Unity】Timeline × Excelでスライドショーを効率よく制作する
      2024-10-31
      【Unity】Boidsアルゴリズムを用いて魚の群集シミュレーションを実装する
      2024-05-28
      【Unity】GoでのランキングAPI実装とVPSへのデプロイ方法についてまとめる【Go言語】
      2024-04-14
      【Unity】第二回 Wwiseを使用したサウンド制御 〜インタラクティブミュージック編〜
      2024-03-30
      【Unity】第一回 Wwiseを使用したサウンド制御 〜基本動作編〜
      2024-03-30
      【Unity】第二回 CRI ADXを使用したサウンド制御 〜インタラクティブミュージック編〜
      2024-03-28
      【Unity】第一回 CRI ADXを使用したサウンド制御 〜基本動作、周波数解析編〜
      2024-03-28
      【Unity】サウンドミドルウェアに依存しない設計を考える【CRI ADX・Wwise】
      2024-03-27