Saving a serialisable dictionary

Discussion and help for Easy Save 3
c-andrews
Posts: 3
Joined: Fri Nov 27, 2020 7:44 pm

Saving a serialisable dictionary

Post by c-andrews »

Hi, could you tell me if there is any examples on how to properly use a serialised dictionary with ES3?

I’ve got the Dictionary working but I need to convert it so that I can see it in the inspector.

Thanks in advance
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving a serialisable dictionary

Post by Joel »

Hi there,

Easy Save is only responsible for saving and loading data. If you want information on displaying variables in the Unity Editor, you would need to ask on the Unity forums as this question is a Unity one rather than an Easy Save one.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
c-andrews
Posts: 3
Joined: Fri Nov 27, 2020 7:44 pm

Re: Saving a serialisable dictionary

Post by c-andrews »

Sorry Joel I've just re-read my message and I didn't explain my issue very well.

I currently have a SerializedDictionary working in the inspector but currently I cannot get it to work with ES3. So I was wondering if there were any examples of how to get it working.

I am getting this error when I try to save using ES3:

Code: Select all

NotSupportedException: Generic type "SerializableDictionary`2[LanguageCode,PlayerGameDictionary]" is not supported by Easy Save.
ES3Internal.ES3TypeMgr.CreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:94)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:32)
ES3Types.ES3ObjectType.Write (System.Object obj, ES3Writer writer) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:29)
ES3Writer.Write (System.Object value, ES3Types.ES3Type type, ES3+ReferenceMode memberReferenceMode) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:221)
ES3Writer.Write (System.Object value, ES3+ReferenceMode memberReferenceMode) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:161)
ES3Writer.WriteProperty (System.String name, System.Object value, ES3+ReferenceMode memberReferenceMode) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:262)
ES3Writer.WriteProperty (System.String name, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:250)

I am using a SerializableDictionary<string, SerializableDictionary<string, MySerializableClass>>

Thanks,
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving a serialisable dictionary

Post by Joel »

Hi there,

Assuming your SerializableDictionary uses a Keys and Values array and OnBeforeSerialize/OnAfterDeserialize method (as Unity suggests), you would need to call your OnBeforeSerialize method and then save these arrays. Then you would load these arrays, and call your OnAfterDeserialize method.

I.e.

Code: Select all

// Save
dict.OnBeforeSerialize();
ES3.Save("keys", keys);
ES3.Save("values", values);

// Load
var dict = new SerializableDictionary();
dict.keys = ES3.Load<LanguageCode[]>("keys");
dict.values = ES3.Load<PlayerGameDictionary[]>("values");
dict.OnAfterDeserialize();
if you wanted to do it with a single ES3.Save/Load call, you could create an ES3Type which does this instead using the instructions here:
https://docs.moodkie.com/easy-save-3/es ... g-es3types

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
c-andrews
Posts: 3
Joined: Fri Nov 27, 2020 7:44 pm

Re: Saving a serialisable dictionary

Post by c-andrews »

Thanks Joel,

I am currently using the Serialised Dictionary from Odin Inspector: https://odininspector.com/tutorials/ser ... ctionaries

Code: Select all

public class MyCustomSerializedDictionary : UnitySerializedDictionary <string, PlayerGameData> { };
Would it be a case of creating the Type for my MyCustomSerializedDictionary? Im assuming I would just need the keyData and valueData to be serialised?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving a serialisable dictionary

Post by Joel »

Hi there,

You would follow the same instructions as mentioned in my previous post. Just making a type for it without calling OnBeforeSerlialize and OnAfterDeserialize wouldn't work because it won't add the data to the Dictionary, and these methods aren't called at runtime.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Alex
Posts: 6
Joined: Sat Oct 29, 2022 12:14 pm

Re: Saving a serialisable dictionary

Post by Alex »

Strange thing happens. I have working project (2021.3.20f) where I use just use:

Code: Select all

ES3.Save("levels", levelSaveData, _es3Settings);
levelSaveData = ES3.Load("levels", new Dict<int, LevelSaveData>());
without calling OnBeforeSerialize or OnAfterDeserialize and everything works fine.

I have created new project (2021.3.25f), moved all scripts here, and now I am getting this error:
NotSupportedException: Generic type "Storage.Dict`2[System.Int32,Storage.LevelSaveData]" is not supported by Easy Save.
ES3Internal.ES3TypeMgr.CreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:96)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:32)
ES3Writer.Write (System.Type type, System.String key, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:142)
ES3Writer.Write[T] (System.String key, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:129)
ES3.Save[T] (System.String key, T value, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:111)
Storage.SaveManager.SaveLevelData () (at Assets/Scripts/Storage/SaveManager.cs:249)
Here is Dict class:

Code: Select all

[Serializable]
    public class Dict<TKey, TValue> : ES3SerializableDictionary<TKey, TValue>
    {
        protected override bool KeysAreEqual(TKey a, TKey b)
        {
            return a.Equals(b);
        }

        protected override bool ValuesAreEqual(TValue a, TValue b)
        {
            return a.Equals(b);
        }
    }
Seems I have same version of ES3 3.5.6, but there is more records in Editor Settings in new project, maybe its related to different Unity Version

Where could be problem?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving a serialisable dictionary

Post by Joel »

Alex wrote: Sun Oct 22, 2023 6:03 am Strange thing happens. I have working project (2021.3.20f) where I use just use:

Code: Select all

ES3.Save("levels", levelSaveData, _es3Settings);
levelSaveData = ES3.Load("levels", new Dict<int, LevelSaveData>());
without calling OnBeforeSerialize or OnAfterDeserialize and everything works fine.

I have created new project (2021.3.25f), moved all scripts here, and now I am getting this error:
NotSupportedException: Generic type "Storage.Dict`2[System.Int32,Storage.LevelSaveData]" is not supported by Easy Save.
ES3Internal.ES3TypeMgr.CreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:96)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:32)
ES3Writer.Write (System.Type type, System.String key, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:142)
ES3Writer.Write[T] (System.String key, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:129)
ES3.Save[T] (System.String key, T value, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:111)
Storage.SaveManager.SaveLevelData () (at Assets/Scripts/Storage/SaveManager.cs:249)
Here is Dict class:

Code: Select all

[Serializable]
    public class Dict<TKey, TValue> : ES3SerializableDictionary<TKey, TValue>
    {
        protected override bool KeysAreEqual(TKey a, TKey b)
        {
            return a.Equals(b);
        }

        protected override bool ValuesAreEqual(TValue a, TValue b)
        {
            return a.Equals(b);
        }
    }
Seems I have same version of ES3 3.5.6, but there is more records in Editor Settings in new project, maybe its related to different Unity Version

Where could be problem?
Hi there,

The only way this would work in your original project is if you made an ES3Type for Dict<int, LevelSaveData>, or you're using a non-standard modified version of Easy Save (which we can't support).

If it's the first one, have you ensured that you've copied the Assets/Easy Save 3/Types/ folder to your new project?

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Alex
Posts: 6
Joined: Sat Oct 29, 2022 12:14 pm

Re: Saving a serialisable dictionary

Post by Alex »

I am using just simple ES3 installed from Package Manager. You mean Assets/Plugins/Easy Save 3/Scripts/Types folder?
Or there should be some another folder with types? I am not sure if I made such types in that project, because it was 9 month ago and I don't remember, but I think I didn't make some additional types, because https://docs.moodkie.com/easy-save-3/ge ... ollections as I see ES3 supports dictionaries.
Alex
Posts: 6
Joined: Sat Oct 29, 2022 12:14 pm

Re: Saving a serialisable dictionary

Post by Alex »

Hmmm, I believed that it wont help, but it worked, i replaced Types folder and everything is working now. If some custom scripts are made from Editor, maybe better to created separate folder for user types
Post Reply