- Home /
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 deter$$anonymous$$e 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!
How about this? I started to imagine something like Python's "pickle" which can turn a data structure into a string, but C# is not a dynamic language and I think you are already trying the next best thing.
The playerprefs docs suggest that the WebPlayer does in fact store files at the following locations.
WebPlayer On Web players, PlayerPrefs are stored in binary files in the following locations: $$anonymous$$ac OS X: ~LibraryPreferencesUnityWebPlayerPrefs Windows: %APPDATA%\Unity\WebPlayerPrefs There is one preference file per Web player URL and the file size is limited to 1 megabyte. If this limit is exceeded, SetInt, SetFloat and SetString will not store the value and throw a PlayerPrefsException.
Whats the apprehension with JSON? I've written a game recently that uses SimpleJSON to parse Scoreoid.com responses. It is also capable of generating JSON, though I didnt use that feature in my project.
One prevailing bit of wisdom I found on the internet were solutions like this:
StringWriter outStream = new StringWriter();
XmlSerializer s = new XmlSerializer(typeof(List<List<string>>));
s.Serialize(outStream, myObj);
properties.AfterProperties["myNoteField"] = outStream.ToString();
As you can see, this creates an X$$anonymous$$L string which is serialized. I would probably at this point use SimpleJSON, myself.
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.
Answer by billykater · Nov 28, 2013 at 10:23 PM
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.
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)?
Your answer
Follow this Question
Related Questions
Help with Binary serialization/de-serialization of List items and the WEBPLAYER 1 Answer
How to serialize/deserialize entities at runtime -1 Answers
Save data through xml Serialization on iOS 1 Answer
how can serialize a gameobject 1 Answer
SerializationException: Type UnityEngine.Vector3 is not marked as Serializable. 1 Answer