Hi there! I'm editing my original question because I was just looking at the tip of the iceberg and thus formulated a too much open/broad/generic question two days ago.
I'm using procedural generation to build the scenes/levels in which my buggy game takes place.
It went all good until I decided that'd have been awesome to force the machine to remember those scenes.
Now I'm fighting against the limits of the engine because it seems that, *even if Vector 3 should now be a serializable class*, many classes I'd like to save into a binary file are **not truly** serialisable.
It seems that I've managed to get to the point where Unity doesn't crash and executes everything, but the binary files I export are messed up because an error keeps showing up: **SerializationException: Type UnityEngine.Vector3 is not marked as Serializable.**
Here's what I need:
1. To Serialize a custom class, MatrixMaster, which is a class that handles all the things procedurally generated in the scene, from the props ( Game Objects) to the grid ( custom class) used by agents to move around
2. To Deserialize that class
3. To do it with the type of Serialization I'm most " proficient" with, which is the one with BinaryFormatter
This is, so far, the chunks of code about my custom class I've got:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Reflection;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization;
//using System.Diagnostics;
[Serializable]
public class MatrixMaster : ScriptableObject, ISerializable {
#region Fields
//A bunch of fields, custom class ones are Serializable
//GameObjects are comprised
#endregion
#region Properties
//A bunch of properties...
#endregion
// Implement this method to serialize data. The method is called on serialization.
public void GetObjectData (SerializationInfo info, StreamingContext context)
{
info.AddValue("ScriptableType", this.GetType().AssemblyQualifiedName, typeof(string));
foreach(FieldInfo field in this.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance))
{
info.AddValue(field.Name, field.GetValue(this), field.FieldType);
}
}
public void SerializeThisToBinary (){
// To serialize the MatrixMaster and its values, we must first open a stream for writing
FileStream fs = new FileStream(Application.persistentDataPath + "/matrix_" + this.associatedLevel.ToString() + ".dat", FileMode.Create);
// Construct a BinaryFormatter and use it to serialize the data to the stream.
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(fs, this);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}
}
///
/// Deserializes a matrix saved into a binary file to an instance of that class.
///
/// Returns a matrix with the values cached inside the binary file.
/// The number of the scene with which the matrix to load was saved.
/// The instance of the matrix to write into.
public MatrixMaster DeserializeTo (int matrixScene, out MatrixMaster matrix){
//This is written poorly by me, or a more competent approach see this: https://msdn.microsoft.com/it-it/library/b85344hz(v=vs.110).aspx
//I like the Try Catch Finally thing
//Construct a BinaryFormatter and use it to deserialize the data to the stream
BinaryFormatter formatter = new BinaryFormatter();
//Open the file containing the data we want to deserialize
FileStream file = File.Open(Application.persistentDataPath + "/matrix_" + matrixScene.ToString() + ".dat", FileMode.Open);
//Declare the instance reference
matrix = ScriptableObject.CreateInstance();
// Deserialize the MatrixMaster from the file and assign the reference to the local variable
matrix = (MatrixMaster) formatter.Deserialize(file);
//Close the stream
file.Close();
//Return
return matrix;
}
}
I've referenced a lot of stuff to get to this point ( I'm quoting all links because I'd like question to be helpful to others too and this sets everybody on the same page):
- [ISerializable Interface][1]
- [Wrapping Up ISerializables][2]
- [Deserialize Method][3]
- [SerializationInfo][4]
- [Implement ISerializable correctly][5]
- [Custom Serialization][6]
[1]: https://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx
[2]: http://forum.unity3d.com/threads/how-to-serialize-scripable-object-at-runtime.246643/
[3]: https://msdn.microsoft.com/it-it/library/b85344hz(v=vs.110).aspx
[4]: https://msdn.microsoft.com/it-it/library/system.runtime.serialization.serializationinfo(v=vs.110).aspx
[5]: https://msdn.microsoft.com/it-it/library/ms182342.aspx
[6]: https://msdn.microsoft.com/it-it/library/ty01x675(v=vs.110).aspx
↧