0
\$\begingroup\$

I am trying to save/persist some data between my scenes but I keep getting the error:

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

Here is my script:

public static void SaveState()
    {

        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Open(Application.persistentDataPath + "/EmpireGame", FileMode.OpenOrCreate);

        SaveClass sc = new SaveClass()
        {
            food = Player.food.amount,
            wood = Player.wood.amount,
            iron = Player.iron.amount,
            stone = Player.stone.amount,
            buildingList = new List<Building>(),

    };
        sc.buildingList = playerBuilt;

        Debug.Log("State Saved!");

        bf.Serialize(file, sc);
        file.Close();
    }
}

[Serializable]
class SaveClass
    {
        public int food, wood, iron, stone;
    public List<Building> buildingList;


}

I've narrowed it down to: public List buildingList; being the offending code, but I don't know how else to save this list. I think the MonoBehaviour part of it is the "" as it inherits from MonoBehaviour.

I've read:

Unity Docs: Serialization

Watched:

persistence-saving-and-loading-data

Saving Data In Unity

I've looked up so many Q&A's over this but still can't figure it out.

\$\endgroup\$
  • \$\begingroup\$ Is the Building class is not serializable? \$\endgroup\$ – wondra Apr 10 '18 at 15:14
1
\$\begingroup\$

Remember when I suggested pulling out just the parts of the component you wanted to save, and putting them in a serializable struct? This is another reason why.

Unity's component types are not natively tagged with the [System.Serializable] attribute, so your BinaryFormatter doesn't know how to serialize & deserialize them properly. (Which makes sense, because correctly deserializing a list of MonoBehaviour components would require knowing which GameObjects in the scene to attach them to, and how to work with Unity to update the scene hierarchy - a .Net standard method that doesn't know anything about Unity can't do that for you.

Defining your own serializable type lets you control exactly what gets saved/loaded and how, to make sure it does the right thing for your game. You can also make your save files more robust against minor changes to your game. Say you change the sprite used for Farm buildings in a recent update. If your save file contained the whole GameObject serialized, then when you load the old save in the new version it could still be referencing an old texture (or no texture at all if it's been removed from the build). By serializing just the information that it's a "Farm-type building, of level L, at position X, Y" lets the updated version of your game spawn a correct, modern, up-to-date version of the farm with those properties, rather than getting clogged with legacy data.

\$\endgroup\$
  • \$\begingroup\$ Finally understood what you were trying to convey in the other question (link provided above). It works great thank you so much \$\endgroup\$ – Anon Apr 12 '18 at 13:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.