Unityでクラスをまるごと保存するサンプルを制作しております。
参考サイトを見ながら、保存まではできたのですが読み込み時にエラーが出てしまいます。
対処方法わかる方おりませんでしょうか。
保存先についてはStreamingAssetsフォルダにて行っており、Jsonの文字列の取得はできておりました。
参考サイト
https://kan-kikuchi.hatenablog.com/entry/Json_SaveData
ArgumentException: Cannot deserialize JSON to new instances of type 'DataManager.' UnityEngine.JsonUtility.FromJson (System.String json, System.Type type) (at C:/buildslave/unity/build/Modules/JSONSerialize/Public/JsonUtility.bindings.cs:48) UnityEngine.JsonUtility.FromJson[T] (System.String json) (at C:/buildslave/unity/build/Modules/JSONSerialize/Public/JsonUtility.bindings.cs:33) DataManager.LoadJson () (at Assets/Scripts/Others/DataManager.cs:323) DataManager.Awake () (at Assets/Scripts/Others/DataManager.cs:130) UnityEngine.Object:Instantiate(GameObject) AddManager:Awake() (at Assets/Scripts/Others/AddManager.cs:25)
C#
1using UnityEngine; 2using UnityEngine.SceneManagement; 3using System; 4using System.IO; 5using System.Collections; 6using System.Collections.Generic; 7using System.Runtime.Serialization.Formatters.Binary; 8 9 10// オリジナルクラス 11public class MyFunction { 12 13 // 使用例 14 /* 15 MyFunction myFunc = new MyFunction(); 16 string filePath = myFunc.GetPathFileNameStreamingAssets("category.json"); 17 string datastr = myFunc.ReadData(filePath); 18 */ 19 20 // Androidの場合、StreamingAssetのファイル名から文字列を返す 21 public string GetStringAndroidStreamingAssets(string fileName){ 22 23 // Androidの場合 24 #if UNITY_ANDROID 25 string path = "jar:file://" + Application.dataPath + "!/assets" + "/" + fileName; 26 WWW www = new WWW(path); 27 while (!www.isDone) {} 28 return www.text; 29 30 #else 31 Debug.Log("not android"); 32 return ""; 33 #endif 34 35 } 36 37 // StreamingAssetsのPathを取得 38 public string GetPathStreamingAssets(){ 39 40 string path = ""; 41 42 #if UNITY_EDITOR 43 path = Application.dataPath + "/StreamingAssets/"; 44 45 #elif UNITY_IOS 46 path = Application.dataPath + "/Raw/"; 47 48 #elif UNITY_ANDROID 49 path = "jar:file://" + Application.dataPath + "!/assets" + "/"; 50 WWW www = new WWW(path); 51 while (!www.isDone) {} 52 53 #else 54 path = Application.dataPath + "/StreamingAssets/"; 55 #endif 56 57 return path; 58 } 59 60 // StreamingAssetsのPathを取得してFileNameを付加する 61 public string GetPathFileNameStreamingAssets(string fileName){ 62 63 return (GetPathStreamingAssets() + fileName); 64 65 } 66 67 public string ReadData(string filePath) { 68 string str = ""; 69 StreamReader reader; 70 reader = new StreamReader (filePath); 71 str = reader.ReadToEnd (); 72 reader.Close (); 73 //Debug.Log(str); 74 return str; 75 } 76 77} 78 79/* ====================================================================== 80* 全シーンで使える変数。 81* [DataManager.Instance.変数名]で各種処理を呼び出すことが可能。 82*====================================================================== */ 83[Serializable] 84public class DataManager : MonoBehaviour { 85 86 private static DataManager instance = null; 87 88 public bool bgmFlag; 89 public int playerMax = 3; 90 public int playerLow = 1; 91 public int playerHigh = 2; 92 93 //SaveDataをJsonに変換したテキスト(リロード時に何度も読み込まなくていいように保持) 94 [SerializeField] 95 private static string _jsonText = ""; 96 97 void Start() { 98 } 99 100 // 初期化 101 public static DataManager Instance{ 102 get{ 103 if( null == instance ){ 104 instance = (DataManager)FindObjectOfType(typeof(DataManager)); 105 if( null == instance ){ 106 Debug.Log(" DataManager Instance Error "); 107 } 108 } 109 return instance; 110 } 111 112 } 113 114 void Awake(){ 115 116 GameObject[] obj = GameObject.FindGameObjectsWithTag("DataManager"); 117 118 if( 1 < obj.Length ){ 119 // 既に存在しているなら削除 120 Destroy( gameObject ); 121 }else{ 122 // シーン遷移では破棄させない 123 DontDestroyOnLoad( gameObject ); 124 LoadJson(); 125 //Load(); 126 } 127 128 } 129 130 // リストを保存 131 public static void SaveList<T>(string key , List<T> value){ 132 string serizlizedList = Serialize<List<T>> (value); 133 PlayerPrefs.SetString (key, serizlizedList); 134 } 135 136 // リストを読み込み 137 public static List<T> LoadList<T> (string key){ 138 //keyがある時だけ読み込む 139 if (PlayerPrefs.HasKey (key)) { 140 string serizlizedList = PlayerPrefs.GetString (key); 141 return Deserialize<List<T>> (serizlizedList); 142 } 143 144 return new List<T> (); 145 } 146 147 //引数のオブジェクトをシリアライズして返す 148 private static string Serialize<T> (T obj){ 149 BinaryFormatter binaryFormatter = new BinaryFormatter (); 150 MemoryStream memoryStream = new MemoryStream (); 151 binaryFormatter.Serialize (memoryStream , obj); 152 return Convert.ToBase64String (memoryStream .GetBuffer ()); 153 } 154 155 //引数のテキストを指定されたクラスにデシリアライズして返す 156 private static T Deserialize<T> (string str){ 157 BinaryFormatter binaryFormatter = new BinaryFormatter (); 158 MemoryStream memoryStream = new MemoryStream (Convert.FromBase64String (str)); 159 return (T)binaryFormatter.Deserialize (memoryStream); 160 } 161 162 //保存しているJsonを取得する 163 private static string GetJson(){ 164 //既にJsonを取得している場合はそれを返す。 165 if(!string.IsNullOrEmpty(_jsonText)){ 166 return _jsonText; 167 } 168 169 //Jsonを保存している場所のパスを取得。 170 string filePath = ""; 171 172 MyFunction myFunc = new MyFunction(); 173 filePath = myFunc.GetPathFileNameStreamingAssets("DataManager.json"); 174 175 //Jsonが存在するか調べてから取得し変換する。存在しなければ新たなクラスを作成し、それをJsonに変換する。 176 if(File.Exists(filePath)){ 177 _jsonText = File.ReadAllText (filePath); 178 } 179 else{ 180 _jsonText = JsonUtility.ToJson(new DataManager ()); 181 } 182 183 Debug.Log(_jsonText); 184 185 return _jsonText; 186 } 187 188 //データを読み込む。 189 private static void LoadJson(){ 190 instance = JsonUtility.FromJson<DataManager>(GetJson ()); 191 } 192 193 public void ReloadJson(){ 194 JsonUtility.FromJsonOverwrite (GetJson(), this); 195 } 196 197 public void SaveJson(){ 198 _jsonText = JsonUtility.ToJson(this, true); 199 File.WriteAllText (GetSaveFilePath(), _jsonText); 200 } 201 202 // 削除 203 public void DeleteJson(){ 204 _jsonText = JsonUtility.ToJson(new DataManager ()); 205 ReloadJson (); 206 } 207 208 //保存する場所のパスを取得。 209 private static string GetSaveFilePath(){ 210 211 string filePath = ""; 212 213 MyFunction myFunc = new MyFunction(); 214 filePath = myFunc.GetPathFileNameStreamingAssets("DataManager.json"); 215 Debug.Log(filePath); 216 /* 217 //確認しやすいようにエディタではAssetsと同じ階層に保存し、それ以外ではApplication.persistentDataPath以下に保存するように。 218 #if UNITY_EDITOR 219 filePath += ".json"; 220 #else 221 filePath = Application.persistentDataPath + "/" + filePath; 222 #endif 223*/ 224 225 return filePath; 226 } 227}
どこで、何というエラーが表示されるか
記載したほうが、回答を得られやすいとおもいます。
JSONの中身も欲しいです
コードを丸投げしてデバッグしてくれと言ってるみたいですね。少しは自分で切り分けしてから質問するようにした方が解決が早いと思いますよ。エラーメッセージは「JSON 文字列を DataManager 型にデシリアライズできない」と言っているのですから、その部分だけ切り出して検証するとか。
>>nanami12様
ご回答ありがとうございます。
Awake内のLoadJson();部分で、エラーが出ています。
エラーについては、一番上のコードの内容です。
>>izmktr様
StartなどでSaveJsonすると自動生成されます。
下記のような普通のJsonが出力されていました。
{
"bgmFlag": false,
"playerMax": 3,
"playerLow": 1,
"playerHigh": 2
}
>>SurferOnWww様
ご指摘のような形になって申し訳ございません。
参考サイトを読み進めながら、試しているのですがこのエラーだけどうしてもとれず・・・。
エラー内容については何となくわかるのですが、なぜ書き出したものが不具合なのかわからず。
別のサンプルを試してJsonUtilityで読み込めることは確認しているため、このエラーの解消方法がわかりませんでした。
上の私のコメントで、
> エラーメッセージは「JSON 文字列を DataManager 型にデシリアライズできない」と言っているのですから、その部分だけ切り出して検証するとか。
・・・と書きましたけど、それをやってみませんか? それで原因が分かれば自己解決できるかもしれません。できない事情はないはずですが。
回答1件
あなたの回答
tips
プレビュー