[unity]アプリで Json.Net を使う

unity には JsonUtility があるじゃん

お手軽だし、速度面はおそらく最速レベル。はいこれで決まりー。

かつて私もそう思った時期がありました。一瞬ですが。
JsonUtility には弱点があったのです。

  1. List<T> が使えない
  2. DateTime が使えない
  3. Dictionary が使えない

①List<T> は、List<T> をメンバーに持つクラスを作り、それをパースする、②もまぁ…パースする前に日付の文字列にするなどで対応……、③ は………いや、どうにか出来なくないけど面倒になってきた。

そう、出来るならクラスをまるっと渡してそのまま Json 文字列にして欲しいです。
それを可能にするのが Json.Net というわけです。

インストール方法

Package Manager > 左上の+ > Add package from git URL... > com.unity.nuget.newtonsoft-json > Add

Newtonsoft Json が追加されれば成功です。

実は適当に持ってきた Newtonsoft.Json.dllAssets/ 下に入れてもエディター上では動作しますが、ビルドした時に動作しなくなるので注意しましょう。

テストコード

using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    class SaveData
    {
        public string StringValue;
        public int    IntValue;
        public Dictionary<string, int> Dics;

        [JsonIgnore]
        public int    IgnoreValue;
    }

    SaveData saveData;

    void Start()
    {
        saveData = new SaveData()
        {
            StringValue = "abcdef",
            IntValue    = 12345,
            IgnoreValue = 67890,
            Dics        = new Dictionary<string, int>()
            {
                { "No.1", 1 },
                { "No.2", 2 },
                { "No.3", 3 },
            },
        };

        // saveData → json
        string json = JsonConvert.SerializeObject(saveData);

        // json → loadData
        var loadData = JsonConvert.DeserializeObject<SaveData>(json);

        Debug.Log($"StringValue: {loadData.StringValue}");
        Debug.Log($"IntValue: {loadData.IntValue}");
        Debug.Log($"IgnoreValue: {loadData.IgnoreValue}");
        foreach (var pair in loadData.Dics)
        {
            Debug.Log($"Dic: {pair.Key} -> {pair.Value}");
        }
    }
}

saveData → json テキスト → loadData とデータを受け渡し、loadData の中身を表示します。

ポイントの解説

using Newtonsoft.Json;

JsonConvert を使うための常套句。

[JsonIgnore]

json 化したくないメンバーの上にこれを書いておけば、json 化を防ぐことができます。
サンプルでは IgnoreValue のみ json 化しません。

string json = JsonConvert.SerializeObject(saveData);

saveData の中身を json テキストに変換します。変換したテキストはこんな感じ。

{"StringValue":"abcdef","IntValue":12345,"Dics":{"No.1":1,"No.2":2,"No.3":3}}

開発時など、json の値をパッと見わかりやすくしたいのであれば、インデントをつける事もできます。

string json = JsonConvert.SerializeObject(saveData, Formatting.Indented);
{
  "StringValue": "abcdef",
  "IntValue": 12345,
  "Dics": {
    "No.1": 1,
    "No.2": 2,
    "No.3": 3
  }
}

var loadData = JsonConvert.DeserializeObject(json);

json テキストを変換し、loadData の中に入れます。

loadData の表示結果

IgnoreValue は [JsonIgnore] によって保存されなかったので、loadData では初期値の 0 になっています。
それ以外は saveData と同じになりました。

速度がそれほど必要ないのであれば…

そもそも速度が必要になるような頻度で json にすることも稀なので、汎用性を取って Json.Net にしておいてはいかがでしょうか。
後からどんなメンバーが追加されても安心です。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA