[Fixed ! Thanks !] Save multiple variable for multiple scenes

Hello everyone, I hope you’re ok. :wink:

I try to make something simple : just save some variable (like a score and, later, the time needed to finish a level) for different scenes. Until then, I just succed to save one variable but that variable is call in everyone of my level. So, the score of my second level erase the score of my first, it’s pretty bad, yeah.

This is what I’ve done so far :

ScoreSaver script

    private FinalPointScript finalPointScript = null;
    private GameController gameController = null;

    static int pointsOnThisLevel = 0;

    // Use this for initialization
    void Start ()
    {
        GameObject gameControllerObject = GameObject.Find("GameController");
        gameController = gameControllerObject.GetComponent<GameController>();

        GameObject finalPointObject = GameObject.Find("FinalPoint");
        finalPointScript = finalPointObject.GetComponent<FinalPointScript>();

        pointsOnThisLevel = PlayerPrefs.GetInt("pointsOnThisLevel");
    }
   
    // Update is called once per frame
    void Update ()
    {
        if (Input.GetKeyDown("x"))
        {
            print("number of points" + pointsOnThisLevel);
        }

        if (finalPointScript.playerColFinalPoint == true)
        {
            if (pointsOnThisLevel < gameController.countPoints)
            {
                pointsOnThisLevel = gameController.countPoints;
                PlayerPrefs.SetInt("pointsOnThisLevel", pointsOnThisLevel);
            }
        }
    }
}

Maybe it’s something simple what I want to do but I’m really novice at programing. If something can explane me how create an array to save my variables the right way (because I suppose it’s a nice way to do this), I’ll be really interested and grateful. :3

If you need to see other scripts, tell me.

Thanks for you help.

If you only want to do a local save of high scores, you could do several things.
If you don’t have a ton of levels, you could just make a PlayerPref to store each high score in its own PlayerPref.
So something like PlayerPrefs.SetInt(“Level1Score”, score);
You would just have to retrieve the right score depending on what level you are on.

If you want to do an Array, just remember Arrays can’t expand, so when you declare an array, it must be set to the number of levels you have in the game.

Personally, I’d probably do a score data class that holds level, score, and initials and create a List variable that I can add to or update. Then if I just wanted to do a local save, just convert it to Json and save to a PlayerPref. (there are other steps involving encryption that might be important also).

If you expect your players to always have access to the internet, you might consider a backend service with a Leaderboard api. Something like PlayFab or App42 are two that I’m familiar with. But only if you need that fancy of a service.

There are many other ways to do what you want, just depending on what you plan to do.

Hi and thanks for you awnser :smile:

I think I’ll try to do the way you personlly think is best. I’m really sorry to ask, can you take some time to explain me how do that ?

I try different things, and I thinks I have to begin with something like that :

ScoreSaver script

public class ScoreSaver : MonoBehaviour {

    public class ScoreTimeLevel
    {
        int Level = 0;
        static int ScoreLevel = 0;
        static float TimeLevel = 0;

        public ScoreTimeLevel (int level, int scoreLevel, float timeLevel)
        {
            Level = level;
            ScoreLevel = scoreLevel;
            TimeLevel = timeLevel;
        }
    }
            List<ScoreTimeLevel> scoreTimeLevel = new List<ScoreTimeLevel>();

But i’m stuck… It’s not the propre way to create list. I see different tutorial and I don’t know where is my mistake.
I hope I don’t do too much foolish things in this peace of code. :<

Thanks again for you help, I appreciate. :wink:

EDIT :

I add one using in my ScoreSaver script :

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

public class ScoreSaver : MonoBehaviour {

    public class ScoreTimeLevel
    {
        int Level = 0;
        static int ScoreLevel = 0;
        static float TimeLevel = 0;

        public ScoreTimeLevel (int level, int scoreLevel, float timeLevel)
        {
            Level = level;
            ScoreLevel = scoreLevel;
            TimeLevel = timeLevel;
        }
    }
         List<ScoreTimeLevel> scoreTimeLevel = new List<ScoreTimeLevel>();

Now my list work, but what is the next step ? I hope to find my self but if some one can help me, it will be perfect. :wink:

Well, with what you have set up, you’ll need to create a new ScoreTimeLevel object and add it to your list.

so, scoreTimeLevel.add(new ScoreTimeLevel(1, 2500, 43.5f)); if you just want a simple add to the list.

Just remember that if you want to keep this data between scenes, you’ll either need to make your list static, save the data to playerprefs, or use dontdestroyonload. If you want it to be saved between games, you’ll need to save it to playeprefs or to a file on the harddrive (or a backend service online).

Thanks for your intereset, really pleasant. ;3
I think I understand that. But, tell me If i’m wrong, with that list, I create some variables myself ? I don’t update them from the result of my player ?

Also, how my game can understand that my player play an another scene and so new variables had to be save an another place of my list ?

Humpf… >.< I I’m a little lost I think. I have to work code : actually I’m reading more than 400 pages of code and I learn all over again, I start with the beginning (the propre way to do I think xD)

Sorry if I’m not very clear but again, thanks for you awnser, it’s really helpful - I’m working something else thanks to you.

Here is the thing, only you can decide what works best for you. There are several ways to implement this feature. If all you wanted was an array of high scores, you could create a new array, set it to the amount of levels you have and then just assign values to it so

scores[currentLevel - 1] = earnedScore;
So if you beat level 1 with 5000, earnedScore would be 5000 in the first array slot. That way when you want to display the score for level 1, you know what array slot it is in.

With the list, you use add, so you might have scores out of order if you just add them in, depending on how you set it up. So using the List design that you have, you might have to use a .Find to find the proper level or a For loop checking the value of level till you find the level you want.

The other option is you use playerprefs and store scores in something like
PlayerPrefs.SetInt(“Score” + currentLevel, earnedScore);

There are also ways to store things into a json string and save this to a file or a single playerpref.
If you want this to persist through scenes, you’ll need to use either a static variable or store it in playerprefs where you can pull the values when you need them.

Personally, for my games I would use json, and depending on where I’m saving the data, probably some sort of encryption.

I decide to listen you recommandation Brathnann. After few days, I try to use Json to save my score, it’s almost good but I have some difficulty, I thinks it’s because I use some static variable but I don’t see how I can do something else.

using UnityEngine;
using UnityEngine.SceneManagement;
using LitJson;
using System.IO;
using System.Collections;
using System.Collections.Generic;

public class SetPlayerScore : MonoBehaviour {

    private FinalPointScript finalPointScript = null;
    private GameController gameController = null;

    static int myLevel = 0;
    static int myScore = 0;
    static double myTime = 0.00;

    JsonData saveLevelDataJson;

    public SaveLevelData levelData = new SaveLevelData(myLevel, myScore, myTime);

    // Use this for initialization
    void Start()
    {
        GameObject gameControllerObject = GameObject.Find("GameController");
        gameController = gameControllerObject.GetComponent<GameController>();

        GameObject finalPointObject = GameObject.Find("FinalPoint");
        finalPointScript = finalPointObject.GetComponent<FinalPointScript>();
     }


// Update is called once per frame
void Update ()
    {

        if (Input.GetKey("p"))
        {
            saveLevelDataJson = JsonMapper.ToJson(levelData);
            myLevel = SceneManager.GetActiveScene().buildIndex;
            myScore = gameController.countPoints;

            File.WriteAllText(Application.dataPath + "/PlayerData.json", saveLevelDataJson.ToString());
        }
    }
}

    public class SaveLevelData
    {
        public int id;
        public int score;
        public double time;

        public SaveLevelData(int id, int score, double time)
        {
            this.id = id;
            this.score = score;
            this.time = time;
        }

    }

When I press “p” during my game, a Json script is create but all my variable are equal to 0 (it’s because of statics variables ?).

Thanks for your support, I think I’m close to finish that script. \o/

Static doesn’t matter, since you are creating a new object.

The problem is you’re making a new SaveLevelData object and setting all it’s values to 0. (since your static variables start as 0).
You are then using JsonMapper to convert this to a string, so the values are still 0.
Then you are updating your static variables.
You never update your levelData to have new values.

You should be doing something like

if (Input.GetKey("p"))
        {
            levelData.id= SceneManager.GetActiveScene().buildIndex;
            levelData.score = gameController.countPoints;
            saveLevelDataJson = JsonMapper.ToJson(levelData);
          
            File.WriteAllText(Application.dataPath + "/PlayerData.json", saveLevelDataJson.ToString());
        }

Note that this is just going to save one level. And you’ll just keep overriding your current save file. You’ll need to do a list if you want to do multiple levels.

Who it’s working. Thanks :o
Thanks to that method, I can save all my stat, it’s perfet You’re a god to me ! :wink:

Ips. In fact, I have one problem (sort of). When I play an another level, all my variables in my Json change.
Can I do something about it ?

Of course. You’re saving one bit of data over another. As I said, you’ll either need to do a list and add the new SaveLevelData to it (or update if you have old data) or you have to create a json file for each level if you’re just going to overwrite it.

Really sorry to bother you with this :wink:

I’ll try the second option I think. Thanks. :wink: