Serializable Class?

I’m trying to use BinaryFormatter to serialize some stuff. Initially I got an error in unity telling me my class wasn’t marked as serializable. So I went and put [System.Serializable] in front of it. But now it’s giving me another error and still says it’s not marked as serializable…

How can I solve this?

SerializationException: Type UnityEngine.ScriptableObject in assembly UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null is not marked as serializable.
System.Runtime.Serialization.FormatterServices.GetSerializableMembers (System.Type type, StreamingContext context) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization/FormatterServices.cs:101)
System.Runtime.Serialization.Formatters.Binary.CodeGenerator.GenerateMetadataTypeInternal (System.Type type, StreamingContext context) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs:78)
System.Runtime.Serialization.Formatters.Binary.CodeGenerator.GenerateMetadataType (System.Type type, StreamingContext context) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs:64)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.CreateMemberTypeMetadata (System.Type type) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:442)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.GetObjectData (System.Object obj, System.Runtime.Serialization.Formatters.Binary.TypeMetadata& metadata, System.Object& data) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:430)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObject (System.IO.BinaryWriter writer, Int64 id, System.Object obj) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:306)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectInstance (System.IO.BinaryWriter writer, System.Object obj, Boolean isValueObject) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:293)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteQueuedObjects (System.IO.BinaryWriter writer) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:271)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectGraph (System.IO.BinaryWriter writer, System.Object obj, System.Runtime.Remoting.Messaging.Header[] headers) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:256)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header[] headers) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:232)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:211)
Player.SaveArmies () (at Assets/Scripts/Player.cs:70)
setup.Awake () (at Assets/Scripts/setup.cs:37)

UnitySerializer is worth looking into. I don’t know off the top of my head if it handles serializableObjects specifically, but it does normal unity-objects so it may be capable.

Otherwise you’ll probably have to look into using Reflection. Essentially you’d have something like this:

foreach(var field in targetObject.GetFields()) {
SerializeSomehow(field.name, field.value);
}
You can check to be sure field.value is serializable before messing with it using some reflection stuff as well.

This STILL isn’t going to be good enough if you need to serialize Vector3 or other non-serializable Unity structs. If it turns out you need some things like that included in your copied object, I’m at a loss. I have some scripts that literally just copy a certain type of SerializedObject into a copy specifically because I couldn’t figure out how to handle those types. :frowning:

Edit: But if you just need to copy from one scripto to another it would look like this:

public void CopyScriptable(ScriptableObject source, ScriptableObject target) {
if ( typeof(source) != typeof(target) ) {
// error message
return;
}
foreach(var field in source.GetType().GetFields()) {
field.SetValue(target, field.Getvalue(source));
}
}