Webplayer deserialization fails

Hi there,

Usually i serialize my savegames to a file and this works yust fine and is super convenient, i just put my class [system.Serializable] attribute and can save it.

So now i need to deploy to Webplayer and i can’t save a file, so i thought of encoding my serialized file to Base64 and save it to playerprefs. This works fine in Editor and Standalone, and saving even works in Webplayer, BUT when i try to deserialize my string/savegame it does not work and i get this error in Webplayer log:

SaveLoad.LoadFileFromPP(): Failed autosave (Reason: System.FieldAccessException: Attempt to access a private/protected field failed.

Any Ideas on how to fix this? I really want to avoid switching all my Savegame stuff to some json serialisation or whatever…

this are the relevant code parts:

Saving (Works, no error in Webplayer):

		public static void SaveFileToPlayerprefs(string filename, object obj){
			MemoryStream memoryStream = new MemoryStream();
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			binaryFormatter.Serialize(memoryStream, obj);
			string str = System.Convert.ToBase64String(memoryStream.ToArray ());
			PlayerPrefs.SetString ( filename, str);
		}

Loading (this does work in Editor but not in Webplayer, with “SaveGame” beeing my custom class which holds all the serialized classes which need to be saved):

public static SaveGame LoadFileFromPlayerPrefs (string filename)
			{
				try {
				BinaryFormatter binaryFormatter = new BinaryFormatter();
				string tmp = PlayerPrefs.GetString (filename, string.Empty);
				if (tmp == string.Empty )
				return null;
				
				MemoryStream memoryStream = new MemoryStream (System.Convert.FromBase64String (tmp));
				return binaryFormatter.Deserialize (memoryStream) as SaveGame;
				}
				catch(Exception e) {
					Debug.LogError("SaveLoad.LoadFileFromPP(): Failed " + filename + " (Reason: " + e.ToString() + ")");
					return null;
				} 
		
			}

Thanks for any advice/ideas!
Simon

Can you output the deserialized (loaded) save file from both the webplayer and the editor/standalone player and determine if there is anything different about the two?

Unfortunately i can't, because i can't save no File in the Webplayer - or did i miss something about this? I'll try to build a simple demo-scene today, this might be easier to debug than in the actual game.

So i am gonna expand my question a little bit - is there any other kind of serialization, which is somehow "easy" to implement, meaning that i do not want to parse each variable on its own from a whatever fileformat savegame-string... (xml or Json or...?). I basically need to save a string to Playerprefs containing everything serializable in my "savegame" class. Thanks!

That's a lot of serialization input, thanks to you! I solved my problem (see answer below) with my serialization to Base64 trick, so i'm gonna stick to this solution.

1 Answer

1

As I had to find out the hard way, there are several cases where the BinaryFormatter fails to deserialize data (Webplayer only) with the mentioned “Attempt to access private field” message. The works fine in the editor/standalone but doesn’t work in the webplayer.

From my documentation on this issue the following classes don’t work and have to be replaced for the structure to become serializable:

  • Dictionary(TKey, TValue)
  • LinkedList(T)
  • HashSet(T)
  • List(List(T)) → A really sneaky bastard it deserializes but the data is wrong (I submitted a bug report to unity for this one, at least it should throw the same internal error).

Sorry for the ( and ) but I don’t know how to post < verbatim.

On the other hand normal List(T) work fine.

After you removed all of those I suggest commenting out things one by one until it doesn’t fail anymore.

Good to know.

Thanks a lot, found the problem - it was a DateTime in one of my serialized classes. I'm really happy that i do not need to rework all my saving code for webplayer, this was really helpful!

Are these container classes really broken, or is this one of those that can be worked around using a SerializationBinder (as hinted at in [this thread][1])? [1]: http://forum.unity3d.com/threads/unity-binaryformatter-deserialization-problem.16281/