【ハルシオンブログ】JsonUtilityとかでデータを保存する際に、ポリモーフィズム化されてるデータの値が保存されないときに、こうやったよ!
こんにちわ。
坂内っす。
熱海の大雨と土石流大変ですね・・・なくなった方もいるとか。
現地の方はお気を付けくださいませ。
Unityでデータを保存するときにJSONにして保存とかよくやりますよね。
この時、子供クラスのデータが保存されないので気をつけましょう。
例えばこんなコードの場合。
[SaveDataBase.cs]
[SaveDataChild.cs]
[SaveData.cs]
[Blog0705.cs]
こんな感じで、SaveDataを保存。
出来上がったファイルはこちら。

「あああ」とか「いいい」などのSaveDataChildがもっているデータは保存されません。
もちろんSaveDataChildのListをそのままSaveDataにいれれば保存されます。
親:Chara
子:CharaA:Chara
子:CharaB:Chara
こんな構成のデータって考えられると思うんですよね。
このデータを保存するときって
List<Chara> charas = new List<Chara>
にCharaAやBのデータを保存するかと。
この時に同じ現象が起きます。
Charaが持っているデータは保存されるが、CharaAなどが継承後に追加したデータが保存されません。
え?
List<CharaA> charaA = new List<CharaA>();
List<CharaA> charaB = new List<CharaB>();
ってやればいいって?
それもありですね。
あ、話を戻します。
ポリモーフィズム化したクラスは保存されないようですね。
List<Chara> charas = new List<Chara>()
にCharaAとかBのデータを入れた場合に、AやBの追加されたデータも保存する方法ありますか?
とりあえずこんな感じで対応してみましたが・・・・
SaveDataBase.csと保存処理のかいてあるSaveメソッドに手を入れてみた。
[SaveData.cs]
[Blog0706.cs]
赤文字のところを追加して、実際に保存をすると、こんなデータになります。

あとはロードのところで以下の追加をすればSaveDataChildのデータも保存読み込みができます。
[Blog0706.cs]
無理やり感すごいですが、別途シリアライズして文字列を突っ込んで保存って感じでできましたw
正しいやり方わかる方教えてぷりーず!
ということで、ポリモーフィズムのデータをJsonUtilityで保存する方法でした。
では、あでゅ~ノシ
坂内っす。
熱海の大雨と土石流大変ですね・・・なくなった方もいるとか。
現地の方はお気を付けくださいませ。
Unityでデータを保存するときにJSONにして保存とかよくやりますよね。
この時、子供クラスのデータが保存されないので気をつけましょう。
例えばこんなコードの場合。
[SaveDataBase.cs]
[System.Serializable]
public class SaveDataBase
{
public int num;
}
[SaveDataChild.cs]
[System.Serializable]
public class SaveDataChild : SaveDataBase
{
public string label;
}
[SaveData.cs]
using System.Collections.Generic;
[System.Serializable]
public class SaveData
{
public List<SaveDataBase> data;
}
[Blog0705.cs]
using UnityEngine;
using System.IO;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
public class Blog070502 : MonoBehaviour
{
string[] str = {
"あああ",
"いいい",
"うう",
"ええ",
"おぉぉぉ"
};
string filePath;
private static readonly string SavePath = "save.bytes";
void Start()
{
SaveData saveData = new SaveData();
saveData.data = new List<SaveDataBase>();
for (int i = 0; i < 5; i++) {
SaveDataChild data = new SaveDataChild();
data.num = i;
data.label = str[i];
saveData.data.Add(data);
}
Save(saveData);
}
// 引数で渡ってきたオブジェクトをシリアライズして返す
public static string Serialize<T>(T obj) {}
// 引数のテキストを指定されたクラスにデシリアライズして返す
public static T Deserialize<T>(string key) {}
private static string GetJson() {
string filePath = Application.persistentDataPath + "/" + SavePath; // Jsonを保存する場所のパスを取得
if (File.Exists(filePath)) { // 指定したファイルがあるか調べるメソッド
return File.ReadAllText(filePath); // ファイルがあれば取得してJsonに変換
} else {
return "";
}
}
public void Save(SaveData data) {
// 指定したパスに新しいファイルを作成し、内容をファイルに書き込み閉じる
File.WriteAllText(Application.persistentDataPath + "/" + SavePath, JsonUtility.ToJson(data));
string json = JsonUtility.ToJson(data);
}
void Load() {
string jsonTxt = GetJson();
SaveData data = new SaveData();
data = JsonUtility.FromJson<SaveData>(jsonTxt);
}
}
こんな感じで、SaveDataを保存。
出来上がったファイルはこちら。

「あああ」とか「いいい」などのSaveDataChildがもっているデータは保存されません。
もちろんSaveDataChildのListをそのままSaveDataにいれれば保存されます。
親:Chara
子:CharaA:Chara
子:CharaB:Chara
こんな構成のデータって考えられると思うんですよね。
このデータを保存するときって
List<Chara> charas = new List<Chara>
にCharaAやBのデータを保存するかと。
この時に同じ現象が起きます。
Charaが持っているデータは保存されるが、CharaAなどが継承後に追加したデータが保存されません。
え?
List<CharaA> charaA = new List<CharaA>();
List<CharaA> charaB = new List<CharaB>();
ってやればいいって?
それもありですね。
あ、話を戻します。
ポリモーフィズム化したクラスは保存されないようですね。
List<Chara> charas = new List<Chara>()
にCharaAとかBのデータを入れた場合に、AやBの追加されたデータも保存する方法ありますか?
とりあえずこんな感じで対応してみましたが・・・・
SaveDataBase.csと保存処理のかいてあるSaveメソッドに手を入れてみた。
[SaveData.cs]
using System.Collections.Generic;
[System.Serializable]
public class SaveData
{
public List data;
public string datastring; ←New
}
[Blog0706.cs]
public void Save(SaveData data) {
saveData.datastring = Serialize<List<SaveDataBase>>(saveData.data); ←New
// 指定したパスに新しいファイルを作成し、内容をファイルに書き込み閉じる
File.WriteAllText(Application.persistentDataPath + "/" + SavePath, JsonUtility.ToJson(data));
string json = JsonUtility.ToJson(data);
}
赤文字のところを追加して、実際に保存をすると、こんなデータになります。

あとはロードのところで以下の追加をすればSaveDataChildのデータも保存読み込みができます。
[Blog0706.cs]
void Load() {
string jsonTxt = GetJson();
SaveData data = new SaveData();
data = JsonUtility.FromJson(jsonTxt);
data.data = Deserialize>(data.data);
←New
}
無理やり感すごいですが、別途シリアライズして文字列を突っ込んで保存って感じでできましたw
正しいやり方わかる方教えてぷりーず!
ということで、ポリモーフィズムのデータをJsonUtilityで保存する方法でした。
では、あでゅ~ノシ
Category: 開発日記(Unity)
« 【ハルシオンブログ】VSCodeのLocal Historyが便利 | 【ハルシオンブログ】Listや配列の中身が一緒か確認するときはSequenceEqualを使うといいですね。 »
コメント
| h o m e |