I have created a bunch of scriptableobject assets which I am using to track equipment for a game. I have a list of these assets stored in a script which I am trying to serialize using binary formaters. However when I try to do so I get the below error. So it looks like that I could create a non scriptable object class and move all the data over before I serialize. But if I do then I lose the ability to create the assets in the editor. I am just looking for some guidance on what the best way to continue would be.
Error (when calling the saveGame() method)
SerializationException: Type UnityEngine.ScriptableObject in assembly UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null is not marked as serializable.
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
public class GameCore : MonoBehaviour
{
public static GameCore baseGame;
public List<GameItem> gameItemList; // the scriptable object in question
void Awake()
{
if( baseGame == null )
{
DontDestroyOnLoad( gameObject );
baseGame = this;
}
else if( baseGame != this )
{
Destroy( gameObject );
}
}
public void saveGame()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create( Application.persistentDataPath + "/inventroy.dat" );
bf.Serialize( file, gameItemList );
file.Close();
Debug.Log ("List Saved");
}
public void loadGame()
{
if( File.Exists( Application.persistentDataPath + "/inventroy.dat" ) )
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open( Application.persistentDataPath + "/inventroy.dat", FileMode.Open );
gameItemList = (List<GameItem>)bf.Deserialize(file);
file.Close();
Debug.Log( "Loaded List" );
}
}
}
using UnityEngine;
using System;
using System.Collections;
[Serializable]
public class GameItem : ScriptableObject
{
public string itemName;
public float itemWeight;
public string getInfo()
{
return itemName + " - " + itemWeight.ToString () + " lbs";
}
}
I just tried to add a wrapper but I got the same error
the wrapper class
using UnityEngine;
using System;
using System.Collections;
[Serializable]
public class GameItemWrapper
{
public GameItem wrappedItem;
public GameItemWrapper() {}
public GameItemWrapper( GameItem obj ) { wrappedItem = obj; }
}
the new save method
public void saveGame()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create( Application.persistentDataPath + "/inventroy.dat" );
List<GameItemWrapper> wrappedList = new List<GameItemWrapper>();
foreach( GameItem xItem in gameItemList )
{
wrappedList.Add( new GameItemWrapper(xItem) );
}
bf.Serialize( file, wrappedList );
file.Close();
Debug.Log ("List Saved");
}
You’re still attempting to serialize something that can’t be. You don’t need a wrapper as that just wraps around the SO before writing to disk and it, again, cannot be written to disk. Instead, create a SaveGameItem class that is serializable. Give it a copy constructor that reads in your SO. Then do something like:
foreach( GameItem xItem in gameItemList )
{
wrappedList.Add( new SaveGameItem(xItem) );
}
Can you explain why does this work?What Mike pointed out works. But I dont understand why it works. Anyone know any documentation on this?Im very confused,I need good detailed information
At first, OP tried to serialize a list of SO which he can not do.
He just creates a new class which holds the same values of the scriptable object he wants to save.
The constructor for this class takes the SO and just copy it’s values.
He can now mark the new class he made as serializeable and save or load it as he wish.
This is the right answer. There is so very much misinformation that is more easily found via Google. I just figured there must be a way to do this, and so I persisted in changing the search terms around until I found an answer I liked. I wish there was a way to mark this as “Googleable”.
SerializationException: Type UnityEngine.ScriptableObject in assembly UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null is not marked as serializable.
Make sure your SaveGameItem class doesn’t inherit from ScriptableObject or anything. It’s gotta be a simple, standalone, serializable class.
[System.Serializable]
public class SaveGameItem
{
public string name;
public float weight;
public SaveGameItem(GameItem a_Item)
{
name = a_Item.name;
weight = a_Item.weight;
}
}
Since its been necro’s, JsonUtility is a much friendlier way to serialize things. It takes advantage of Unity’s own serialization system, which means you get consistent behavior everywhere.