概要
Unityで二次元配列をJSONに入れたいと思ったことはありませんか?
今回は、マップを例に二次元配列をJSONファイルに保存する方法を紹介します。
ポイント
classを2つに分けて保存する。
data.cs
───────
using System;
[Serializable]
public class YValue
{
public int[] xValue = new int[23];
}
[Serializable]
public class SavingData
{
public YValue[] yValue = new YValue[10];
}
JSONファイルに取り込む。
jsonWrite.cs
using System.IO
// 書き込み
public void saveData_save(SavingData saver)
{
StreamWriter writer;
string jsonstr = JsonUtility.ToJson(saver);
writer = new StreamWriter(Application.dataPath + "/save/savedataJO.json", false);
writer.Write(jsonstr);
writer.Flush();
writer.Close();
}
// 読み込み
public SavingData loadsaveData()
{
string datastr = "";
StreamReader reader;
reader = new StreamReader(Application.dataPath+"/save/savedataJO.json");
datastr = reader.ReadToEnd();
reader.Close();
try
{
return JsonUtility.FromJson<SavingData>(datastr);
}
catch (ArgumentException e)
{
Debug.LogError("Failed to deserialize JSON: " + e.Message);
return null;
}
この2点を押さえればOK。
詳しいやり方
今回はマップのバリューをJSONに保存します。
今回やることは次の通りになります。
- 保存するためのSavingDataクラスを作る
- 保存先のTrapControllerクラスでマップの値を読み込み
- Jsonの書き込むSaveManagerクラスで入れた値を書き込む
保存用classを作る
jsonは二次元配列を記述することができないため、まず、YValueクラスとSavingDataクラスの2つに分けます。
SavingDataクラスで、YValueの配列YValueクラスでintの配列を作ることにより、擬似的な二次元配列を表現します。
date.cs
using System;
[Serializable]
public class YValue
{
public int[] xValue = new int[23];
}
[Serializable]
public class SavingData
{
public YValue[] yValue = new YValue[10];
}
保存先で値を代入する
SavingDataクラスをインスタンスとして関数を
dataSystem.cs
// save
public SaveMapping saveMapping = new SaveMapping();
public GameObject sM_trap;
void Start()
{
// save setting
saveMapping.saveX = transform.position.x;
saveMapping.saveY = transform.position.y;
int changeX = (int)saveMapping.saveX;
int changeY = (int)saveMapping.saveY;
// 連番変換
if (changeX < 0)
{
changeX = 11 + changeX;
}
else if (changeX >= 0)
{
changeX += 11;
}
if (changeY < 0)
{
changeY = (changeY * -1) + 4;
}
else if (changeY >= 0)
{
changeY = 4 - changeY;
}
saveMapping.saveCode = 3;
sM_trap = GameObject.Find("SaveManager");
saveMapping.sM = sM_trap.GetComponent<SaveManager>();
saveMapping.sM.InputTo(changeY, changeX,saveMapping.saveCode);
// save End
}
Jsonに書きこむ
StreamWriter 変数[writer]を用意string型の変数に保存用のクラスをJsonUnity.ToJsonでJSON型変換する[writer]にStreamWriter(パス+ファイル名,false)インスタンスを入れる[writer]のStreamWriterインスタンスのWrite、Flushを使用してJSONの中身を書き込む書き終わったらwriterの書き込みを終了させる
using System.IO
//save activety
public void saveData_save(SavingData saver)
{
StreamWriter writer;
string jsonstr = JsonUtility.ToJson(saver);
writer = new StreamWriter(Application.dataPath + "/save/savedataJO.json", false);
writer.Write(jsonstr);
writer.Flush();
writer.Close();
}
サンプルコード
StageData.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
[Serializable] public class StageValueX
{
public List<int> xValue;
}
[Serializable] public class StageValueY
{
public List<StageValueX> yValue;
}
[CreateAssetMenu(fileName = "StageDate", menuName = "GameDate/StageDateBase")]
public class StageDate : ScriptableObject{
public List<StageValueY> stageList;
}
[Serializable]public class Total
{
public int EnemyKill;
public float PlayingTime;
public int SetTrap;
}
public class GameManeger : MonoBehaviour
{
//@result-Use result menu.
//map[y,x] で管理してる
/* 0= なんもない
* 1= プレイヤー
* 2= 敵
* 3= トラップ
*/
public List<int> enemyManagerID = new List<int>();
public Transform player;
public GameObject enemy;
public GameObject trap;
public GameObject menu;
int[,] map = new int[9,17] {
{ 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2,2 },
{ 2, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 0, 2,2 },
{ 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 2,2 },
{ 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2,2 },
{ 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2,2 },
{ 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,2 },
{ 2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,2 },
{ 2, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 2,2 },
{ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,2 }
};
int mapNumber = 0;
int y_number = 0;
int x_number = 0;
public SpriteRenderer background;
[SerializeField] GameDate gamestageDateBase;
public bool EndGame = false;
public bool Use_menuListNumber = true;
// Start is called before the first frame update
void Start()
{
if (Use_menuListNumber)
{
stageNumber = MenuManager.menuStageNumber;
}
background.sprite = gamestageDateBase.stagelist[stageNumber].background;
//SetStage
for(int y = 4; y >= -5; y--)
{
for(int x = -11; x <= 11; x++)
{
if (x_number > 22)
{
x_number = 0;
}
mapNumber = stagedate.stageList[stageNumber].yValue[y_number].xValue[x_number];
switch (mapNumber)
{
case 1:
player.position = new Vector3(x, y, 0);
break;
case 2:
Instantiate(enemy, new Vector3(x, y, 0), Quaternion.identity);
break;
case 3:
Instantiate(trap, new Vector3(x, y, 0), Quaternion.identity);
break;
}
mapnumberMix = mapNumber % 100;
int mapcheack = mapNumber - mapnumberMix;
x_number++;
}
y_number++;
}
}
}
以上です、ご覧いただきありがとうございました。