0

I'm new on unity, but I know c++, so I have some bases. I've been trying to save these variables for 3 hours, and it's always the same error, no matter what I do :

"SerializationException: Type 'UnityEngine.MonoBehaviour' in Assembly 'UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable."

I don't understand why, because the class is marked :

using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using UnityEngine;

[System.Serializable()]
public class MoneyHandlerData : MonoBehaviour
{
    public int pickaxe = 0;
    public int nbDwarves = 1;

    public double moneyAccount = 10000;
    public double moneyPerSec = 500;

    public int bow = 0;
    public int nbElves = 0;
}

Here's the class I use to Serialize :

using System.Collections;
using System.Collections.Generic; 
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; 
using System.IO;
using UnityEngine;

public class SaveLoad : MonoBehaviour
{
    public MoneyHandlerData save;

    public void Saving()
    {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create (Application.persistentDataPath + "/save.mst");
        bf.Serialize(file, save); //Here's where the problem is
        file.Close();
        Debug.Log("Game saved");
    }

    public void Loading() 
    {
        if(File.Exists(Application.persistentDataPath + "/save.mst")) 
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.persistentDataPath + "/save.mst", 
                FileMode.Open);
            save = (MoneyHandlerData)bf.Deserialize(file);
            file.Close();
            Debug.Log("Game loaded");
        }
    }
}

And here is the full error message :

SerializationException: Type 'UnityEngine.MonoBehaviour' in Assembly 'UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable. System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers (System.RuntimeType type) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.FormatterServices+<>c__DisplayClass9_0.b__0 (System.Runtime.Serialization.MemberHolder _) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Collections.Concurrent.ConcurrentDictionary'2[TKey,TValue].GetOrAdd (TKey key, System.Func'2[T,TResult] valueFactory) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.FormatterServices.GetSerializableMembers (System.Type type, System.Runtime.Serialization.StreamingContext context) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo () (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize (System.Object obj, System.Runtime.Serialization.ISurrogateSelector surrogateSelector, System.Runtime.Serialization.StreamingContext context, System.Runtime.Serialization.Formatters.Binary.SerObjectInfoInit serObjectInfoInit, System.Runtime.Serialization.IFormatterConverter converter, System.Runtime.Serialization.Formatters.Binary.ObjectWriter objectWriter, System.Runtime.Serialization.SerializationBinder binder) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize (System.Object obj, System.Runtime.Serialization.ISurrogateSelector surrogateSelector, System.Runtime.Serialization.StreamingContext context, System.Runtime.Serialization.Formatters.Binary.SerObjectInfoInit serObjectInfoInit, System.Runtime.Serialization.IFormatterConverter converter, System.Runtime.Serialization.Formatters.Binary.ObjectWriter objectWriter, System.Runtime.Serialization.SerializationBinder binder) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize (System.Object graph, System.Runtime.Remoting.Messaging.Header[] inHeaders, System.Runtime.Serialization.Formatters.Binary.__BinaryWriter serWriter, System.Boolean fCheck) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header[] headers, System.Boolean fCheck) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header[] headers) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0) SaveLoad.Saving () (at Assets/Scripts/Save/SaveLoad.cs:18) Quit.Exit () (at Assets/Scripts/Quit.cs:11) UnityEngine.Events.InvokableCall.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent/UnityEvent.cs:166) UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent/UnityEvent/UnityEvent_0.cs:58) UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:66) UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:108) UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:50) UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction'1[T1] functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261) UnityEngine.EventSystems.EventSystem:Update()

This barely make sens to me, but if someone could enlighten me please, you would make my day (Sorry if the post is too long)

Thanks

Rufus L
  • 36,127
  • 5
  • 30
  • 43
Hugal
  • 1
  • 1
    Remove the base class, i.e. `class MoneyHandlerData : MonoBehavior` → `class MoneyHandlerData` – p.s.w.g Jun 17 '19 at 20:33
  • Now the class is missing the class attribute 'ExtensionOfNativeClass' :/ – Hugal Jun 17 '19 at 20:37
  • As Anton explained in his answer, the BinaryFormatter tries to serialize the class `MoneyHandlerData` (and thus its base class too), but the base `MonoBehaviour` class isn't marked as `Serializable` (and no, you can't do that by yourself), so it throws the exception (which btw states exactly where the problem is). – Galandil Jun 17 '19 at 21:11
  • 1
    Possible duplicate of [What is the best way to save game state?](https://stackoverflow.com/questions/40965645/what-is-the-best-way-to-save-game-state) – Draco18s no longer trusts SE Jun 18 '19 at 03:49
  • Thanks Galandil, this is clearer now ! – Hugal Jun 18 '19 at 15:59

1 Answers1

3

You get that error because you tried to serialize the Mono Behaviour (ie the component) itself. What you wanted to do is to serialize just the data. What you can do is to put the data in a class in itself and serialize that

[System.Serializable()]
public class MoneyHandlerData  //Note - no monobehaviour
{
    public int pickaxe = 0;
    public int nbDwarves = 1;

    public double moneyAccount = 10000;
    public double moneyPerSec = 500;

    public int bow = 0;
    public int nbElves = 0;
}

Now that this class is not a MonoBehaviour anymore you can't use it as a component, that's why you get ExtensionOfNativeClass error. You can keep it in the state of a monobehaviour though

public class MoneyHandler : MonoBehaviour
{
    MoneyHandlerData  data; //Serialize me
}

You can also make the save - load class not a MonoBehaviour, since it doesn't use any of its functionality. Not everything has to be a Component in Unity. You can make the functions static, so that you can access them from anywhere and just let them take in the object to be serialized as a parameter (e.g. the MoneyHandlerData object)

Anton Mihaylov
  • 938
  • 5
  • 10