0
\$\begingroup\$

I'm trying to create a scoring system for a game with multiple levels. For this I'm using the binary formatter instead of playerprefs (I read online that playerprefs are not that secure). I have created the system but whats happening is that the score is not resetting to 0 when I load a new level. If in one level the score was 10 and I start some other level, the score in this level starts from 10 instead of 0. This is the code I have so far:

public class ScoreIncrease : MonoBehaviour
{
  public Text scoreTxt;
  public int score;

void Start()
{
    LoadScore();        
}

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        Save();            
    }
}

public void Save()
{
    score++;
    scoreTxt.text = "Score" + score;
    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = File.Open(Application.persistentDataPath + "/scoreContainer.dat", FileMode.Create);

    ScoreContainer scoreContainer = new ScoreContainer();
    scoreContainer.score = score;
    bf.Serialize(file, scoreContainer);
    file.Close();
}

public void LoadScore()
{
    if(File.Exists(Application.persistentDataPath + "/scoreContainer.dat"))
    {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Open(Application.persistentDataPath + "/scoreContainer.dat", FileMode.Open);
        ScoreContainer scoreContainer = (ScoreContainer)bf.Deserialize(file);
        file.Close();
        score = scoreContainer.score;
        scoreTxt.text = "Score" + score;
    }
  }
}

[Serializable]
public class ScoreContainer
  {
    public int score;
  }

How can I change this so that each level has a separate highscore and all levels have a start score of 0?

\$\endgroup\$
4
  • \$\begingroup\$ When the scoreboard is just local, then you shouldn't think too much about security. The player would only be cheating themselves by changing their score. And you can not prevent them anyway. A tech-savvy player won't have issues with editing a binary file. \$\endgroup\$
    – Philipp
    Commented Apr 14, 2020 at 13:58
  • \$\begingroup\$ I plan on adding a leaderboard and that's the reason why I dont want to use playerprefs. \$\endgroup\$ Commented Apr 15, 2020 at 11:34
  • \$\begingroup\$ Storing scores in local files doesn't get you any closer to an online leaderboard either. \$\endgroup\$
    – Philipp
    Commented Apr 15, 2020 at 12:02
  • \$\begingroup\$ oh...ok.. I was under the impression that an online leaderboard takes the score from a users local files...If that's the case I might as well implement the scoring system using playerprefs. Thanks for your help... \$\endgroup\$ Commented Apr 16, 2020 at 10:38

1 Answer 1

1
\$\begingroup\$

You could have a separate file for each level and put the level number into the filename. For example, if your game has 200 levels, name the files "scoreContainer0.dat" to "scoreContainer199.dat".

When there is no score entry for a level yet, then that file won't exist yet. You can handle that case in LoadScore by setting score to 0 in that case.

string filename = Application.persistentDataPath + "/scoreContainer" + level + ".dat";
if(File.Exists(filename))
{
    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = File.Open(filename, FileMode.Open);
    ScoreContainer scoreContainer = (ScoreContainer)bf.Deserialize(file);
    file.Close();
    score = scoreContainer.score;
    scoreTxt.text = "Score" + score;
} else {
    score = 0;
    scoreTxt.text = "Not played yet";
}

However, a cleaner solution might be to store the scores for all levels in one file. In that case I would use a C# integer array with each entry representing a score and the index being the level, or a Dictionary<int, int> with the first integer being the level number and the second integer being the score (the value-type of the dictionary might later receive an upgrade to a structure which contains more information about the state of the level). Either data type can be handled by the BinaryFormatter.

But this will require some more considerations regarding how you access the score values for levels in the rest of your code.

\$\endgroup\$
1
  • \$\begingroup\$ ..thanks for this....so far the method you suggested seems to be working fine...I'm just using the scene build index to create a new file for each level. since there are only about 25 levels in my game, this will probably be fine.... \$\endgroup\$ Commented Apr 15, 2020 at 11:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .