Save Level Selection

Hello,

I made a game with 100 levels and when i’m on level (for example) 80 and I finish it.
I close the game and When i’m going back to MenuScene, the game is on Level 1… and i have to scroll to level 80…

Anyone have an idea to save this ? (I have an Level.Json, to store all data level)
Here is my code :

void Start()
    {
        //Get Level data
        data = null;
        string path = JSON_PATH;
        TextAsset textAsset = Resources.Load<TextAsset>(path);
        data = textAsset.ToString().Split(';');

        //Get Level Data solved
        string[] levelSolvedData = PlayerPrefs.GetString(LevelManager.LEVELSOLVED_KEY).Split('_');
        int highestLevelSolved;

        //Find the highest level solved
        if (levelSolvedData.Length == 1)
        {
            highestLevelSolved = 0;
        }
        else
        {
            highestLevelSolved = int.Parse(levelSolvedData[0].Trim());
            for (int i = 1; i < levelSolvedData.Length; i++)
            {
                if (highestLevelSolved < int.Parse(levelSolvedData[i]))
                {
                    highestLevelSolved = int.Parse(levelSolvedData[i]);
                }
            }
        }

        //Find all levels resolved in the pack
        float range = highestLevelSolved / LEVELS_PER_PACK;
        List<int> listLevelSolvedInRange = new List<int>();
        if (highestLevelSolved != 0)
        {
            foreach (string o in levelSolvedData)
            {
                if (range > 0)
                {
                    if (int.Parse(o) >= range * LEVELS_PER_PACK && int.Parse(o) <= (range + 1) * LEVELS_PER_PACK)
                    {
                        listLevelSolvedInRange.Add(int.Parse(o));
                    }
                }
                else
                {
                    listLevelSolvedInRange.Add(int.Parse(o));
                }
            }
        }

        //Prepare scrollview level details
        #region Handle Level Detail Scrollview   

        //Calculate the level group
        float levelgroupNumber = Mathf.Ceil(data.Length / (float)buttonGroupPrefab.transform.childCount);
        ScrollToSelectedPack();
        int count = 0;

        //Generate the level group each level group at 20 levels
        for (int i = 1; i <= levelgroupNumber; i++)
        {
            GameObject buttonGroup = Instantiate(buttonGroupPrefab, levelDetailContent.transform.position, Quaternion.identity) as GameObject;
            buttonGroup.transform.SetParent(levelDetailContent.transform);
            buttonGroup.GetComponent<RectTransform>().localScale = new Vector3(1, 1, 1);

            int childCount = 0;
            for (int j = count; j < buttonGroup.transform.childCount * i; j++)
            {
                if (j >= data.Length)
                {
                    buttonGroup.transform.GetChild(childCount).gameObject.SetActive(false);
                }
                else
                {
                    LevelData levelData = JsonUtility.FromJson<LevelData>(data[j]);
                    Transform theChild = buttonGroup.transform.GetChild(childCount);
                    theChild.GetComponentInChildren<Text>().text = levelData.levelNumber.ToString();

                    LevelButtonController levelButtonController = theChild.GetComponent<LevelButtonController>();
                    GameObject lockOb = theChild.Find("Lock").gameObject;
                    GameObject imgSolvedOb = theChild.Find("imgSolved").gameObject;
                    Image levelImg = theChild.Find("Mask").Find("Image").GetComponent<Image>();
                    RectTransform levelImgRT = levelImg.GetComponent<RectTransform>();

I hope anyone can help me with that…

If anyone have an idea but he had to look deeper in my code, we can go on chat (Skype or something else)

Thanks for your time and help.

Best regards,
Shinsuki

This is the kind of thing that PlayerPrefs is good for. When you get up to a level, store an int with its number using PlayerPrefs. When you go to the main menu, pre-select the appropriate level based on that number.

1 Like

To answer the question you sent via PM…

PlayerPrefs is a class provided by Unity which allows you to persistently store and retrieve simple data between runs of your game. As per the name, it’s intended use is storing preference information that the player has selected, but that’s functionally equivalent to storing other simple data, such as what level the player is up to.

In your case, I’d probably do something like…

PlayerPrefs.SetInt("selectedLevel", X);

…when the player picks a level from your menu, or when the player wins a level.

When the menu us opened, you’ll want to use GetInt(…) to get the value you’ve stored, and use that to select the relevant level in the menu. Note that GetInt(…) also takes two parameters - the first is the name of the value you’re looking for, and the second is a default value to return if no stored value is found. That’s very useful, because it means you don’t have to separately do a check to see if a value has been stored and then write separate code paths to handle each case. Just provide the number for your first level as a default, and if no value is stored the code will then just select the first value, no fuss.

int storedSelectedLevel = PlayerPrefs.GetInt("selectedLevel", 0);

Note: This is the kind of stuff PlayerPrefs is great for. If you need to store complex or large data, though, don’t forget that we’ve got access to a full .NET environment, including file IO and a bunch of other handy related stuff.

1 Like

Small update/note: The method is: Unity - Scripting API: PlayerPrefs.GetInt

2 Likes

Ah, thanks!

1 Like

:slight_smile: np heh

1 Like

I answered this the first time you posted here: Load Level Data.json

Did I answer your question incorrectly or misunderstand something?

2 Likes

It’s unfortunate when people double post (or triple, etc…lol) :slight_smile:

1 Like

Hello,

Thanks for all the help.

But I don’t know how to call it ? (I understand the part of GetInt)
but in my code, I don’t know where to put it… ??

using UnityEngine;
using System.Collections.Generic;
using System.IO;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using SgLib;

public class LevelScroller : MonoBehaviour
{
    public const string JSON_PATH = "Json/LevelsData";

    public static int maxUnlockedLevel;
    public static int levelSnapped = 1;
    public const int LEVELS_PER_PACK = 20;
    public static bool isLevelDetailActive;

    public ScrollRect levelDetailScrollview;
    public ScrollRect levelPackScrollview;
    public GameObject levelDetailContent;
    public GameObject levelPackContent;
    public GameObject buttonGroupPrefab;
    public GameObject levelPackPrefab;

    [Header("Config")]
    public Color lockedColor;
    // Percent
    public int packCompletePercentage = 99;

    private string[] data;
    private const string MAX_UNLOCKED_LEVEL_PPK = "SGLIB_MAX_UNLOCKED_LEVEL";

    // Use this for initialization
    void Start()
    {
        //Get level data
        data = null;
        string path = JSON_PATH;
        TextAsset textAsset = Resources.Load<TextAsset>(path);
        data = textAsset.ToString().Split(';');
        PlayerPrefs.SetInt("LevelSnap",levelSnapped);

        //Get level data solved
        string[] levelSolvedData = PlayerPrefs.GetString(LevelManager.LEVELSOLVED_KEY).Split('_');
        int highestLevelSolved;

        //get the highest level data solved
        if (levelSolvedData.Length == 1)
        {
            highestLevelSolved = 0;
        }
        else
        {
            highestLevelSolved = int.Parse(levelSolvedData[0].Trim());
            for (int i = 1; i < levelSolvedData.Length; i++)
            {
                if (highestLevelSolved < int.Parse(levelSolvedData[i]))
                {
                    highestLevelSolved = int.Parse(levelSolvedData[i]);
                }
            }
        }

        //get level data solved in pack
        float range = highestLevelSolved / LEVELS_PER_PACK;
        List<int> listLevelSolvedInRange = new List<int>();
        if (highestLevelSolved != 0)
        {
            foreach (string o in levelSolvedData)
            {
                if (range > 0)
                {
                    if (int.Parse(o) >= range * LEVELS_PER_PACK && int.Parse(o) <= (range + 1) * LEVELS_PER_PACK)
                    {
                        listLevelSolvedInRange.Add(int.Parse(o));
                    }
                }
                else
                {
                    listLevelSolvedInRange.Add(int.Parse(o));
                }
            }
        }

Thanks you for your help.

And sorry to double post…

Best regards,
Shinsuki

All my post tells you is how to set and get the value. You need to add other things to your code as well for it to be useful.

The GetInt(…) part goes where your menu is being set up. Once you’ve got the value you use it to select and/or scroll to the appropriate item.

The SetInt(…) part goes after the player has selected a level, to store that level’s value for next time.

You might also need to call Save() or something like that, read the docs page I linked to.

1 Like

Hello,

Thanks you it’s working :slight_smile:

Thanks again for your help.

Best regards,
Shinsuki

1 Like

Glad it’s working for ya :slight_smile: