Information Transfer

Overview

This section covers some ways information can be transferred in a unity project. Some examples include transferring information between game objects, scenes, and play sessions.

Transfer Information Between Game Objects

Example: We have 2 scripts (PlayerController and PlayerUI) on 2 different game objects. Both scripts call functions that require the player’s health. How can both of these game objects get access to the same player health variable?

Referencing the Other Game Object

We can have the PlayerController class store the player health variable. Then we have the PlayerUI class have a variable that references the PlayerController class and use that reference to get the player health from PlayerController.

Warning

This method can reduce the modularity of your game and make testing more difficult. In this example, since PlayerUI depends on a PlayerController existing in the scene, if you wanted to test the behavior of PlayerUI B in a new scene you must also add a PlayerController to the scene. This can become cumbersome when your game architecture has a web of references.

Using Scriptable Objects

We can have a scriptable object Health contain the player health variable. From this we create a PlayerHealth asset that we use to store the player’s health. Then we can give PlayerController and PlayerUI a reference to PlayerHealth thus giving both classes access to the player’s health.

For more on scriptable objects as data containers, see: Unite Austin 2017 - Game Architecture with Scriptable Objects

Transfer Information Between Scenes

Example: A player has 3 lives and he loses 1 life in scene #1. When we load scene #2, how can the game remember how many lives the player has?

Using A Static Class

A static class can persist between scene changes. This means any information stored within the static class will also persist between scene changes and can be accessed by scripts in the new scene.

Warning

Data in a static class can be accessed from anywhere. This can introduce bugs when multiple developers attempt to modify static variables. The project can end up having multiple classes reading and writing to static variables without taking into account each other’s logic. Additionally it hard to identify where changes to static variables are coming from when they can be accessed by anyone.

Using Scriptable Objects

A scriptable object can contain information and is stored as an asset in your project. This means that it persists through scene changes and you can give scripts references to the scriptable object to read and write information from it.

Important

If you reference the same scriptable object in multiple scenes and you plan on reading and writing data to that object, if you happen to jump from a scene that contains the object to a scene that does not, the object can be unloaded and the data contained within can be lost. To prevent this you can include the following line of code in the OnEnable function inside your scriptable object to make sure it persists between scene changes:

private void OnEnable()
{
    // This makes sure that this object persists between scene changes
    hideFlags = HideFlags.DontUnloadUnusedAsset;
}

Link to the thread from which I found this solution.

Warning

Changes you make to scriptable objects in play mode will persist while in the editor. If you are not careful you could accidentally build a game with scriptable objects containing values you did not want. For example, if you have a scriptable object tracking how many lives the player has and during your play testing that amount is set to 10 before you exit play mode, the scriptable object will now have that value set to 10. If you then build the game, when starting the game up the player will start with 10 lives. You can fix this issue any number of ways. For example you can have a game manager that makes sure to reset the lives to 3 at the start of each level.

Using DontDestroyOnLoad

By default, all game objects from the previous scene are destroyed when we open a new scene. If we call DontDestroyOnLoad() on a game object, that object will continue to exist into the next scene. This means that any information the game object has will be carried into the new scene. Objects in the new scene can then access that game object to retrieve the information.

Transfer Information Between Sessions

Example: A player has unlocked levels 1-3 in your game. The player then closes the game. When the player re-opens the game, how can the game remember the levels the player has unlocked?

Using JSON Serialization

Unity can convert unity objects into JSON text through JSON Serialization and save that text using File.WriteAllText() to a standard location at Application.persistentDataPath.

Warning

JSON Serialization does not support data types like Dictionary<>. For a comprehensive list of supported types, see JSON Serialization

Using Binary Serialization

In unity you can save data to custom binary files. These files are harder to read than json files and make them slightly more secure.

Scriptable Object Save System Example

Note

Some of the code in this example was lifted from Save SCRIPTABLE OBJECTS - Unity Tutorial

This save system is useful if your game stores its information inside scriptable objects. Scriptable objects can use this system to store their data in binary files. You can coordinate the saving of data throughout the game with a use of a central scriptable object that has references to all other scriptable objects that contain data. Additionally its supports multiple save files.

Implementation:

  • ISaveLoad.cs

    • An interface for scriptable objects that allows them to work within the save system.

    • The interface makes the scriptable object responsible for saving and loading its own data.

  • SaveSystemUtilities.cs

    • Utility functions that allow for the saving and loading of data to binary files.

    • Contains functions that help identify the saves that do and do not exist as well as functions to generate new save names if the need arises

  • SaveSystem.cs

    • A scriptable object you can use in game to coordinate saving and loading game data.

    • The save system contains reference to scriptable objects that implement the ISaveLoad inteface

Example

Click to download ScriptableObjectSaveSystemExample.unitypackage.