Issue with PlayerPrefs not loading a value, as well as a bug...

My game uses PlayerPrefs to save and load values for the last played Score and Highscore variables (both integers). So far everything’s functional except for one thing: when the scene is changed, i.e. back to the main menu or to the options menu, then back to the main game scene, the game doesn’t count up the score the next time it is run; in other words, the score variable doesn’t count up until the player dies at least once and refreshes. Well, now that I’ve explained all of that, here’s all my related code to the issue:

The Death() method of my Player Movement script:

	void Death() {
		IsAlive = false;
		PlayerPrefs.SetInt("Score", Score.scoreValue);
		if (Score.scoreValue > PlayerPrefs.GetInt("Highscore")) {
			PlayerPrefs.SetInt("Highscore", Score.scoreValue);
		}
		Instantiate (DeathEffect, this.gameObject.transform.position, Quaternion.identity);
		GameOver gameOver = GameObject.Find("Main Camera").GetComponent<GameOver>();
		gameOver.DisplayGameOverGUI();
		gameOver.gameOverPanel.gameObject.SetActive(true);
		Score score = GameObject.Find("Main Camera").GetComponent<Score>();
		score.scoreText.gameObject.SetActive(false);
	}

Score.cs:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Score : MonoBehaviour {

	public static int scoreValue;
	public Text scoreText;

	void Start() {
		scoreValue = 0;
		InvokeRepeating("CountScore", 1, 0.5f);
	}

	void Update() {
		scoreText.text = "Score: " + scoreValue + "

Highscore: " + PlayerPrefs.GetInt(“Highscore”);
}

	public void CountScore() {
		if(Movement.IsAlive == true) {
			scoreValue++;
		}
	}
}

GameOver.cs:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections;

public class GameOver : MonoBehaviour {

	public Text gameOverText;
	public GameObject gameOverPanel;

	void Start() {
		gameOverPanel.gameObject.SetActive(false);
	}

	public void DisplayGameOverGUI() {
		if (!Movement.IsAlive) {
			if(PlayerPrefs.GetInt("Highscore")>=(PlayerPrefs.GetInt("Score"))) {
				gameOverText.text = "Score: " + Score.scoreValue + "

Highscore: " + PlayerPrefs.GetInt(“Highscore”) + "
You got " + (PlayerPrefs.GetInt(“Highscore”) - (PlayerPrefs.GetInt(“Score”))) + " lower than your highscore. Pretty close!";
}
if (PlayerPrefs.GetInt(“Score”) >= (PlayerPrefs.GetInt(“Highscore”))) {
gameOverText.text = “Score: " + Score.scoreValue + "
Highscore: " + PlayerPrefs.GetInt(“Highscore”) + "
You beat your highscore by " + (PlayerPrefs.GetInt(“Score”) - (PlayerPrefs.GetInt(“Highscore”))) + " points!”;
}
}
}

	public void PlayAgain() {
		SceneManager.LoadScene("Game");
		Movement.IsAlive = true;
		Score.scoreValue = 0;
	}

	public void QuitGame() {
		SceneManager.LoadScene("Menu");
		Score.scoreValue = 0;
	}
}

The Start() method of MenuGUI:

	void Start() {
		scoreText.text = "Latest Score: " + PlayerPrefs.GetInt("Score") + "

Highscore: " + PlayerPrefs.GetInt(“Highscore”);
}

Hopefully that helps illustrate and explain my situation… Thanks in advance :slight_smile:

You should only set or get PlayerPrefs values at key points during gameplay – usually at the start and end of the game – and load those values into “normal” variables for actual use. Accessing PlayerPrefs all the time will only lead to issues.

When changing scenes all objects and their data will be destroyed (unless you assign DontDestroyOnLoad)! So you probably want to save and load this data right before and after changing scenes. or just avoid changing scenes altogether.

I would also only have one class (Score.cs) handle all access to PlayerPrefs to keep things as clear and easy to follow as possible. Something like this:

using UnityEngine;
using UnityEngine.UI;

public class Score : MonoBehaviour
{
    public static int curScore;
    public static int highscore;
    public Text scoreText;
    
    // Called at start of scene.
    void Start()
    {
        highscore = PlayerPrefs.GetInt("Highscore");    // Restore latest highscore value.

        Movement.IsAlive = true;    // Maybe you need to reset this?
        InvokeRepeating("CountScore", 1, 0.5f);
    }

    // Called when changing scenes, if object not set to DontDestroyOnLoad.
    public void OnDestroy()
    {
        PlayerPrefs.SetInt("Highscore", highscore);     // Save highscore value.
    }

    void Update()
    {
        scoreText.text = "Score: " + curScore + "

Highscore: " + highscore);
}

    public void CountScore()
    {
        if (Movement.IsAlive == true)
        {
            curScore++;
        }
    }
}

Then just access these variables (curScore, Highscore) from the other scripts, rather than going through PlayerPrefs. I also don’t know why you would want to save the current score to PlayerPrefs? Just access the current score from Score.cs directly. The score is also probably not counting up because you forgot to set Movement.IsAlive back to true somewhere.