0
\$\begingroup\$

I'm making a player settings thing where the user can turn off or turn on the game music by clicking buttons. I had this script below and everything was working fine.

 private GameObject music;

 public void Start()
 {
     music = GameObject.FindGameObjectWithTag("Music");
 }
 public void YesButton()
 {
     music.SetActive(true);
 }

 public void NoButton()
 {
     music.SetActive(false);
 }

I want to save it as player preferences so when they go out and back into the game, their settings would be saved. How would I do this? This is what I tried:

 private GameObject music;
 private bool musicOn = true;

 public void Start()
 {
     music = GameObject.FindGameObjectWithTag("Music");
 }

 public void YesButton()
 {
     musicOn = true;
     PlayerPrefs.GetInt("MusicOn", (musicOn ? 1 : 0));
 }

 public void NoButton()
 {
     musicOn = false;
     PlayerPrefs.GetInt("MusicOn", (musicOn ? 1 : 0));
 }

 void Update()
 {
     PlayerPrefs.SetInt("MusicOn", (musicOn ? 1 : 0));

     int value;

     value = musicOn ? 1 : 0;

     if (musicOn)
     {
         value = 1;
         music.SetActive(true);
     } else if (!musicOn)
     {
         value = 0;
         music.SetActive(false);
     }
 }

But it doesn't work. When I click the "no" button, the music turns off but it turns back on when I go back into the game. How would I fix this problem? Thanks for your help!

New code that mostly works:

public GameObject music;
public bool musicOn = true;

public void Start()
{
    music = GameObject.Find("Music");
    bool musicOn = PlayerPrefs.GetInt("MusicOn", 0) > 0;
    if (musicOn)
        YesButton();
    else
        NoButton();
}

public void YesButton()
{
    music.SetActive(true);
    PlayerPrefs.SetInt("MusicOn", 1);
}

public void NoButton()
{
    music.SetActive(false);
    PlayerPrefs.SetInt("MusicOn", 0);
}
\$\endgroup\$
2
\$\begingroup\$

It is because you are setting PlayerPref in Update method. Now, you start your game, ant object's values are reset to initial value. So music object becomes null and musicOn becomes true (because you defined it explicitly to be initialized with true). You don't retrive actual value from PlayerPrefs when object is created in scene (Start method), thus on first Update your PlayerPrefs value is set to 1 (true).

There's two solutions to your problem, the ugly and the nice.

The ugly solution is to load your PlayerPref value in Start method.

The nice solution is to load your PlayerPref value in Start method AND move PlayerPrefs.SetInt from Update to YesButton and NoButton methods, after musicOn value is set. Add music.SetActive() to YesButton and NoButton methods as well. Delete Update method as it is no longer needed.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I now have code (I edited my post so you can see it there) that mostly works. It enables and disables the gameObjects that have the tag "music" and it is properly saving, however, it doesn't enable or disable the gameObjects with the tag "music" if it is in another scene. How can I make this code work across multiple scenes? \$\endgroup\$ – Matheson Jul 19 at 2:01
  • \$\begingroup\$ @Matheson I'm not sure exactly... There should be answers on this topic. Try googling 'unity how to find objects in other scenes'. I think it might return some useful links. \$\endgroup\$ – eLTomis Jul 19 at 12:23
0
\$\begingroup\$
public bool MusicOnBool;
    
// This method will toggle the MusicOnBool and saves it to playerprefs
public void ToggleButton()
{
    MusicOnBool = !MusicOnBool; // sets it to its opposite state
    music.SetActive(MusicOnBool);
    // Below we save the bool (which is either a 1 or 0) to "MusicOn"
    PlayerPrefs.SetInt("MusicOn", MusicOnBool ? 1 : 0); // condition ? true : false, so if the condition is true, itll be 1, otherwise it'll be 0.
    music.SetActive(MusicOnBool);
}

// This method can be called wherever, such as the Start() method in your script and basically it'll load the saved int and check to see if it's 1 which would be true. So if 0, it'll be false, if 1, it'll be true.
public void Load()
{
    MusicOnBool = PlayerPrefs.GetInt("MusicOn", 1) == 1;
    // EX: MusicOnBool = 0 == 1 will result in false
    music.SetActive(MusicOnBool);
}
| improve this answer | |
\$\endgroup\$

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.