[Unity]LitJsonを使用してデータファイルのセーブ・ロード処理を簡単に実装 

ゲーム開発

Unityでのデータファイルのセーブ・ロード処理の実装方法をまとめてみました。 
データファイルはLitJsonの機能を使用して外部出力しています。 
*著者はUnity専門家ではありません。実装内容については参考程度にご覧ください。 

この記事ではこんなことがわかります 

  • セーブ・ロード機能の実装方法 
  • データファイルの外部出力・読み込み機能の実装方法 

機能を確認するためのサンプル処理 

データファイルのセーブ・ロード処理の機能を確認するためのサンプル処理を作成しました。 
Returnキーを入力するとスコアの値が1ずつ増加し、スコアの値がハイスコア以上になった場合はハイスコアの値を更新する処理になります。
スクリプト名はSample.csになります。 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class Sample : MonoBehaviour {
    [SerializeField]
    private TextMeshProUGUI scoreCountText;
    [SerializeField]
    private TextMeshProUGUI highScoreCountText;

    private int scoreCount;
    private int highScoreCount;

    private void Start() {
        //各値の初期化
        scoreCountText.text = 0.ToString();
        highScoreCount = 10;
        highScoreCountText.text = highScoreCount.ToString();
    }

    private void Update() {
        //Returnキーを押したらスコアが1ずつ増加
        if (Input.GetKeyDown(KeyCode.Return)) {
            scoreCount++;
            scoreCountText.text = scoreCount.ToString();
        }
        //スコアがハイスコア以上になったらハイスコアを更新
        if(scoreCount >= highScoreCount) {
            highScoreCount = scoreCount;
            highScoreCountText.text = highScoreCount.ToString();
        }
    }

}
Hierarchy内の構成
起動時の挙動

LitJsonを使用するための準備 

LitJsonを使用するためには準備が必要になります 。

初めに以下のGitHubからLitJsonのZipファイルをダウンロードします。 
https://github.com/findix/litjson-unity

GitHub - findix/litjson-unity: JSON library for the .Net framework
JSON library for the .Net framework. Contribute to findix/litjson-unity development by creating an account on GitHub.

その後、ダウンロードしたZipファイルを展開します。

最後に、展開したファイル内のsrcフォルダをUnityプロジェクトのAssets内に配置します。

これでLitJsonを使用できるようになりました。

セーブ・ロード処理の実装 

データファイル(今回はスコアデータ)のセーブ・ロード処理などを行うプログラムになります。 
スクリプト名はScoreData.csになります。

using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;

public static class ScoreData{

    private const string SAVE_PATH = "/Assets/Output/";//ファイルを保存するためのパス
    private const string FILE_NAME = "scoreData.dat";//保存するファイル名
    private const int DEFAULT_HIGH_SCORE = 15;

    public struct ScoreDataStruct { public int highScore; }//ハイスコアの値を保存する構造体
    public static ScoreDataStruct scoreDataStruct;

    /// <summary>
    /// ファイルパスの設定処理
    /// </summary>
    /// <returns>ファイルパス</returns>
    private static string FilePath() {
        string path = "";
        #if UNITY_EDITOR
            path = Directory.GetCurrentDirectory() + SAVE_PATH;
        #endif
        return path + FILE_NAME;
    }

    /// <summary>
    /// スコアデータの作成処理
    /// </summary>
    private static void ScoreDataCreate() {
        scoreDataStruct.highScore = DEFAULT_HIGH_SCORE;
        string jsonText = JsonMapper.ToJson(scoreDataStruct);
        ScoreDataSave(jsonText);
    }

    /// <summary>
    /// スコアデータの保存処理
    /// </summary>
    /// <param name="jsonText">保存するjsonText</param>
    private static void ScoreDataSave(string jsonText) {
        using (TextWriter tw = new StreamWriter(FilePath(), false, Encoding.UTF8))
            tw.Write(jsonText);
    }



    /// <summary>
    /// スコアデータの読み込み処理
    /// </summary>
    private static void ScoreDataLoad() {
        using (TextReader tr = new StreamReader(FilePath(), Encoding.UTF8))
            scoreDataStruct = JsonMapper.ToObject<ScoreDataStruct>(tr);
    }


    /// <summary>
    /// スコアデータの初期設定処理
    /// </summary>
    public static void ScoreDataInit() {
        if(File.Exists(FilePath())) {   //ファイルがある場合、ファイルを読み込む
            ScoreDataLoad();
        } else {                        //ファイルがない場合、ファイルを作成する
            ScoreDataCreate();
        }
    }

 

    /// <summary>
    /// スコアデータの更新処理
    /// </summary>
    /// <param name="highScore">ハイスコアの値</param>
    public static void ScoreDataUpdate(int highScore) {
        scoreDataStruct.highScore = highScore;
        string jsonText = JsonMapper.ToJson(scoreDataStruct);
        ScoreDataSave(jsonText);
    }
    
}

プログラム紹介

変数について 

スコアデータはint型の値を構造体内で管理して使用しています。
理由は、JsonMapper.ToJson()の処理でint型を直接入れ込むとエラーが発生するためです。 

public struct ScoreDataStruct { public int highScore; }//ハイスコアの値を保存する構造体
public static ScoreDataStruct scoreDataStruct;

FilePath()

データファイルの保存・読み込みを行う際に使用するパスを取得します。
今回はUnityEditor上のパスを取得しています。
他のプラットフォームのパスを取得する際は、個別に設定する必要があります。

   /// <summary>
     /// <summary>
    /// ファイルパスの設定処理
    /// </summary>
    /// <returns>ファイルパス</returns>
    private static string FilePath() {
        string path = "";
        #if UNITY_EDITOR
            path = Directory.GetCurrentDirectory() + SAVE_PATH;
        #endif
        return path + FILE_NAME;
    }

ScoreDataCreate()

ハイスコアのデフォルト値を設定してデータをjson化します。
その後、json化した文字列をScoreDataSave()で保存します。

    /// <summary>
    /// スコアデータの作成処理
    /// </summary>
    private static void ScoreDataCreate() {
        scoreDataStruct.highScore = DEFAULT_HIGH_SCORE;
        string jsonText = JsonMapper.ToJson(scoreDataStruct);
        ScoreDataSave(jsonText);
    }

ScoreDataSave()

StreamWriterでデータを作成します。
その後、tw.Write()でjson化したスコアデータを保存します。 

    /// <summary>
    /// スコアデータの保存処理
    /// </summary>
    /// <param name="jsonText">保存するjsonText</param>
    private static void ScoreDataSave(string jsonText) {
        using (TextWriter tw = new StreamWriter(FilePath(), false, Encoding.UTF8))
            tw.Write(jsonText);
    }

ScoreDataLoad()

データファイルをFilePath()で取得したパスから読み込みます。
その後、構造体内の変数に値を代入しています。

    /// <summary>
    /// スコアデータの読み込み処理
    /// </summary>
    private static void ScoreDataLoad() {
        using (TextReader tr = new StreamReader(FilePath(), Encoding.UTF8))
            scoreDataStruct = JsonMapper.ToObject<ScoreDataStruct>(tr);
    }

ScoreDataInit()

データファイルの初期設定処理になります。 
ファイルがある場合はファイルの読み込みを行います。
ファイルがない場合はファイルの作成を行います。

    /// <summary>
    /// スコアデータの初期設定処理
    /// </summary>
    public static void ScoreDataInit() {
        if(File.Exists(FilePath())) {   //ファイルがある場合、ファイルを読み込む
            ScoreDataLoad();
        } else {                        //ファイルがない場合、ファイルを作成する
            ScoreDataCreate();
        }
    }

ScoreDataUpdate(int highScore)

ハイスコアの値を引数の値に代入します。
その後、データをjson化してScoreDataSave()で保存します。
ScoreDataCreate()と処理は流れは同じになります。

    /// <summary>
    /// スコアデータの更新処理
    /// </summary>
    /// <param name="highScore">ハイスコアの値</param>
    public static void ScoreDataUpdate(int highScore) {
        scoreDataStruct.highScore = highScore;
        string jsonText = JsonMapper.ToJson(scoreDataStruct);
        ScoreDataSave(jsonText);
    }

サンプル処理の修正

以下が、Sample.csにScoreData.csの処理を反映させたプログラムになります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class Sample : MonoBehaviour {
    [SerializeField]
    private TextMeshProUGUI scoreCountText;
    [SerializeField]
    private TextMeshProUGUI highScoreCountText;

    private int scoreCount;
    private int highScoreCount;

    private void Start() {
        //スコアデータの初期設定
        ScoreData.ScoreDataInit();

        //スコア値の設定
        scoreCount = 0;
        scoreCountText.text = scoreCount.ToString();

        //ハイスコア値の設定
        highScoreCount = ScoreData.scoreDataStruct.highScore;//スコアデータからハイスコアの値を取得

        highScoreCountText.text = highScoreCount.ToString();
    }

    private void Update() {
        //Returnキーを押したらスコアが1ずつ増加
        if (Input.GetKeyDown(KeyCode.Return)) {
            //スコア値の設定
            scoreCount++;
            scoreCountText.text = scoreCount.ToString();

            //スコアがハイスコア以上になったらハイスコアを更新
            if (scoreCount >= highScoreCount) {
                //ハイスコア値の設定
                highScoreCount = scoreCount;
                highScoreCountText.text = highScoreCount.ToString();

                //スコアデータの更新
                ScoreData.ScoreDataUpdate(highScoreCount);
            }

        }
    }

}

プログラムの確認

実際に起動してみます。

データファイルの作成 
起動後データファイルが存在しない場合は、データファイルを指定のパスに作成します。 
今回はプロジェクト名/Assets/Output/内に作成しています。

なお、作成したデータファイルはプロジェクトシーンにすぐ表示されません。 
一度、リフレッシュを行う必要があります。 
(リフレッシュの方法はProjectシーン内で右クリック→Refreshを選択になります。) 

データ作成時時の挙動とリフレッシュ方法

作成されたデータファイルの内容は以下になります。 

作成したデータファイル

データファイルの更新 
ハイスコアの値が更新されたら、データファイルが更新されます。 

データファイルの更新1
データファイルの更新2

データファイルを確認するとhighScoreの値が変化しているのが確認できると思います。 

更新後のデータファイル

最後に

Unityでデータファイルのセーブ・ロード処理の実装方法をまとめてみました 
今回はハイスコアの値のみを管理する処理を作成しましたが、こちらのプログラムを応用することで多くのデータを管理することができます。 

応用したデータファイル1
応用したデータファイル2

簡単に処理を実装することができますので、セーブ・ロード機能の実装に悩んでいる方の参考になれればと思います 。

コメント

タイトルとURLをコピーしました