Saving Score Between Scenes - Help Please

Hello, in my 2D platformer players collect items, “data”, and the score is increased by one every time they pick one up.
I got this code from Coding in Flow’s “Collect and Count Items” tutorial for 2D platformers.

This is the code, basically when the player collides with the item, the number goes up and the UI is updated to reflect that. Any idea how to maintain the score instead of it resetting to 0 between scenes is greatly appreciated. Thanks

public class ItemCollector : MonoBehaviour
{
private int data = 0;
[SerializeField] private Text dataText;
[SerializeField] private AudioSource collectionSoundEffect;

private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Data"))
{
    collectionSoundEffect.Play();
    Destroy(collision.gameObject);
    data++;
    dataText.text = "DATA:" + data;
}
}

}

Two possible easy solutions:

ULTRA-simple static solution to a GameManager:

https://discussions.unity.com/t/855136/6

https://gist.github.com/kurtdekker/50faa0d78cd978375b2fe465d55b282b

OR for a more-complex “lives as a MonoBehaviour” solution…

Simple Singleton (UnitySingleton):

Some super-simple Singleton examples to take and modify:

Simple Unity3D Singleton (no predefined data):

https://gist.github.com/kurtdekker/775bb97614047072f7004d6fb9ccce30

Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

https://gist.github.com/kurtdekker/2f07be6f6a844cf82110fc42a774a625

These are pure-code solutions, do not put anything into any scene, just access it via .Instance!

If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

public void DestroyThyself()
{
   Destroy(gameObject);
   Instance = null;    // because destroy doesn't happen until end of frame
}

There are also lots of Youtube tutorials on the concepts involved in making a suitable GameManager, which obviously depends a lot on what your game might need.

1 Like

Thank you, I think I’m all set, I just need to know how to access the Game Manager via Instance? Is that something that goes in a script on a game object and how do you use instances in this case?

GameManager.Instance.DoSomethingGameMangery();

You can also use scriptable objects to pass data between scenes. The important thing to note is the data is not persistent in a live build when the user closes the game. It will persist data between scenes due to the nature of scriptable objects.

If you close the game and reload it the SO values will be their default values (whatever values are set in the inspector when you build).

However, to persist data between sessions (user closes game then relaunches later) you would need a proper load/save system to persist between sessions to populate the SO data.

  1. Pull data from load system and populate scriptable object data
  2. SO data can be persisted between scenes
  3. Save system pulls data from the SO before use quits game.
using UnityEngine;

[CreateAssetMenu(fileName = "Data", menuName = "SO/TestData", order = 1)]
public class TestDataSO : ScriptableObject
{
    public string someString;
    public int someNumber;
}
using UnityEngine;

public class UseScriptableObjectExample : MonoBehaviour
{
    public TestDataSO testDataSO;

    private void Start()
    {
        Debug.Log(testDataSO.someNumber);
    }

}
1 Like