How to save game progress using Serialization in Unity

Saving and loading game sessions are a must for large games. You can use Playerprefs If you need to save some simple variables of your game and retrieve it. Playerprefs are not suitable to save large amounts of data. This is where serialization comes in. To understand how serialization works, take a look at the graphics below.

serialization data flow

Now that you know what serialization means, now it’s time to know the rules.

Serialization rules

  1. You will need a class that does not inherit from monobehaviour.
  2. All variables must be declared as public.
  3. Only primitive data types, array of primitive data types, Enum, List and some built in Unity functions can be serialized. (Full list of serializable data types). If you are using a binary formatter then you can use only int, float, string, array and Boolean.
  4. The class should not be abstract, static or generic.

Example of a Serializable class

[Serializable]
public class example
{
   public int t1;
   public float t2;
   public bool t3;
   public int[] t4;
   public string t5;
}

Steps to save your game

Create a class with all the required variables that follow the serialization rules.

Free Unity asset banner

To keep things simple for the purpose of this tutorial, let’s save the health of the player and the game level string.

[System.Serializable]
public class save_data
{
    public float player_health;
    public string level_name;
}

Assign the values to this class from your other scripts. For example, the player’s health needs to be assigned from the player script and the level details may be in the level manager.

To assign the values to this class, you need to create an instance of this class in your other script as shown in the code snippet below.

using UnityEngine;

public class player_script : MonoBehaviour
{
    float health=100;
    bool game_saving=false;
    save_data sav=new save_data();

    // Update is called once per frame
    void Update()
    {

        if(game_saving)
        {
           sav.player_health=health;

        }
        
    }
}

The above code uses a Boolean to check if the player is trying to save the game. You can also create a new function to assign the data to your save class.

The next step is to serialize the class and save it in a file. In this tutorial we will use a binary formatter.

Saving and loading file using Binary formatter

You need to use a binary formatter to do that and in order to use a binary formatter you need to add “using System.IO” and “using System.Runtime.Serialization.Formatters.Binary;” to your script.

Here is a sample save function

using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class save_script
{
    
    save_data sav=new save_data();//this is the instance of the serializable class
    string file_path=Application.persistentDataPath + "/gamedata.mine";//path of your file
    FileStream my_stream;//data stream connection to file

  
    void save_game()
    {
        BinaryFormatter file_converter=new BinaryFormatter();        
        if(File.Exists(file_path))
        {
            my_stream=new FileStream(file_path,FileMode.Append);
            file_converter.Serialize(my_stream,sav);
            my_stream.Close();
        }
        else
        {
            my_stream=new FileStream(file_path,FileMode.CreateNew);
            file_converter.Serialize(my_stream,sav);
            my_stream.Close();
        }

        
    }
}

To load the data from file to Unity you just need to deserialize it.

The load data function should return a data type of the class used to serialize. Here is the sample function to deserialize the data

using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class Save_script
{
    save_data sav=new save_data();

    string file_path=Application.persistentDataPath + "/gamedata.mine";
    FileStream my_stream;


    save_data load_data()
    {
        BinaryFormatter file_converter=new BinaryFormatter();        
        if(File.Exists(file_path))
        {
            my_stream=new FileStream(file_path,FileMode.Open);
            save_data lod=file_converter.Deserialize(my_stream)as save_data;
            my_stream.Close();
            return lod;
        }
        else
        {
            Debug.Log("File doesn't exist");
            return null;
        }

        
    }
}

In our next tutorial, we will see how to serialize and save data in Json format.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.