PlayerPrefs - having trouble saving/loading high score on restart

Hi all,

I cant seem to make my “highscore” functionality save using Playerprefs.
I found a Brackey’s guide and i followed it to the letter, but im not sure if there is another element interfering with it that was not covered by the guide.

it resets back to zero visually, but i can see that it isn’t updating along side the score meaning it is registering that the current score is below the previous high score, but it shows 0 until it is beaten. When i restart the game it goes back to 0.

Any advice is appreciated, and apologies in advance if my question isn’t using all the right terminology!

public class LogicScript : MonoBehaviour
{
    public int playerScore;
    public Text scoreText;
    public GameObject gameOverScreen;
    public Text highScore;

    public void Start()
    {
         highScore.text = PlayerPrefs.GetInt("Highscore", 0).ToString();       
    }
     
    public void addScore(int scoreToAdd)
    {
        playerScore = playerScore + scoreToAdd;
        scoreText.text = playerScore.ToString();

        if (playerScore > PlayerPrefs.GetInt("HighScore", 0))
        {
            PlayerPrefs.SetInt("HighScore", playerScore);
            highScore.text = playerScore.ToString();
        }
    }
   public void scoreReset()
    {
        PlayerPrefs.DeleteKey("HighScore");
    }

It’s a case issue. On line 10 you’ve spelled the word “score” with a lowercase s, but you’ve stored the value in PlayerPrefs with an uppercase S.

While we’re on the subject of case, you’ve spelled some of your method names using camelCase and others beginning with a capital. Try to keep all your method names in a similar format. Generally, methods are spelled beginning with a capital letter and variables beginning with a lowercase letter or underscore to make them easy to differentiate.

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

public class LogicScript : MonoBehaviour {

    public int playerScore;
    public Text scoreText;
    public Text highScore;

    void Start ()
    {
        highScore.text = PlayerPrefs.GetInt ("HighScore", 0).ToString ();    
    }
   
    public void AddScore (int scoreToAdd)
    {
        playerScore = playerScore + scoreToAdd;
        scoreText.text = playerScore.ToString ();

        if (playerScore > PlayerPrefs.GetInt ("HighScore", 0))
        {
            PlayerPrefs.SetInt ("HighScore", playerScore);
            highScore.text = playerScore.ToString ();
        }
    }

    public void ScoreReset ()
    {
        PlayerPrefs.DeleteKey ("HighScore");
    } 

}
2 Likes

Yes this… you never want to ever type the word “Score” (or any other string literal used as a key) more than once.

Check out this pattern:

Here’s an example of simple persistent loading/saving values using PlayerPrefs:

https://gist.github.com/kurtdekker/01da815d2dfd336a925ae38019c3a163

Useful for a relatively small number of simple values.

And anyway, to your original question… here is my “best score” and/or “lowest time” approach:

Tracking simple high score / low time single-entry leaderboard:

For the highest score: https://pastebin.com/VmngEK05

Usage:

TheBest.RecordScoreIfHigher( lastGamePlayScore);

For the lowest time: https://pastebin.com/A7GC76uQ

Usage:

TheBest.RecordTimeIfLower( lastGamePlayTime);

To retrieve the best score or time, use one of these:

int bestScore = TheBest.BestScore;
float bestTime = TheBest.BestTime;

Full usage example:

https://pastebin.com/ygFAvNsM