Reputation: 21
I would like to save the data with a binary form but it doesn't work and says << SerializationException: Type 'UnityEngine.MonoBehaviour' in Assembly 'UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable. >> Do you know what is the problem?
Here is some parts of my << DataManager >> Script :
public class DataManager : MonoBehaviour {
private string dataPath;
public void Initialize() {
dataPath = Application.persistentDataPath + "/gameData.dat";
}
public void Save(GameData gameData) {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(dataPath);
GameData data = new GameData();
data.level = gameData.level;
data.hp = gameData.hp;
data.mp = gameData.mp;
data.damage = gameData.damage;
data.exp = gameData.exp;
data.maxExp = gameData.maxExp;
data.equipItem = gameData.equipItem;
bf.Serialize(file, data);
file.Close();
}
And here are some parts of << GameManager >> script :
public class GameManager : MonoBehaviour {
private static GameManager m_instance;
public static GameManager instance {
get {
if (m_instance == null) {
m_instance = FindObjectOfType<GameManager>();
}
return m_instance;
}
}
private DataManager dataManager;
public GameData gameData;
public event Action levelUp;
public bool isPlayerDead { get; private set; }
public void Awake() {
if (instance != this) {
Destroy(gameObject);
}
dataManager = GetComponent<DataManager>();
dataManager.Initialize();
LoadGameData();
levelUp += UpdateMaxExp;
levelUp += UpdateMaxHp;
levelUp += UpdateMaxMp;
levelUp += UpdateLevel;
FindObjectOfType<PlayerHealth>().onDeath += PlayerDeath;
}
public void SaveGameData() {
dataManager.Save(gameData);
}
public void OnApplicationQuit() {
SaveGameData();
}
This is the GameData script :
namespace DataInfo {
[System.Serializable]
public class GameData {
public int level = 1;
public float hp = 100f;
public float maxHp = 100f;
public float mp = 100f;
public float maxMp = 100f;
public float damage = 25f;
public float exp = 0f;
public float maxExp = 100;
public List<Item> equipItem = new List<Item>();
}
}
Upvotes: 2
Views: 3936
Reputation: 90871
In general you should NOT use BinaryFormatter
anymore at all!
Consider rather serializing via JSON
or XML
Also in general don't use +"/..."
for system paths. As different platforms use different system path separators you should rather use Path.Combine
which always uses the correct separator depending on the platform (OS)
dataPath = Path.Combine(Application.persistentDataPath, "gameData.dat");
Finally don't directly (de)serialize a MonoBehaviour
!
It makes no sense since a MonoBehaviour
may not exist without being attached to a GameObject
.. so you can't deserialize it (in a valid way) anyway and using new
on it is forbidden .. which is what the BinaryFormatter
internally does.
The only exception for this is stuff like JsonUtility.FromJsonOverwrite
since it doesn't create a new instance but rather overwrites the fields of an already existing one.
Rather use a "normal" [Serializable]
data contianer class. As soon as a script is
MonoBehaviour
messages like Update
, Awake
etcIt should not inherit from MonoBehaviour
at all but rather simply store the data like e.g.
// not a MonoBehaviour since it has no own behavior anyway
// So this doesn't need to be attached to a specific GameObject but rather simply exists
// somewhere in a field or property
[Serializable]
public class GameData
{
// Your fields here
}
and in the manager have
public GameData gameData = new GameData();
Upvotes: 2
Reputation: 797
Your GameData
class needs to have a [Serializable]
attribute. Depending on what's in that class, you also might want to define how it is serialized.
This question might also help.
Upvotes: -1