Seems every game development faces a problem: how to serialize and deserialize data? This question occurs in two main scenarios: saving/loading and network communication (how to send data to server or computer). In both cases you want to save some game data (items, players or perhaps game state or action) and restore this data later (might be on other server).
Let me take short overview of each of them.
+ Simple to use
+ Built-in
- Does not support data transferring
- Does not support complicated data types (as classes)
- Pure performance
+ Simple to use
+ Human-readable formats
+ Support complicated object serialization
+ Open standards that have a lot of realizations (cross-language support)
- Large serialized size
- Pure performance
+ Simple to use
+ Well performance (in comparison with previous approaches)
+ Support complicated object serialization
+ Small size of serialized data (in comparison with string serialization)
- No multi-language support
To my astonishment, there is pure support of these protocols in Unity. You can find some articles about using protobuf in Unity but mostly they use old-built release version of protobuf-net and it is frustrating. Also it is not as convenient as previously mentioned approaches.
About flatbuffers I have found one good article (this one) but the problem with using flatbuffers still stays on. For example Unity Editor does not support creating flatbuffers-files (*.fbs). You have to create them in other ways (for example from console or by Windows Explorer). Another inconvenience is that for compiling (translating from .fbs messages to C# or other language code) you have to run a console app (flatc) with a number of arguments. For example typical command to compile Message.fbs to Message.cs with selecting include directory is:
I have decided to use flatbuffers in my project because of these advantages:
+ Great performance
+ Small size of serialized data
+ Cross-language support
To make my life easier I have decided to develop a tool/plugin for Unity to facilitate using flatbuffers. Next part of this article contains detail overview of this tool (I called it UnityFbs). A few screenshots how it looks:
Most common solutions
What approaches does Unity suggest for that? I have found these variants:Let me take short overview of each of them.
PlayerPrefs
It is one of the most simple way to store data in Unity. It uses built-in system PlayerPrefs that allows to save data in system key-value storage. It has only three functions to store base types of data (int, float and string). PlayerPrefs is not about performance or data transferring. Pros and cons:+ Simple to use
+ Built-in
- Does not support data transferring
- Does not support complicated data types (as classes)
- Pure performance
String serialization (json, xml)
String serialization has an advantage over other methods: it can be easily read by human. So you can see how does your data serialize. Unity supports several helpers to work with these format (XMLSerializer is Microsoft's wrapper, but Unity supports it). You can combine JSON/XML with previous PlayerPrefs to store object (serialize your object and store it as string). But unfortunately these serializers have bad performance and serialized data has a large size. Pros and cons:+ Simple to use
+ Human-readable formats
+ Support complicated object serialization
+ Open standards that have a lot of realizations (cross-language support)
- Large serialized size
- Pure performance
Binary serialization
Using of binary serialization allows to avoid problems with performance and large size of serialized data. It is also easy to use (similar to json serializing). There is a class BinaryFormatter that helps to serialize data. But unfortunately it does not provide cross-language support. It means that you are limited to C# and if your game requires for a example a server you have to write a server on C#. If it is not a problem binary serialization is a good choice. Pros and cons:+ Simple to use
+ Well performance (in comparison with previous approaches)
+ Support complicated object serialization
+ Small size of serialized data (in comparison with string serialization)
- No multi-language support
Other ways...
Well... what if none of mentioned variants suits you. What can you do else? Google introduced their approaches to data exchange with messages. There are two protocols developed by Google: protobuf and flatbuffers. Flatbuffers is more later protocol and it has some advantages over protobuf. Both these protocols are much more efficient than previously mentioned approaches. You can find performance tests on this page.To my astonishment, there is pure support of these protocols in Unity. You can find some articles about using protobuf in Unity but mostly they use old-built release version of protobuf-net and it is frustrating. Also it is not as convenient as previously mentioned approaches.
About flatbuffers I have found one good article (this one) but the problem with using flatbuffers still stays on. For example Unity Editor does not support creating flatbuffers-files (*.fbs). You have to create them in other ways (for example from console or by Windows Explorer). Another inconvenience is that for compiling (translating from .fbs messages to C# or other language code) you have to run a console app (flatc) with a number of arguments. For example typical command to compile Message.fbs to Message.cs with selecting include directory is:
I have decided to use flatbuffers in my project because of these advantages:
+ Great performance
+ Small size of serialized data
+ Cross-language support
To make my life easier I have decided to develop a tool/plugin for Unity to facilitate using flatbuffers. Next part of this article contains detail overview of this tool (I called it UnityFbs). A few screenshots how it looks:
Comments
Post a Comment