0
\$\begingroup\$

I am working on Unity 2D game. I used PlayerPrefs to save the level of the scene. As I go from one level to the next, the levels become unlocked and it works fine. But, after unlocking a few levels, when I go back to the lowest level, all the levels above become locked. What is the problem in my code?

Here is the LevelSelector class:

public class LevelSelector : MonoBehaviour {

public void Update ()

  {
    {
        int myLevel = PlayerPrefs.GetInt ("LevelPassed",1);

        for (int level = 0; level < myLevel; level++) 
        {
        levelButtons[level].interactable = true;
        }
     }
   }
}

Here is the Score script:

public class Score : MonoBehaviour {

    void Update ()
    {

        UpdateScore ();


    }

    public void UpdateScore ()
    {


        if (sceneOne.isLoaded && meshLevel != null) {

            zLevel = 1;
            meshLevel.text = "Level  " + zLevel;
            PlayerPrefs.SetInt ("LevelPassed", 1);  
        }

        else if (sceneTwo.isLoaded && meshLevel != null) {

            zLevel = 2;
            meshLevel.text = "Level  " + zLevel;
            PlayerPrefs.SetInt ("LevelPassed", 2);
        }

        else if (sceneThree.isLoaded && meshLevel != null) {

            zLevel = 3;
            meshLevel.text = "Level  " + zLevel;
            PlayerPrefs.SetInt ("LevelPassed", 3);
        }

        else if (sceneFour.isLoaded && meshLevel != null) {

            zLevel = 4;
            meshLevel.text = "Level  " + zLevel;
            PlayerPrefs.SetInt ("LevelPassed", 4);

        }
    }
}
\$\endgroup\$
3
\$\begingroup\$

Since this looks like more of a Code Review question, I'll answer it like one. Please note that I'm writing all of this to offer help and constructive criticism.

First of all, you're checking what levels are available inside the Update() function, that means that your game is checking whether the levels are available at every frame, which is most likely at least 30 times per second.

You could fix this by using the code inside Start() or Awake(), depending on the situation, instead of Update().

Secondly, you're updating score at every frame too. There should be no need for this. You should only ever call that update score when the score changes. (i.e. you earn points, you call UpdateScore() method).

Also, in case of an if call, if you're using the same check at every single one, you should really consolidate them into one and anything you do in every single if call can also be consolidated into one, like so:

public void UpdateScore ()
{

  if(meshLevel != null){

    if (sceneOne.isLoaded) {
        zLevel = 1; 
    }
    else if (sceneTwo.isLoaded) {
        zLevel = 2;
    }
    else if (sceneThree.isLoaded) {
        zLevel = 3;
    }
    else if (sceneFour.isLoaded) {
        zLevel = 4;

    }
    meshLevel.text = "Level  " + zLevel;
    PlayerPrefs.SetInt ("LevelPassed", zLevel); 
  }
}

Now, let's get to the meat of the question.

Inside UpdateScore() you're setting the "LevelPassed" integer to whatever the level you are in. That means, if you replay any previous level, the "LevelPassed" integer will be set to that same level instead of the latest passed level.

You could fix that by writing a check to see whether the maximum passed level is lower than the level you're on, like this:

public void UpdateScore ()
{

  if(meshLevel != null){

    if (sceneOne.isLoaded) {
        zLevel = 1; 
    }
    else if (sceneTwo.isLoaded) {
        zLevel = 2;
    }
    else if (sceneThree.isLoaded) {
        zLevel = 3;
    }
    else if (sceneFour.isLoaded) {
        zLevel = 4;

    }
    meshLevel.text = "Level  " + zLevel;
    int maxLevelPassed = PlayerPrefs.GetInt ("LevelPassed", 1); //leaving 1 here since the minimum level to be passed is 1
    if( maxLevelPassed < zLevel )
    {
        PlayerPrefs.SetInt ("LevelPassed", zLevel);
    }
  }
}

This will ensure you are on a level you have not passed before and it should fix your problem. If it doesn't, then you have something else that interferes with the locks but you haven't posted it here.

\$\endgroup\$
  • 1
    \$\begingroup\$ Thank you @ John! I've spent 2 days without a clue! You made my day! \$\endgroup\$ – Haileapp Nov 28 '17 at 13:41
0
\$\begingroup\$

You need to check if the value stored in LevelPassed is already higher than the current value. As is, you're resetting the value each time, even if LevelPassed is already 4.

\$\endgroup\$
  • \$\begingroup\$ when i made with <= sign,it unlocks every other level even though the game become over at one level. \$\endgroup\$ – Haileapp Nov 27 '17 at 20:06
  • \$\begingroup\$ I misunderstood the problem. I've updated the answer. \$\endgroup\$ – Stephan Nov 27 '17 at 20:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.