1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

二次元配列をJSONに書き込む方法【Unity・C#】

Last updated at Posted at 2024-09-21

概要

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に保存します。

今回やることは次の通りになります。

  1. 保存するためのSavingDataクラスを作る
  2. 保存先のTrapControllerクラスでマップの値を読み込み
  3. 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++;
        }
    }
}

以上です、ご覧いただきありがとうございました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?