Unity Serialization Part 1: How it works and examples

This post is part of a series about Unity serialization.  On this series of articles we will discuss a topic that is extremely  important to Unity3D development: serialization. This subject may be a bit cloudy for beginners, but understanding it not only helps to figure out how the Unity engine works, but it can also become really handy during a game development process and assist you to build better solutions. We will concentrate our study on the following subjects:

  • What is it? (Part 1)
  • How Unity does (Part 1)
  • Examples (Part 1)
  • Defining a Serializable Type (Part 2)
  • Problems with Serialization (Part 2)
  • Scriptable Objects (Part 3)

Fell free to navigate through the sections if you are comfortable with the previous concepts.

What is it?

Among other definitions, serialization is the process of converting the state an object to a set of bytes in order to store (or transmit) the object into memory, a database or a file. In another words: it’s how you can save an object to restore its state for later use.

Let’s say you have a Vector3 and you need to store it for future use. Which fields would you save into a file to restore its state? X, Y and Z, that’s easy! Apply this rule for any object and if you serialize all the (important) data, you can reload the object exactly how it was before. We name the process of storing the state of the object as “serialization” and the reverse process of building an object out of a file “deserialization”.

As we already read, this process is really useful to store and transmit data, so think about this: you have an online store deployed on your server, probably running a database manager application aside. Eventually, we need to store the data from memory into the disk (primary storage is volatile) and we do it by serializing our objects into database tables (which basically are files). The same process happens with every application that needs to store data into a disk, and computer games (and engines) are not an exception.

How Unity Does

Unity, as a Game Engine, needs to load a lot of stuff (scripts, prefabs, scenes) from the disk into the memory within application data. Maybe more important than that, Unity needs to move data between the native C++ side of the engine and the managed C# side. Even though we may think this task is strict to loading and storing assets processes, the serialization is used in many more situations than we think (like inspector window, reloading of editor code and instantiation among other scenarios). You can learn a bit more about Unity Serialization on their own blog. I’d risk to say it’s a mandatory read for developers.

The UnityEngine.Object class (which is serializable) provides us with the serialization resource in Unity: any other class than inherits from it – that includes MonoBehaviour, ScriptableObject (more on this later on the series), Shader, Sprite and basically everything in Unity – can also be serialized. Most of its uses are invisible and don’t matter when developing a game, except for a major use: scripting. When you create scripts, you need to keep on mind which fields you want to serialize, and, to do so, your field must:

  • Be public, or have [SerializeField] attribute
  • Not be static
  • Not be const
  • Not be readonly
  • The fieldtype needs to be of a type that we can serialize.

Which fieldtypes can we serialize? According to Unity’s documentation:

  • Custom non abstract classes with [Serializable] attribute.
  • Custom structs with [Serializable] attribute. (New in Unity 4.5)
  • References to objects that derive from UntiyEngine.Object
  • Primitive data types (int,float,double,bool,string,etc)
  • Array of a fieldtype we can serialize
  • List of a fieldtype we can serialize

A really common data structure isn’t serializable: Dictionaries, even if you declare them as public, and [SerializeField] atribute. So keep that in mind when developing a game.

Ok, this is a lot of information, so let’s break it to a straightforward code example:

Examples

Let’s take the following code (MyBehaviour.cs) as an example:

using UnityEngine;

public class MyBehaviour : MonoBehaviour
{
  [SerializeFieldprivate int x = 3;
  [SerializeFieldprivate float y = 5.6f;
  public float pi = 3.1415f;
  private int mySecret = 42;
  public static int myStatic = 10;
  public const int myConst = 22;
  public readonly int myReadOnly = 99;
  public int MyProperty { get { return 100; } }
}

The only fields that are serialized are “x”, “y” and “pi” because they are not static, const, readonly, a property or private with no [SerializeField] attribute. One way to show this is by taking a look at the script’s inspector, which only shows us serialized fields (that can come handy):

Screen Shot 2015-04-08 at 10.48.08 PM

But there is a better way to show that the other fields were not serialized: by cloning the object. Remember I told you that the Instantiate method uses the Unity serialization process? So let’s test it by adding the following method to our script:

private void Start()
{
  Debug.Log("Pi:" + pi + ". MySecret:" + mySecret + ". MyStatic:" + myStatic);
}

private void Update()
{
  if (Input.GetMouseButtonDown(0))
  {
    pi = -4;
    mySecret = -11;
    myStatic = 13;
    GameObject.Instantiate(gameObject);
  }
}

This method should modify the current object and create another object in the scene when the mouse’s left button is pressed. A naive thought would be that since the second object is a clone of the first one, it should have the same value for “pi”, “mySecret” and any other field as the first object, right? Well, it does for “pi”, because it’s a public field (hence it’s serialized), but it doesn’t for “mySecret”: its value remains unchanged when the second Debug.Log() is executed:

screen-shot-2016-11-03-at-3-47-32-pm

The field “mySecret” can’t be serialized because it’s a private field with no [SerializeField] attribute (which is the only circumstance a private fields will be serialized*).

*: Private fields are serialized in some circumstances in the Unity Editor and that can lead us to some problems we will discuss later on the next article on the “Problems” session. (source)

Curiously, the value of “myStatic” changes in both objects, but does that mean static fields are serializable? The answer is no. Even though its behavior leads us to conclude that, remember that static fields belong to the class, and not to an instance of it. That said, if we, per example, create a new object and add a MyBehaviour script to it in play mode (Using “GameObject > Create Empty” in the menu), “myStatic” will have the same value as the other objects, although it isn’t a copy of any other object. However, note that the “pi” variable has its original value.

screen-shot-2016-11-03-at-3-51-03-pm

This proves what the Unity documentation tells us about how can we make a field of a serializable type be serialized. This works with most Unity objects, including MonoBehaviours, but what if I don’t want to define a MonoBehaviour and I still want to create a Serializable type? In other words, how can I define a Serializable type?

On the next article we will find out how to declare our own serializable types and how to treat problems that can come along with it.

Fell free to write me any suggestions, errors, complements or just to say hi on the comments section 🙂

Source:
Serialization in Unity by Lucas Meijer (mandatory read)
Unity Serialization Best Practices by Tim Cooper
ScriptableObject
Serialization (C# and Visual Basic)

How does Unity3D scripting work under the hood?

On the previous post we learnt how Unity exports to so many platforms. Now let’s talk about a subject that can sound unnecessary at first, but helped (at least me) a lot on the process of understanding how Unity works. We all know Unity3D is an engine, but how it really works? In this post we’ll learn about:

  • How Unity3D Engine is implemented
  • How we access the engine code
  • Wrappers
  • How to use your own Mono library inside Unity
  • Unity3D Engine vs Unity3D Editor

We’ve always been told that managed programming languages are slow compared to native code, even though some managed languages are reaching great performance. We know that Java and C# are great for web development, non-critical systems and mobile apps. But when it comes to high performance (a pit where realistic graphics always fall) we all know these guys can’t do a lot for us. Although the Unity game world is fulfilled with 2D or simple graphics games, it’s capable of delivering stunning and realistic worlds and scenes.

So we ask (at least I did) ourselves: how does Unity deliver such amazing graphics with a great performance, if all the coding is made with C#, Javascript or Boo, and runs on a virtual machine (Mono)? If these are managed languages, how does it do the job? Is it dark magic? Unfortunately not.

One more time, let’s do some researching. After consulting Google, we get to an answer. The Unity Engine itself, the core, is written using C\C++, which we know is a native language. All the graphics, sound, physics coding is mostly C++ (I can’t say how much exactly because I don’t have access to the source code). But the guys from Unity itself gave us some tips is an article about C\C++ code coverage. By now things start to make sense: Unity is written in C\C++ and that’s why it’s so fast, smooth and provides us with a good performance. It’s almost over when suddenly another question pops: So why (and how) do we program in C# if Unity runs native code under the hood?

Again, the answer lays in one single hero: Wrappers! Oh, you don’t know what a wrapper is? Let’s talk about it a bit.

So when you are coding in C\C++, it’s a common practice to create libraries with a couple of functions\classes you are using. When you do so, you choose which functions\classes you want to expose, and which you want to hide. The exposed ones will be accessible out of the library and the hidden ones are not, commonly used by other functions\classes inside it. You know, the famous exposing code problem. When you’re done, you often have a DLL file with your library inside, and you can use it as any regular library.

But if you never used wrappers, you probably used your libraries with the same language you wrote them. So here is where the wrappers do their magic. One of the wrappers uses (there are others) is giving us a layer that provides cross language interoperability. This means you can call a C\C++ code from a C#, Python or Perl programs, per example. If you never heard about wrappers and cross language use, this can be mind-blowing, but think about it: it’s all about moving data around. If you know how to handle the data between both sides, they can work in perfect harmony.

The first time I used it was in a Game Development class where our teacher gave us an assignment that consisted of compiling a C library into a DLL file, wrapping it with C# code, and import it into Unity. There are some tutorials online teaching how to do so and I think this one is really straightforward. If you are curious about, try it, it’s such a simple exercise but it can teach you a lot about how Unity works. It may sound really painful (and it can be) to wrap bigger libraries, but there are tools that help us to do such challenging job. The one we used was SWIG, it worked perfectly and it was all magic.

So what we just did? We created C code that is accessible from C# code. Do you get what we just did? Let’s call this C code “Unity Engine”, and let’s assume it has hundreds of functions to deal with graphics, sound, physics and particles. Now let’s create a library from it and then create a wrapper in C# that will access it. This way, any C# project that contains our library can access its content. This is the Unity Engine! The core is written using C\C++ and you code in C# taking advantage of the native code performance. The Unity Engine itself is a DLL in your installation folder, check it out. Also, you can add your own Mono libraries to your Unity project, the guys from Unity teach you how to play with it.

Let’s talk about one more thing: the difference between the Unity Engine and the Unity Editor. The Unity Engine is a huge library that provides us a lot of tools to run games. The Unity Editor (the gray interface, with the inspector, hierarchy, etc.) we use is another thing: it’s a user interface (UI) that helps us to build games, but it’s not necessary to run them. It’s literally just a friendly interface to help us using the Unity Engine. The editor runs some of its code from the Unity Engine, and some of its own. It is built mostly in C#, and can be expanded: you can create your own windows, inspectors, and crazy stuff like your own browser. Extending the editor IMO is one of the most powerful Unity’s features.

Summing up, the Unity Engine is a C\C++ set of libraries that help us to run games, and we access it using a wrapper, typically using C#. It’s a clever way to build games with great performance by taking advantage of the fast and easy development of C#. Finally, the Unity Editor is a user-friendly interface that helps us to build games using the Unity Engine.

Last but not least, the Unity Engine itself (native portion) runs in plenty of devices because it was compiled to all of those devices: check the Unity installation folder and you can see the dlls to every platform the engine exports to. So with this thought, we complete the circle of life circle of execution on a Unity game: the Unity Engine’s core was written in C\C++ and runs on every platform the engine targets. We can interact with that code through C# wrappers, which runs on the Mono virtual machine. Lastly, the Mono project by its nature (bringing C# to other platforms) gives us the environment to run C# applications on our devices.

That closes our discussion about how the Unity3D Engine works greatly on so many platforms with amazing performance and easy programming.

Important update (September, 2015): Unity’s IL2CPP technology is changing the way the engine’s scripting backend works, eliminating Mono’s VM and AOT compiler. Take a look at it!

How does Unity export to so many platforms?

So for my first article I picked a not so simple theme, but one that has been extremely intriguing to me lately. This week a friend, during a talk about game development and Unity3D, asked me: “How does Unity export to so many and different platforms?” I started to think and formulate my answer, struggled and I couldn’t really answer why. I never really thought about it. So I started doing some research about it.

So let’s start. Unity3D is probably the most famous Game Development Engine on the market. It’s user friendly (15 yo kids can use it after a few tutorials, trust me), it’s available for both Windows and MacOS X (a Linux port is on experimental phase)  and finally and the most important in this article: it can export to basically any existing device. I’m not kidding, check the list at their website:

  • iOS
  • Android
  • Windows Phone
  • BlackBerry
  • Windows
  • Windows Store Apps
  • Mac OS X
  • Linux
  • Their native Web Player
  • PS 3
  • Xbox 360
  • Wii U
  • PS 4
  • Xbox One
  • Tizen
  • SamsungTV
  • PS Vita
  • Gear VR
  • Oculus Rift

It’s a legit myriad of devices and environments. If you don’t know Unity3D and want to give a try, the free version lets you export to Mac OX, Linux, Windows, iOS, Android, BlackBerry, Web Player, SamsungTV, WebGL, Tizen and Windows Phone. It’s pretty awesome, try it! (unfortunately I’m not making money by advertising, I just truly think it’s awesome).

Update: As pointed by Jashan in the comments section, I focused only on scripting in this article, so I decided to write a bit about how Unity3D exports other features to so many platforms. As you will notice whilst reading the next paragraphs, although Unity Technologies does a great job with Unity3D, it relies on several companies to help them to bring some features into it. When a new platform is announced, the UT developers check if every single one of these features are supported by one of their partners, and if so, the time dedicated to support it is reduced drastically. Now let’s take a look at some of the main features.

Graphics
Let’s start with graphics. A few graphics API are supported by Unity: OpenGL, OpenGL ES, WebGL, Metal and DirectX, each of these APIs targeting a different platform. OpenGL is widely used, from MacOS X and some iOS devices, to Linux and even Windows. OpenGL ES is compatible with mobile devices, mostly Android and some iOS. WebGL is the new promise on browser-based graphic application and games, eliminating the need of plugins like Flash and Unity web player. Metal is Apple’s new graphics API, compatible with the most recent iOS devices and computers from the Californian company. Finally, DirectX is Microsoft’s own graphics API solution, compatible with Windows, Windows Phone and Xbox. So even though the folks from UT dedicate a lot of time for graphics, most of the time is devoted to integrate these tools to the engine, and not to write their own API from scratch.

Physics
When it comes to physics, Unity trusts solely in one tool: Nvidia’s PhysX, which supports every single platform Unity builds to. It is, hands down, one of the best physics engines in the market, and it’s been trustful and efficient since the first version of the game engine, when PhysX was called Novodex and didn’t belong to Nvidia yet. The main reason to have a single physics solution for all platforms is consistency: all collisions and movements must behave identically in every device you support, otherwise some platforms can be favored in game.

Lighting
Once again, Unity relies on externals tools to implement lighting, both baked and realtime. Before Unity 5, Autodesk’s Beast was used as a baked lighting tool, been replaced by Geomeric’s Enlighten, which is now used for both realtime GI and baked lighting on the new versions (5.x) of the engine.

Networking
In 2014, Unity Technologies announced UNET (Unity Networking), which is their own networking and multiplayer solution, made in house. In the past, some networking solutions were common, the most famous being Photon. The new tool consists of two parts: the Networking APIs (with high and low level APIs) and the paid Multiplayer services. Since this is a internal project, UT has to port the code to all supported platforms, differently from graphics, physics and lighting described above.

Finally: Scripting

STOP: If you are a developer, is really confident about concepts like managed and native code, execution environments and different platforms, this section is for you. If you are an 3D artist, 2D artist or you are just curious about how this works, I’m really sorry but you may consider stopping here and accepting an awful answer: it’s magic. Seriously, you may jump to the last two paragraphs of this section that summarizes it. If you are still curious, give it a try!


For those who don’t know, Unity lets us script using C# and Unityscript (eww), and without any conversion or specialized tool, export our game to any of the previously listed platforms. Simple like that. So here comes the question: HOW? I thought that just stopping and thinking about it I could come up with an answer, but even tough I had some knowledge about how Unity works under the hood, I couldn’t figure out why. So I asked my best friend in these times (Google) the question that titles this post. Let’s just say I didn’t have the best feedback ever, and later I found out why: I was asking the wrong questions.

The answer lays on the real star of this post: Mono. I knew Mono was really important to Unity, but it goes further than I thought. Let’s start with the beginning: what the hell is Mono? According to the official website, Mono is a “cross platform, open source .NET development framework”. That’s somehow confusing, so let’s go deep in the Mono history.

Right after Microsoft released the .NET framework in 2000 as a “new platform based on internet standards”, this guy called Miguel de Icaza of Xamarin really liked .NET but wanted to develop for Linux. Since Microsoft .NET didn’t support (and still doesn’t) Linux or other non-Windows platforms, he simply decided to create his own environment, the Mono open source project in 2001. So Mono is basically an open source project to “bring” the .NET Framework to other platforms including its own C# compiler and CLR (Common Language Runtime). Historically, Mono was way behind .NET when it comes to features in the beginning. Today, not only it implements most of the .NET tools, but some extra ones. So summing up, Mono is an open source, C/C++ written implementation of the .NET development framework that today is available to a whole bunch of platforms (do you see a pattern here?).

So now let’s stop talking about Mono and give our friend Unity some attention again. So how we program our scripts in Unity? Using C# or Unityscript. So there comes the questions: if we program using C#, how can an Unity game run on so many platforms? Doesn’t Android use Java and iOS use objetive-C instead of C#? Does Unity compile every single game to each of the platforms native code? So many questions.

Let’s start with the last question. No, Unity doesn’t compile every single game to each of the platforms native code. That’s just insanity. Doesn’t Android use Java? Not only. You can still develop using native code (C/C++). But no one wants do do that, right? Wrong, that’s exactly what Mono does.

Now let’s go to the main question: how does my Android device runs a game that was written in C# but there’s no runtime environment that runs C# in it? Well, Mono runs it. But hey, I didn’t install Mono on my device. So basically the question is: how does Mono “get into” my device? With each game made in Unity (and every application developed using Mono) goes a Mono runtime environment. Are you crazy? No, and I can’t prove it right now, but here’s what Xamarin (remember them?) claim on their “How it works” page, and makes perfect sense:

Write your app in C# and call any native platform APIs directly from C#. The Xamarin compiler bundles the .NET runtime and outputs a native ARM executable, packaged as an iOS or Android app.

This brings other question: a Mono developed app attaches the whole framework to itself? The answer can be found in the same website: unused classes in the framework are stripped during linking. So the only portions of the framework that are bundled and put into your app are the ones you use. If you want to read more about how it works on the Xamarin products, visit the Developer Center.

So this is it boys and girls. Mono is the savior here. He provides the .NET Framework to Unity Games. This is why you can code using C# and run the game at so many platforms. I think this is it for my first post here. I hope I can keep the blog updated with more thoughts that have been concerning me. If you like, if you don’t, if there’s an error or even if you think this is total BS, please leave a comment.

Important update (September, 2015): Unity’s IL2CPP technology is changing the way the engine’s scripting backend works, eliminating Mono’s VM and AOT compiler. Take a look at it!

What to read next? I wrote a new post about how Unity3D works under the hood and how our code interacts with the engine code here.