Search Unity

Mayor problem when attempting to save custom class using binary formater.

Discussion in 'Scripting' started by raycosantana, Apr 17, 2014.

  1. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    Im trying to save a Custom Class I created, before this I had every player stat separate but for convenience reasons I created a custom class so I could save it with one line, but now I get this really big error message:

    Code (csharp):
    1. SerializationException: Type UnityEngine.MonoBehaviour in assembly UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null is not marked as serializable.
    2. System.Runtime.Serialization.FormatterServices.GetSerializableMembers (System.Type type, StreamingContext context) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization/FormatterServices.cs:101)
    3. System.Runtime.Serialization.Formatters.Binary.CodeGenerator.GenerateMetadataTypeInternal (System.Type type, StreamingContext context) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs:78)
    4. System.Runtime.Serialization.Formatters.Binary.CodeGenerator.GenerateMetadataType (System.Type type, StreamingContext context) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs:64)
    5. System.Runtime.Serialization.Formatters.Binary.ObjectWriter.CreateMemberTypeMetadata (System.Type type) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:442)
    6. System.Runtime.Serialization.Formatters.Binary.ObjectWriter.GetObjectData (System.Object obj, System.Runtime.Serialization.Formatters.Binary.TypeMetadata metadata, System.Object data) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:430)
    7. System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObject (System.IO.BinaryWriter writer, Int64 id, System.Object obj) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:306)
    8. System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectInstance (System.IO.BinaryWriter writer, System.Object obj, Boolean isValueObject) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:293)
    9. System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteQueuedObjects (System.IO.BinaryWriter writer) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:271)
    10. System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectGraph (System.IO.BinaryWriter writer, System.Object obj, System.Runtime.Remoting.Messaging.Header[] headers) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:256)
    11. System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header[] headers) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:232)
    12. System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:211)
    13. SaveSystem.Save () (at Assets/scripts/Singletons/SaveSystem.cs:69)
    14. Goal.GoalFunc (Int32 id) (at Assets/scripts/Sistem/Goal.cs:50)
    15. UnityEngine.GUILayout+LayoutedWindow.DoWindow (Int32 windowID) (at C:/BuildAgent/work/d3d49558e4d408f4/artifacts/EditorGenerated/GUILayout.cs:412)
    16. UnityEngine.GUI.CallWindowDelegate (UnityEngine.WindowFunction func, Int32 id, UnityEngine.GUISkin _skin, Int32 forceRect, Single width, Single height, UnityEngine.GUIStyle style) (at C:/BuildAgent/work/d3d49558e4d408f4/artifacts/EditorGenerated/GUI.cs:1395)
    This is beyond my comprehension, well I do understand it says its not marked as Serializable but the custom class is marked as Serializable.

    Here the class I created:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. [System.Serializable]
    5. public class BaseCharacter : MonoBehaviour {
    6.     public string Name;
    7.     public int CurHP;
    8.     public int MaxHP = 100;
    9.     public int CurMP;
    10.     public int MaxMP = 50;
    11.     public int PHAttack = 10;
    12.     public int PHDefense = 10;
    13.     public int MGAttack = 10;
    14.     public int MGDefense = 10;
    15.    
    16.     /************States***************/
    17.     public bool Regen = false;
    18.     public bool Poison = false;
    19.     public bool Flames = false;
    20.    
    21.    
    22.    
    23.    
    24.    
    25. }
    And here my save system:

    Code (csharp):
    1. using System.Collections.Generic;
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5. //You must include these namespaces
    6. //to use BinaryFormatter
    7. using System;
    8. using System.Runtime.Serialization.Formatters.Binary;
    9. using System.IO;
    10. using System.Linq;
    11.  
    12. public class SaveSystem : MonoBehaviour {
    13.     public BaseCharacter DefaultCharacter;
    14.         [System.Serializable]
    15.     public class SaveEntry{
    16.         public BaseCharacter PlayerCharacter;
    17.         public int potions;
    18.         public int potionPower;
    19.         public int TotalLoot;
    20.         public int TotalGold;
    21.         public int TotalEnemies;
    22.         public float TotalTime;
    23.         public List<LevelContainer> Levels = new List<LevelContainer>();
    24.         public List<Item> Inventory = new List<Item>();
    25.     }
    26.  
    27.  public SaveEntry SaveData = new SaveEntry();
    28.    
    29.     // Use this for initialization
    30.     public static SaveSystem Instance { get; private set; }
    31.  
    32.     void Awake()
    33.     {
    34.         if(Instance != null  Instance != this)
    35.         {
    36.             // If that is the case, we destroy other instances
    37.             Destroy(gameObject);
    38.         }
    39.         // First we check if there are any other instances conflicting
    40.         // Here we save our singleton instance
    41.        
    42.  
    43.         // Furthermore we make sure that we don't destroy between scenes (this is optional)
    44.        
    45.         DontDestroyOnLoad(gameObject);
    46.     }
    47.     void Start(){
    48.         //PlayerPrefs.DeleteAll();
    49.         Instance = this;
    50.         Load ();
    51.     }
    52.    
    53.     public void Save(){
    54.         SaveData.PlayerCharacter = Status.Instance.PlayerCharacter;
    55.         SaveData.potions = Status.Instance.potions;
    56.         SaveData.potionPower = Status.Instance.potionPower;
    57.         SaveData.TotalLoot = Status.Instance.TotalLoot;
    58.         SaveData.TotalGold = Status.Instance.TotalGold;
    59.         SaveData.TotalEnemies = Status.Instance.TotalEnemies;
    60.         SaveData.TotalTime = Status.Instance.TotalTime;
    61.         SaveData.Levels = Status.Instance.Levels;
    62.            
    63.        
    64.         //Get a binary formatter
    65.         var b = new BinaryFormatter();
    66.         //Create an in memory stream
    67.         var m = new MemoryStream();
    68.         //Save the scores
    69.         b.Serialize(m, SaveData);
    70.         //Add it to player prefs
    71.         PlayerPrefs.SetString("SaveFile", Convert.ToBase64String(m.GetBuffer()));
    72.         PlayerPrefs.Save();
    73.         Debug.Log ("Save complete " );
    74.     }
    75.  
    76.    public void Load(){
    77.                 //Get the data
    78.         var data = PlayerPrefs.GetString("SaveFile");
    79.         //If not blank then load it
    80.         if(!string.IsNullOrEmpty(data))
    81.         {
    82.             //Binary formatter for loading back
    83.             var b = new BinaryFormatter();
    84.             //Create a memory stream with the data
    85.             var m = new MemoryStream(Convert.FromBase64String(data));    
    86.         SaveEntry SaveData = (SaveEntry)b.Deserialize(m);
    87.         Status.Instance.PlayerCharacter = SaveData.PlayerCharacter;
    88.         Status.Instance.potions = SaveData.potions;
    89.         Status.Instance.potionPower = SaveData.potionPower;
    90.         Status.Instance.TotalLoot = SaveData.TotalLoot;
    91.         Status.Instance.TotalGold = SaveData.TotalGold;
    92.         Status.Instance.TotalEnemies = SaveData.TotalEnemies;
    93.         Status.Instance.TotalTime = SaveData.TotalTime;
    94.         foreach (LevelContainer L in SaveData.Levels.Where (i=> i.Bought == true)){
    95.                 SendMessage("LoadLevels",L.Name);
    96.             }
    97.         }
    98.         if(string.IsNullOrEmpty(data)){
    99.         Status.Instance.PlayerCharacter = DefaultCharacter;
    100.         Status.Instance.potions = 0;
    101.         Status.Instance.potionPower = 25;
    102.         Status.Instance.TotalLoot = 0;
    103.         Status.Instance.TotalGold = 0;
    104.         Status.Instance.TotalEnemies = 0;
    105.         Status.Instance.TotalTime = 0;
    106.         Status.Instance.Levels[0].Bought = true;
    107.         }
    108.     }
    109.    
    110.     public void LoadLevels(string Level){
    111.        
    112.         for(int t = 0; t < Status.Instance.Levels.Count; t++) {
    113.         if (Status.Instance.Levels[t].Name == Level){
    114.                 Status.Instance.Levels[t].Bought = true;
    115.                     }
    116.                 }
    117.        }
    118. }
    119.  
    Any help is welcome.
     
    Last edited: Apr 17, 2014