Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Is there serialization outside of Unity.

Discussion in 'Scripting' started by ReoCyan, Nov 19, 2023.

  1. ReoCyan

    ReoCyan

    Joined:
    Sep 25, 2023
    Posts:
    34
    I am taking a look at other C# things and as a heads up, I want to know if serialization is a unity feature or a part of C#.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,304
    Serialisation is just a programming/computer thing in general. A google search could've told you this.
     
  3. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,263
    The specific serialization system that is used in the editor for saving and loading scenes and prefabs is specific to Unity.
    [SerializeField] is a Unity-specific attribute that only works in Unity.
    JsonUtility uses this Unity-specific serialization system internally.

    JSON, Binary and YAML, and serialization in general, are concepts that exist outside of Unity.
    Unity's serialization system is really fast, but has its limitations, so sometimes people use alternative serialization frameworks like Json.NET.
     
    Last edited: Nov 19, 2023
    Ryiah, Bunny83 and ReoCyan like this.
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,078
    Unity has a Serialization package that unfortunately still few know about. It handles binary and json serialization.
     
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,847
    Just as some general clarification.

    Serialization is simply the process of converting complex structured data, usually from a representation in memory, to a series of simple symbols. Such a series is usually a text string or a binary string of data. Almost all storage media or network system only store / transmit such series of data.

    Serialization is an essential part of any digital system. Even though most wouldn't call a "text file" being "serialized" but technically it also applies. A text file consists of "lines" and some other structural features which give the text it's shape. However stored on disk a text file is just a single long stream of data. There are simply special control characters that are interpreted / deserialized as a line break, space or tab. So a file like

    Code (CSharp):
    1. ABC
    2. DEF
    3. GHI
    4.  
    5. Last
    would be stored as a single string that looks like this:

    Code (CSharp):
    1. ABC\r\nDEF\r\n\r\nGHI\r\n\r\nLast
    Though the
    "\r"
    is already not really correct as the carriage return character is just a single character. However it can not be printed as systems which show text would interpret it as, well a carriage return and start over with the next line. So it usually make more sense to show the actual bytes stored. We usually use hexa-decimal notation. So every byte is represented by two characters our of a pool of 16 characters (0123456789ABCDEF):

    Code (CSharp):
    1. 41 42 43 0D 0A 44 45 46 0D 0A 47 48 49 0D 0A 0D 0A 4C 5E 73 74
    2. A  B  C \r \n  D  E  F \r \n  G  H  I \r \n \r \n  L  a  s  t
    3.  
    JSON for example (the JavaScript Object Notation) is a text based serialization format for objects and is essentially a subset of the javascript language (well the name kinda implies that :) ). Since that format is very simple and can usually be adapted easily to any language it is quite versatile. So when you have a bunch of objects in memory, when you serialize them to json, you end up with a single stream of data. As already mentioned, such a stream of data can be stored in memory, on disk or send over a network connection.

    Of course when there is serialization there's also deserialization at some point which of course does the opposite. So it takes that stream of data as input and recreates the original structured data. In the case of JSON the objects it represents would be recreated or at least the stored data is applied to already existing objects.

    Serialization could mean a lot of different things but ultimatively it's the process of creating a simple stream of data out of a more complex object. Note that serialization does not necessarily recreate every aspect of an object. That's up to the serializer / deserializer. For example imagine an ordinary class like this:

    Code (CSharp):
    1. public class Person
    2. {
    3.     public string name;
    4.     public int age;
    5.     public Person father;
    6.     public Person mother;
    7.    
    8.     public string Serialize()
    9.     {
    10.         return name +","+ age.ToString();
    11.     }
    12.    
    13.     public static Person Deserialize(string aData)
    14.     {
    15.         string[] arr = aData.Split(',');
    16.         Person p = new Person();
    17.         p.name = arr[0];
    18.         p.age = int.Parse(arr[1]);
    19.         return p;
    20.     }
    21. }
    As you can see here, when we call the Serialize method we get a string back that may look something like
    Code (CSharp):
    1. "Bunny83,39"
    The class also has Person references to the father and mother of that person, however that information is not serialized. So when we use the Deserialize method we get back a Person object with the correct name and age, but the two reference would be null.

    Those are common serialization challenges how to deal with references to other objects that may exist separate from the object you want to serialize. So when you recreate the objects how do you tell the system which of the existing objects you want to reference. Unity's AssetDatabase serves this purpose for "assets". Each imported asset in Unity gets a GUID (an AssetID) that is unique. So the deserialization system can use this ID to look up the actual object in the database and recreate the reference.

    Most generic serialization systems use a feature of the C# language / .NET framework which is called "reflection" which allows code to inspect arbitrary objects to get information about their fields, methods and properties. Each serialization system usually has it's own rules what information it serializes and what it ignores. Most would only serialize types which have the System.Serialize attribute attached. Unity's serialization system also has this requirement, at least for ordinary C# classes. MonoBehaviour or ScriptableObject derived classes are specially treated anyways since they have a counterpart on the C++ engine core. Unity by default only serializes public fields or non-public fields that are marked with their SerializeField attribute. Fields are only serialized when the type of the field is of a supported type, otherwise they are ignored.

    I probably could write another ten pages trying to dive deep into all the details, but that would be a waste of time as there are many articles on the web which provide way more focused information on a particular aspect. Certain things have to be learned in small pieces through experience. For many people a PC is this kinda magical thing. Though the more you dive into the innerworkings, the more clear certain aspects get. After all everything in a PC is binary and simple logic.
     
    spiney199, CodeSmile and SisusCo like this.
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,491