Я хочу сохранить несколько не связанных ScriptableObjects
объектов в один файл сохранения. Таким образом, я могу сохранить / загрузить данные для всего, что я захочу отслеживать. IE. Двери разблокированы, инвентарь, рекорды, найдены сундуки с сокровищами и т. Д. Таким образом, я все еще могу использовать ScriptableObjects
, а также сохранять и / или перезагружать в точку, находящуюся под контролем DataManager
. Я хотел, чтобы DataManager
ничего не делал, кроме сохранения и перезагрузки ScriptableObjects
с сохраненными данными.
Сохранение различных ScriptableObjects
в один файл, по-моему, работает нормально. Если я открою файл data_editor.sav
, я увижу, что данные были сериализованы и помещены в файл.
{"serializedObjects":["{\"GUID\":\"e27e7e59111210141bb70cbdff58f4f6\",\"Prefab\":{\"instanceID\":3648}}","{\"GUID\":\"52abd33f0dd972246b5eaa87a938331e\",\"Prefab\":{\"instanceID\":3190}}","{\"GUID\":\"78d783846b8abb3488ee1e274773aec6\",\"Prefab\":{\"instanceID\":3080}}"]}
Однако чтение данных и попытка заселения моего свойства DataManager
managedData
- это то, что продолжает ломаться. Я не могу понять, как десериализовать строки JSON обратно в ScriptableObjects
.
.
Я получаю ошибку:
ArgumentException: Невозможно десериализовать JSON для новых экземпляров типа
'ScriptableObject.
Я рассмотрел несколько SO вопросов, , включая этот , но я не могу найти ничего, что касается управления несколькими различными ScriptableObjects
в одном.
Любая помощь?
Я пробовал варианты JsonUtility.FromJsonOverwrite
и JsonUtility.FromJson<ScriptableObject>
, но не смог заставить его работать.
DataStore
Это класс, который записывается на диск.
[Serializable]
public class DataStore : ISerializationCallbackReceiver
{
public List<string> serializedObjects;
public DataStore()
{
serializedObjects = new List<string>();
}
#region ISerializationCallbackReceiver_Methods
/// <summary>
/// Serialization implementation from ISerializationCallbackReceiver
/// </summary>
public void OnBeforeSerialize() {}
/// <summary>
/// Deserialization implementation from ISerializationCallbackReceiver
/// </summary>
public void OnAfterDeserialize()
{
Debug.Log("OnAfterDeserialize Loaded Count: " + serializedObjects.Count);
foreach (string so in serializedObjects)
{
Debug.Log(so);
}
}
#endregion
public void AddSerializedObjects(List<ScriptableObject> scriptableObjects)
{
foreach(ScriptableObject so in scriptableObjects)
{
serializedObjects.Add(JsonUtility.ToJson(so));
}
}
public List<ScriptableObject> GetStoredSerializedObjects()
{
//return JsonUtility.FromJsonOverwrite(serializedObjects.ToString(), new List<ScriptableObject>());
List<ScriptableObject> temp = new List<ScriptableObject>();
foreach (string so in serializedObjects)
{
//ScriptableObject file = ScriptableObject.CreateInstance(JsonUtility.FromJson<ScriptableObject>(so));
var json = JsonUtility.FromJson<ScriptableObject>(so);
//JsonUtility.FromJsonOverwrite(so, stemp);
ScriptableObject file = ScriptableObject.CreateInstance((ScriptableObject)json);
temp.Add(file);
}
return temp;
}
}
После того, как данные будут считаны из файла сохранения, я могу вывести их, чтобы увидеть данные SO.
Вот как выглядит SO
DataManager
public class DataManager : MonoBehaviour
{
public List<ScriptableObject> managedData = new List<ScriptableObject>();
private DataStore m_Data;
[NonSerialized]
private IDataSaver m_Saver;
private void Awake()
{
m_Saver = new JsonSaver();
m_Data = new DataStore();
LoadData();
}
public void SaveData()
{
m_Data.AddSerializedObjects(managedData);
m_Saver.Save(m_Data);
}
public void LoadData()
{
Debug.Log("LoadData()");
m_Saver.Load(m_Data);
//Here is where I am trying to put the scriptable objects back
//managedData.Clear();
//managedData.AddRange(m_Data.GetStoredSerializedObjects()));
//managedData = m_Data.GetStoredSerializedObjects();
}
}
IDataSaver
public interface IDataSaver {
void Save(DataStore data);
bool Load(DataStore data);
}
JsonSaver
public class JsonSaver : IDataSaver {
private static readonly string s_Filename = "data_editor.sav";
public static string GetSaveFilename()
{
return string.Format("{0}/{1}", Application.persistentDataPath, s_Filename);
}
protected virtual StreamWriter GetWriteStream() {
return new StreamWriter(new FileStream(GetSaveFilename(), FileMode.Create));
}
protected virtual StreamReader GetReadStream() {
return new StreamReader(new FileStream(GetSaveFilename(), FileMode.Open));
}
public void Save(DataStore data) {
string json = JsonUtility.ToJson(data);
using (StreamWriter writer = GetWriteStream()) {
writer.Write(json);
}
}
public bool Load(DataStore data) {
string loadFilename = GetSaveFilename();
if (File.Exists(loadFilename)) {
using (StreamReader reader = GetReadStream()) {
JsonUtility.FromJsonOverwrite(reader.ReadToEnd(), data);
}
return true;
}
return false;
}
}