Search Unity

Saving generic list of several instances of a class that inherit from another class

Discussion in 'Scripting' started by Collin__Patrick, May 2, 2016.

  1. Collin__Patrick

    Collin__Patrick

    Joined:
    May 20, 2015
    Posts:
    188
    I keep getting an error that tells me that my CharacterSheet class needs to be serializable when I try to save and whenever I put [system.serializable] at the top of the class, it gives me a similar error that the class that my CharacterSheet inherits from also needs to be serializable. I put [System.Serializable] at the top of it and then I get another error that monobehaviour needs to be serializable. I am sure that I am doing something wrong but I cant figure out what after hours of googling.

    Save/Load Script:
    Code (CSharp):
    1. public class CharacterManager : MonoBehaviour
    2. {
    3.     public static CharacterManager characterManager;
    4.    
    5.     void Awake () {
    6.         if (characterManager == null) {
    7.             characterManager = this;
    8.             DontDestroyOnLoad (gameObject);
    9.         }else if(characterManager != this){
    10.             Destroy(gameObject);
    11.         }
    12.     }
    13.  
    14.     public List<GameObject> CharactersSaveAndLoad = new List<GameObject>(2);
    15.     public List<CharacterSheet> CharacterSheetsSaveAndLoad = new List<CharacterSheet>(2);
    16.  
    17.     public void GetSheets(){
    18.         CharacterSheetsSaveAndLoad.Clear();
    19.         for (int i = 0; i < CharactersSaveAndLoad.Count; i++) {
    20.             CharacterSheetsSaveAndLoad.Add (CharactersSaveAndLoad[i].GetComponent<CharacterSheet>());
    21.         }
    22.     }
    23.     public void Save(){
    24.         BinaryFormatter bf = new BinaryFormatter ();
    25.         FileStream file = File.Create (Application.persistentDataPath + "/playerInfo.dat");
    26.  
    27.         GetSheets ();
    28.         CharacterData data = new CharacterData ();
    29.  
    30.         data.Sheets = CharacterSheetsSaveAndLoad;
    31.         bf.Serialize (file, data);
    32.         file.Close();
    33.         Debug.Log ("Save Compleated");
    34.        
    35.     }
    36.     public static void Load(GameObject CharacterObject){
    37.         CharacterSheet objectCharacterSheet = CharacterObject.GetComponent<CharacterSheet>();
    38.         //CharacterSheet findCharacterSheet = CharacterObject.GetComponent<CharacterSheet>();
    39.  
    40.         if (File.Exists (Application.persistentDataPath + "/playerInfo.dat")) {
    41.             BinaryFormatter bf = new BinaryFormatter ();
    42.             FileStream file = File.Open (Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
    43.             CharacterData data = (CharacterData)bf.Deserialize(file);
    44.             file.Close();
    45.  
    46.             for (int i = 0; i < data.Sheets.Count; i++){
    47.                 if (data.Sheets[i].objectID == objectCharacterSheet.objectID){
    48.                     //findCharacterSheet = data.Sheets[i];
    49.                     objectCharacterSheet.characterName = data.Sheets[i].characterName;//findCharacterSheet.characterName;
    50.                 }
    51.             }
    52.  
    53.         }
    54.     }
    55. }
    56.  
    57. [System.Serializable]
    58. public class CharacterData{
    59.     public List<CharacterSheet> Sheets;
    60.  
    61. }
     
  2. SirNiklas

    SirNiklas

    Joined:
    Jun 7, 2015
    Posts:
    85
    It is impossible to serialize instances of types that inherit from MonoBehaviour with the BinaryFormatter because MonoBehaviour does not have a Serializable-attribute applied. You need to transfer all the data you want to save from the CharacterSheet instances into new serializable container class instances and then serialize these.

    Code (CSharp):
    1. class CharacterSheet : MonoBehaviour
    2. {
    3.    public string name;
    4.    public int intelligence;
    5. }
    6.  
    7. [Serializable]
    8. class CharacterSheetContainer
    9. {
    10.    public string name;
    11.    public int intelligence;
    12.  
    13.    public CharacterSheetContainer(CharacterSheet charSheet)
    14.    {
    15.       this.name = charSheet.name;
    16.       this.intelligence = charSheet.intelligence;
    17.    }
    18. }
     
    ThermalFusion likes this.
  3. Collin__Patrick

    Collin__Patrick

    Joined:
    May 20, 2015
    Posts:
    188
    Thank you. This is exactly what I needed. Your help is very much appreciated.