Theoeidis Productions
Theoeidis Productions

Reputation: 13

How do I keep score between scenes in Unity dynamically?

I have a UI bug that I can not figure out. I wish to be able to carry my score over into each scene, while also having each scene independent of one another. If the player chooses to start the game in level 6 he should be able to do so with a clean scoreboard, same as starting at level 1. The score should proceed unitl to transfer until the player dies at which point the score should be set back to 0. To do this I've prefabbed my scoreboard and dropped it into every scene using the singleton pattern to make sure that there are no duplicate scoreboards in the scene. While trying to access my score text UI of type Text using UnityEngine.UI I receive a null reference error when the class is called after loading a new scene. Here are the C# classes defining the methods used in order to implement the functionality and screes snippets of my hierarchy in Unity 2019.4.1f1. I'm also attaching a short youtube video to show you that the score does work in the first scene, however it does not work in any other scene after. I do know that I'm destroying the Text UI at the beginning of every scene if there are multiple. What I do not understand is why the Text UI nested under the Scoreboard Canvas is not finding it's reference on Awake() for every instance created and why it's being called null. I truly appreciate anyone help!

Here are the screen snippets and videos in this order:

  1. Youtube video of bug
  2. Hierarchy of Scoreboard Canvas
  3. Hierarchy of Score Text
  4. Scoreboard singleton class (Attached to Scoreboard Canvas)/ ScoreText class (Attached to ScoreText UI)
  5. Implementation of classes used to add score upon completion of level in CollisionHandler class

UI Bug Video

Hierarchy of Scoreboard Canvas

Hierarchy of ScoreText

Scoreboard Classes

CollisionHandler class used for implementation

If these don't help, here is the github link to see the project code:

Github Project Files

Upvotes: 1

Views: 1954

Answers (2)

Weedosaurus
Weedosaurus

Reputation: 164

As for why it is not working, I'm not really sure. But I can tell you some ways around it: You could try to make a public static instance of your ScoreText inside the script of ScoreText.

public static ScoreText _instance;
public static ScoreText instance { get { return _instance; } }
private int score;
private Text scoreText;

    private void Awake()
    {
        if (_instance != null && _instance != this)
        {
            Destroy(this.gameObject);
        }
        else
        {
            _instance = this;
        }
    }

    void Start()
    {
        score = 0;
        scoreText.text = score.ToString();
    }

And access its functions with:

ScoreText.instance.AddToScore();

It would be cleaner and easier to use, in my opinion. If you would like to simplify a bit more, you could update scoreText in the update function as well. But since you only add points upon landing in those green zones, your way works fine as well. Hope I could help.

Upvotes: 0

Molly J
Molly J

Reputation: 519

Store your score in a monobehavior that calls DontDestroyOnLoad(this.gameObject);

This will preserve that object between scene changes. https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html

Upvotes: 1

Related Questions