An ideal way to store variables between scenes is through a singleton manager class. By creating a class to store persistent data, and setting that class to
DoNotDestroyOnLoad(), you can ensure it is immediately accessible and persists between scenes.
Another option you have is to use the
PlayerPrefs is designed to allow you to save data between play sessions, but it will still serve as a means to save data between scenes.
Using a singleton class and
The following script creates a persistent singleton class. A singleton class is a class that is designed to only run a single instance at the same time. By providing such functionality, we can safely create a static self-reference, to access the class from anywhere. This means that you can directly access the class with
DataManager.instance, including any public variables inside the class.
/// <summary>Manages data for persistance between levels.</summary>
public class DataManager : MonoBehaviour
/// <summary>Static reference to the instance of our DataManager</summary>
public static DataManager instance;
/// <summary>The player's current score.</summary>
public int score;
/// <summary>The player's remaining health.</summary>
public int health;
/// <summary>The player's remaining lives.</summary>
public int lives;
/// <summary>Awake is called when the script instance is being loaded.</summary>
// If the instance reference has not been set, yet,
if (instance == null)
// Set this instance as the instance reference.
instance = this;
else if(instance != this)
// If the instance reference has already been set, and this is not the
// the instance reference, destroy this game object.
// Do not destroy this object, when we load a new scene.
You can see the singleton in action, below. Note that as soon as I run the initial scene, the DataManager object moves from the scene-specific heading to the "DontDestroyOnLoad" heading, on the hierarchy view.
Unity has a built in class to manage basic persistent data called
PlayerPrefs. Any data committed to the
PlayerPrefs file will persist across game sessions, so naturally, it is capable of persisting data across scenes.
PlayerPrefs file can store variables of types
float. When we insert values into the
PlayerPrefs file, we provide an additional
string as the key. We use the same key to later retrieve our values from the
/// <summary>Manages data for persistance between play sessions.</summary>
public class SaveManager : MonoBehaviour
/// <summary>The player's name.</summary>
public string playerName = "";
/// <summary>The player's score.</summary>
public int playerScore = 0;
/// <summary>The player's health value.</summary>
public float playerHealth = 0f;
/// <summary>Static record of the key for saving and loading playerName.</summary>
private static string playerNameKey = "PLAYER_NAME";
/// <summary>Static record of the key for saving and loading playerScore.</summary>
private static string playerScoreKey = "PLAYER_SCORE";
/// <summary>Static record of the key for saving and loading playerHealth.</summary>
private static string playerHealthKey = "PLAYER_HEALTH";
/// <summary>Saves playerName, playerScore and
/// playerHealth to the PlayerPrefs file.</summary>
public void Save()
// Set the values to the PlayerPrefs file using their corresponding keys.
// Manually save the PlayerPrefs file to disk, in case we experience a crash
/// <summary>Saves playerName, playerScore and playerHealth
// from the PlayerPrefs file.</summary>
public void Load()
// If the PlayerPrefs file currently has a value registered to the playerNameKey,
// load playerName from the PlayerPrefs file.
playerName = PlayerPrefs.GetString(playerNameKey);
// If the PlayerPrefs file currently has a value registered to the playerScoreKey,
// load playerScore from the PlayerPrefs file.
playerScore = PlayerPrefs.GetInt(playerScoreKey);
// If the PlayerPrefs file currently has a value registered to the playerHealthKey,
// load playerHealth from the PlayerPrefs file.
playerHealth = PlayerPrefs.GetFloat(playerHealthKey);
/// <summary>Deletes all values from the PlayerPrefs file.</summary>
public void Delete()
// Delete all values from the PlayerPrefs file.
Note that I take additional precautions, when handling the
- I have saved each key as a
private static string. This allows me to guarantee I am always using the right key, and it means that if I have to change the key for any reason, I do not need to ensure I change all references to it.
- I save the
PlayerPrefs file to the disk after writing to it. This probably won't make a difference, if you do not implement data persistence across play sessions.
PlayerPrefs will save to the disk during a normal application close, but it may not naturally call if your game crashes.
- I actually check that each key exists in the
PlayerPrefs, before I attempt to retrieve a value associated with it. This might seem like pointless double-checking, but it is a good practice to have.
- I have a
Delete method that immediately wipes the
PlayerPrefs file. If you do not intend to include data persistence across play sessions, you might consider calling this method on
Awake. By clearing the
PlayerPrefs file at the start of each game, you ensure that any data that did persist from the previous session is not mistakenly handled as data from the current session.
You can see
PlayerPrefs in action, below. Note that when I click "Save Data", I am directly calling the
Save method, and when I click "Load Data", I am directly calling the
Load method. Your own implementation will likely vary, but it demonstrates the basics.
As a final note, I should point out that you can expand upon the basic
PlayerPrefs, to store more useful types. JPTheK9 provides a good answer to a similar question, in which they provide a script for serialising arrays into string form, to be stored in a
PlayerPrefs file. They also point us to the Unify Community Wiki, where a user has uploaded a more expansive
PlayerPrefsX script to allow support for a greater variety of types, such as vectors and arrays.