Reputation: 23
Ok so I followed the Unity3D data persistence tutorial, everything is going smoothly until I tried to save a Vector3 type of data. The tutorial only shows how to save int and strings.
When I used the function Save() , the consoles shows me that says: "SerializationException: Type UnityEngine.Vector3 is not marked as Serializable.
But as you can see from my code, I included it under the Serializable part. I am trying to save my playerPosition. Thanks
using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections.Generic;
public class GameManager : MonoBehaviour
{
public static GameManager control;
public float health;
public float mana;
public float experience;
public Vector3 playerPosition;
public List<Item> inventory = new List<Item>();
void Awake()
{
if(control == null)
{
DontDestroyOnLoad(gameObject);
control = this;
}
else if(control != this)
{
Destroy(gameObject);
}
}
// Use this for initialization
void Start (){}
// Update is called once per frame
void Update () {}
void OnGUI()
{
GUI.Box(new Rect(10, 10, 100, 30), "Health: " + health);
GUI.Box(new Rect(10, 30, 100, 30), "Mana: " + mana);
GUI.Box(new Rect(10, 50, 100, 30), "Experience: " + experience);
}
public void SaveSlot1()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath +
"/saveData1.dat");
PlayerData data = new PlayerData();
data.health = health;
data.mana = mana;
data.experience = experience;
data.playerPosition = playerPosition;
for(int i = 0; i <inventory.Count; i++)
{
//data.inventory[i] = inventory[i];
}
bf.Serialize(file, data);
file.Close();
}
public void LoadSlot1()
{
if(File.Exists(Application.persistentDataPath +
"/saveData1.dat") )
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath +
"/saveData1.dat", FileMode.Open);
PlayerData data = (PlayerData)bf.Deserialize(file);
file.Close();
health = data.health;
mana = data.mana;
experience = data.experience;
playerPosition = data.playerPosition;
for(int i = 0; i <inventory.Count; i++)
{
//inventory[i] = data.inventory[i];
}
}
}
[Serializable]
class PlayerData
{
public float health;
public float mana;
public float experience;
public Vector3 playerPosition;
public List<Item> inventory = new List<Item>();
//position
//spells
//
}
}
Upvotes: 2
Views: 4686
Reputation: 5313
Marking something as Serializable just let's .NET to know that you are going to be using serialization. At that point every property all the way down the data model must also be serializable, either by being inherently serializable like ints and strings, or being a type that is also marked as serializable. There's a couple of options
[Serializable]
class PlayerData
{
public PlayerData()
{
playerPosition = Vector3.zero;
}
public float health;
public float mana;
public float experience;
[NonSerialized]
public Vector3 playerPosition;
public double playerPositionX
{
get
{
return playerPosition.x;
}
set
{
playerPosition.x = value;
}
}
public double playerPositionY
{
get
{
return playerPosition.y;
}
set
{
playerPosition.y = value;
}
}
public double playerPositionZ
{
get
{
return playerPosition.z;
}
set
{
playerPosition.z = value;
}
}
public List<Item> inventory = new List<Item>();
}
This first option will not serialize the vector field, and instead use the properties. Having a vector to start with is important.
The other option is to implement the ISerializable interface on your class and then specifically control what fields are being written. The interface is somewhat tricky to implement, here is a MSDN link that explains some good and bad examples
Upvotes: 3