Serialization exception for vector3 when no vector3 is mentioned when trying to save variables

Viewed 47

I'm building off of Sebastian Lague's videos on procedural planets, and I stopped where I was happy with what the scripts did. So I worked on procedurally generating a system with the planets based off of presets.

I got to saving these systems with AssetDatabase.Save and Load and when it didnt work to build I moved to formatting it to save the data. I used Binary formatting because it seemed simple and the easiest to find tutorials on how to do.

However when I attempt to save data I get

SerializationException: Type 'UnityEngine.Vector3' in Assembly 'UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

here's the scripts that cause the errors

Save script

using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

[System.Serializable]
public class Vector3Ser // serializealbe Vector3
{
public float x, y, z;
}

[System.Serializable]
public static class SaveSystem
{

const string savesPath = "/Saves";
public static void Save<t>(t obj, string key)
{
    BinaryFormatter bf = new BinaryFormatter();
    string path = Application.persistentDataPath + savesPath;
    Directory.CreateDirectory(path); // create path if it doesnt exist

    FileStream stream = new FileStream(path + key, FileMode.Create);
    bf.Serialize(stream, obj); // save obj
    
    stream.Close();
}

public static void CreateFolder(string key)
{
    string path = Application.persistentDataPath + savesPath;
    Directory.CreateDirectory(path + key); // create folder at path
}


public static T Load<T>(string key)
{
    BinaryFormatter bf = new BinaryFormatter();
    string path = Application.persistentDataPath + savesPath;

    T data = default;

    if (File.Exists(path + key))
    {
        
        FileStream stream = new FileStream(path + key, FileMode.Open);
        stream.Flush(); //no idea why its there but I found it somewhere and tried it
        stream.Position = 0; //no idea why its there but I found it somewhere and tried it
        data = (T)bf.Deserialize(stream); // save the deserialized file to a variable
        stream.Close();

    } else
    {
        Debug.LogError("Failed to load save at " + path + key);
    }

    return data; // return file/data
}


public static bool SaveExists(string key)
{
    string path = Application.persistentDataPath + savesPath;

    return File.Exists(path + key);
}

}

Data class that I'm attempting to save

[System.Serializable]
public class PlanetData
{
public string planetName;
public Vector3Ser planetPos;
public int planetID = -1;
public float planetRadius;
public bool[] noiseLayerEnabled;
public bool[] nLFirstLayerAsMask;
public NoiseSettings[] noiseLayerNoiseSettings;
public string indentifier;



public PlanetData(ShapeSettings sS, ColourSettings cS)
{
    planetName = sS.name + "_" + cS.name; // load name

    planetRadius = sS.planetRadius; // load radius and planet id
    planetID = sS.planetID;

    planetPos = new Vector3Ser(); // load planet pos

    planetPos.x = sS.PlanetPos.x; // load planet pos values 
    planetPos.y = sS.PlanetPos.y;
    planetPos.z = sS.PlanetPos.z;

    noiseLayerEnabled = new bool[sS.noiseLayers.Length]; // initalize these values
    nLFirstLayerAsMask = new bool[sS.noiseLayers.Length];
    noiseLayerNoiseSettings = new NoiseSettings[sS.noiseLayers.Length];

    for (int i = 0; i < sS.noiseLayers.Length; i++) // loop through all values in sS.noiselayers
    {
        noiseLayerEnabled[i] = sS.noiseLayers[i].enabled;
        nLFirstLayerAsMask[i] = sS.noiseLayers[i].useFirstLayerAsAMask;
        noiseLayerNoiseSettings[i] = sS.noiseLayers[i].noiseSettings;
    }
    indentifier = cS.indentifier;

}

}

script snipits used for saving

if (SaveSystem.SaveExists(universeKey))//check if it exists
    {
        universeSettings = SaveSystem.Load<UniverseSettings>(universeKey); // if it does load it
    } else
    {
        universeSettings = new UniverseSettings(); // otherwise make a new instance
    }

------------

string key = "/GeneratedScenes/" + SceneManager.GetActiveScene().name + "/" + "PlanetData_" + i + ".gameDat"; // Save location
        planetData = new PlanetData(BarrenShapePrefab, BarrenColourPrefab);
        if (SaveSystem.SaveExists(key)) //check if it exists
        {
            planetData = SaveSystem.Load<PlanetData>(key); // if it does load it
        }

if (!SaveSystem.SaveExists(key)) // otherwise make a new instance
        {
            SaveSystem.Save(planetData, key);
        }

        if (universeSettings.planetNum != numOfPlanets) // check if the amount of planets is saved (other bits of code will set the num of planets to this value if loaded)
        {
            string universeKey = "/GeneratedScenes/" + SceneManager.GetActiveScene().name + "/" + "UniverseData" + ".gameDat";
            universeSettings.planetNum = numOfPlanets; // set value
            SaveSystem.Save(universeSettings, universeKey); // save values
        }
0 Answers
Related