I think it's the fifth or sixth times I answered that question only. Frankly, it's a rather good question.

I have a custom set of data that I use in my video game. This data is not attached to a level, a game object or a prefab. It must work on any deployable platform. What should I do?

 

An experienced C# coder would point towards the different .NET library that allows you to save object in a variety of formats, such as XML, Binary, JSon and who know how many others if you start counting open source libraries.

However, depending on which platform you deploy, you may not have full access to .NET, and your open source library may not be compatible with your platform of choice. For example, WebPlayer is not kind with third party dll.

Finally, you'll need to load that data! It's about at that point that you'll find out that System.IO is not accessible from almost all useful platform. (iOS, Android, WebPlayer, 360, PS3 and so on). You can only rely on System.IO if you deploy on Windows, Mac or Linux. (With some restriction on the last two)

So you're kinda stuck! You can save your data, but retrieving it becomes a problem. On top, serialization and deserialization can be annoyingly broken when it starts to collide with Unity's own object initialization.

Luckily, Unity has built-in system that allows to do all that, easily, with a minimum of code. The only downside is, you'll have to use Unity's own file system, which can be a bit rigid sometimes.

First, you'll go read this: http://docs.unity3d.com/Documentation/ScriptReference/AssetDatabase.CreateAsset.html

Basically, it's the function you will use to save native Unity .asset files. The rules of serialization is exactly the same as serialization in a MonoBehaviour. The only difference is, you'll derive from ScriptableObject.

Once properly saved, you'll put your newly created files in the Resources folder. Full blown directory management is often blocked and impossible to use on closed deviced like mobile phones. To counter that situation, Unity build a kind of "Big File" using the content of the Resources folder. A "Big File" is often used in database or in video game. It's a file that contains other files, like the .unitypackage files. It has its own built-in directory system so it doesn't need to rely on the device own path system. Be careful, Unity does not check for any kind of dependency. Everything you put in that folder will be packaged with your game! Don't put stuff in there that you don't need.

Second, you'll read this: http://docs.unity3d.com/Documentation/ScriptReference/Resources.Load.html

It's the method you'll use to load, at runtime, the files from that "Big File". You may note that everything pass by Unity's .asset files. Unity does not offer alternative format out of the box. Frankly, they don't really need and neither should you.

If for some strange reason you would like your file to be readable and editable in a text editor, the Pro version of Unity allows to save its file in a text readable format.

 

Quick recap on Unity's serialization rules;

  • Public fields are always serializable, unless flagged with the "NonSerializable" attribute.
  • Private fields are never serializaded, unless flagged with the "SerializeField" attribute.
  • Dictionaries, Hashtables or any other kind of hash collection is non-serializable.
  • The serialization entry points are: ScriptableObject, MonoBehaviour.
  • Objects deriving from System.Object are serializable if the class is tagged with the "Serializable" attribute.
  • However, objects deriving from System.Object are not polymorphic. They are always deserialized into the type of the field holding them.

You can read more about it here: http://blogs.unity3d.com/2012/10/25/unity-serialization/

 

In the end, it means you can have an unlimited number of nested structure serializaded without having to do anything. However, you got to be careful about the common Unity's pitfall;

  • You cannot save a ScriptableObject in a prefab. Only GameObject and its components go in there.
  • ScriptableObject exist in a .asset or a level. However, they are not too friendly to duplication when they have cross-references.
  • The non-polymorphic properties of standard object in a .asset means you have to be extra careful when designing your hierarchy.
  • List/Array works like a normal fields, in which they are non-polymorphic when holding System.Object derived objects.

There you go, you can save and load the universe!

Write comment (1 Comment)