- Home /
Serializing a monobehaviour class to xml and some other related doubts
Hello everyone.
In order to save the data for my game, I've heard of the XmlSerializer class, which copies a whole class into an xml file and is able to retrieve any information from it. This seems to be just what I needed to save my games, but I was wondering...
Can the XmlSerializer (from the System.Xml dll) save a class inherited from monobehaviour? I know this classes are a little bit different (no constructor nor cannot be instanced using "new" keyword). I don't think that's going to make a difference, but I just wanted to make sure before implementing my code.
Also, I would like to know what does that XmlSerializer with the composed classes (A class inside an instance of a class. To make an example, I'm trying to save players, and each player has an object instance of a class called inventory, which holds multiple instances of the item class). How would react the XmlSerializer to that? I don't think it's going to save all my object as I need so Is there any way to do this?
I would also like to know, if it's possible to encrypt some way all those Xml files so I make sure the users won't be able to modify them (at least not as easily as editing the xml document themselves without decrypting). I'm not planning on stopping hackers from modifying game data, just want to make the data a little bit more complicated to get, so I make sure most of the users won't be able to modify it.
And lastly (sorry, I know that's a lot of asking for a single post), How can I refer to a path relative to the game's exectuable when trying to load an xml (or, actually, any other kind of) file? I supose there's actually a difference if I'm building my game or just playing it from the editor. I don't care about the editor as I only have to specify a path in my PC, but when I build my game I'll need to set a path relative to my project folder, so is there any builtin variable in unity with that information?
Thank you very much, I know I'm asking a lot of things, it's just some doubts I've been coming across these days and need to get resolved if I want to continue with my project.
Well, I've tried to serialize my class and there's many errors to fix, many of the unity builtin classes cannot be serialized (nor I need to). I think i just won't bother to use this class and write an script myself which saves the data I want. I'm still interested in my other questions though
Answer by Bunny83 · Jun 26, 2012 at 11:03 AM
As you have figured out, almost all Unity classes derived from UnityEngine.Object can't be serialized / deserialized. This has many issues. Most of these classes have a counterpart in native code, so it's difficult to restore all states of an instance. Components in addition can't live on their own. They always need to be attached to a GameObject. That's why it's constructor is private. Components can only be created with AddComponent which makes standard deserialization impossible.
I didn't used the standard serializer that often, but as far as i know they do serialize "child objects". But keep in mind, if they serialize such an aggregation, when two of your instances reference the same thing, for example a manager, the deserializer will create a seperate manager for each serialized instance. Most serializer can't handle this cases.
There are many ways to encrypt data in a way the "normal user" can't read / change it. One would be to use binary serialization and not xml. Xml is ment to be human readable. If you don't need / want it to be human readable, simply store your stuff in binary form. You can of course use xml if you want to and use any encrypting method you want. A simple xor with a constant value or a set of values should be enough for most users ;)
Your last question is tho most simple one ;) Juat take a look at Application.dataPath. Keep in mind that datapath points to the Assets folder in the editor and to the data folder in a standalone build. Files placed in the Assetsfolder aren't available in a build as seperate files. "Assets" in the sense of Unity are compressed and packed into their assetdatabase. Unity only ships assets with your build that are "used" in some way.
However you can of course copy datafiles into the data folder of your game after you created the build. Keep in mind that you have to do this every time you build your game.
See this question on that topic.
edit
Here are some related questions on loading / saving the game and other related posts:
http://answers.unity3d.com/questions/8480/how-to-scrip-a-saveload-game-option.html
http://unifycommunity.com/wiki/index.php?title=Save_and_Load_from_XML
http://forum.unity3d.com/threads/138678-Unity-Save-Game-Level-Serialization
Thank you very much ^^ that answers my question. As I said I'll have to program a custom script in order to save my player data, so I can fully control what gets saved and what doesn't.
As for the encrypting, I'm using xml as I want the data to be human readable during de developement, so I can check the data is being saved correctly, but I'll want it to be encrypted when I actually play the game. (Also, I want to be able to modify the saved data myself for testing purposes).
I'll check on encrypting methods as I didn't know much about them.
$$anonymous$$ost methods of saving state give you fine grained control over individual fields and properties - bear in $$anonymous$$d that storing transforms and the like can be tricky for instantiated prefabs. Unity Serializer - which is mentioned above does provide full control, but isn't human readable for the sake of size and performance. It does have an option to fully log detailed info to the console however for debugging.
Your answer
Follow this Question
Related Questions
Error while serializing Material with Texture (UnitySerializer) 0 Answers
Saving usermade creations in game 1 Answer
Saving serializable class list at runtime. 1 Answer
Serializer Script 3 Answers