Coding_Goose
Coding_Goose

Reputation: 37

How to Fix Save and Load Play Prefs

I have a settings menu that has the option for a volume, viewdistance, and quality sliders. I want to save the value of those and use them when the player loads into the game. My issue is the quality level and view distance reset while the volume saves properly.

private void Start()
    {
        if(!PlayerPrefs.HasKey("musicVolume"))
        {
            PlayerPrefs.SetFloat("musicVolume",1);
            Load();
        }
        else 
        {
            Load();
        }
        if (!PlayerPrefs.HasKey("qualityLevel"))
        {
            PlayerPrefs.SetInt("qualityLevel",6);
            Load();
            
        }
        
        else 
        {
            Load();
        }
        if (!PlayerPrefs.HasKey("ViewDistance"))
        {
            PlayerPrefs.SetFloat("ViewDistance", 10);
            Load();
            Debug.Log("saved viewdistance" + qualityslider.value * 1000);
        }
        else 
        {
            Load();
        }
    }
private void Save()
    {
        
        PlayerPrefs.SetFloat("musicVolume", volumeslider.value);
        PlayerPrefs.SetInt("qualityLevel", QualitySettings.GetQualityLevel());
        PlayerPrefs.SetFloat("ViewDistance", qualityslider.value);
    }
private void Load()
    {
        volumeslider.value = PlayerPrefs.GetFloat("musicVolume");
        qualityslider.value = PlayerPrefs.GetFloat("ViewDistance");
         QualitySettings.SetQualityLevel(PlayerPrefs.GetInt("qualityLevel"));
    }
public void ChangeVolume ()
     
    {
        Save();
        AudioListener.volume = volumeslider.value;

    }
public void ChangeViewDistance()
{
    Save();
    Camera.main.farClipPlane  = viewDistanceSlider.value * 1000;

}
 public void ChangeQuality(float level)
 {
    //level = qualityslider.value;
      
           
           // QualitySettings.SetQualityLevel(level, false);
           
           switch((float)level)
      {

         case 0:
     QualitySettings.SetQualityLevel(0); // For lowest quality
     break;
     case 1:
     QualitySettings.SetQualityLevel(1); // For lowest quality
     break;
     case 2:
     QualitySettings.SetQualityLevel(2); // For lowest quality
     break;
     case 3:
     QualitySettings.SetQualityLevel(3); // For lowest quality
     break;
     case 4:
     QualitySettings.SetQualityLevel(4); // For lowest quality
     break;
     case 5:
     QualitySettings.SetQualityLevel(5); // For lowest quality
     break;
     case 6:
     QualitySettings.SetQualityLevel(6); // For lowest quality
     break;
      }
       
}



This is my first time trying save and load with player prefs in unity. I recieve no errors and can't find anything online. The volume saves but the view distance and quality do not.

UI

UI

ChangeQuality

Change View Distance Change Volume

Upvotes: 0

Views: 340

Answers (4)

derHugo
derHugo

Reputation: 90862

The main mistake is

qualityslider.value = PlayerPrefs.GetFloat("ViewDistance");

That's the wrong slider! ;)


In general you Load the values into the sliders .. but you do not apply them to the actual systems!

Before coming to that some other comments.

In the ChangeQuality you are using a switch on a float value.

For a float it is mostly unlikely that they ever match an exact integer value! E.g. 0.5 + 0.5 might instead of the expected 1 rather be 1.0000001 or 0.99999999 in which case it won't enter the expected case.

You would probably rather do something like e.g.

var level = Mathf.Clamp(Mathf.RoundToInt(value), 0, 6);
QualitySettings.SetQualityLevel(level);

Besides that as mentioned before you are not calling Save within that method.

In general your entire Start method could be simplified a lot by simply providing fallback/default values like

private void Start ()
{
    Load();
}

private void Load()
{
    var volume = PlayerPrefs.GetFloat("musicVolume", 1);
    var distance = PlayerPrefs.GetFloat("ViewDistance", 10);
     var quality= PlayerPrefs.GetInt("qualityLevel", 6);

    // ... See below 
}

Then later on I would always only actually set the value that changed instead of everytime polling and saving them all.

Therefore you should use parameterized callbacks and do

public void ChangeVolume (float value)   
{
    AudioListener.volume = volumeslider.value;
    PlayerPrefs.SetFloat("musicVolume", value);
}

public void ChangeViewDistance(float value)
{
    Camera.main.farClipPlane  = viewDistanceSlider.value * 1000;
    PlayerPrefs.SetFloat("ViewDistance", value);
}

public void ChangeQuality(float value)
{
    var level = Mathf.Clamp(Mathf.RoundToInt(value), 0, 7);
    QualitySettings.SetQualityLevel(level);
    PlayerPrefs.SetInt("qualityLevel", level));
}

And then finally coming back to the very first point:

Actually call all those once after loading!

private void Load()
{
    var volume = PlayerPrefs.GetFloat("musicVolume", 1);
    ChangeVolume(Volume);
    var quality =  PlayerPrefs.GetInt("qualityLevel", 6);
    ChangeQuality(quality);
    var distance = PlayerPrefs.GetFloat("ViewDistance", 10);
    ChangeViewDistance(distance);
}

Upvotes: 2

danixdev1205
danixdev1205

Reputation: 68

To save the changed value of a slider to PlayerPrefs your public method must look like that

public void ChangeQuality(System.Single value) => PlayerPrefs.SetFloat("qualityLevel", Mathf.Clamp(value, 0, 6));

You need to use System.Single because it will help Unity automatically pass the new value, so you can save it.

Your method in the list must be under 'Dynamic float' label

enter image description here

Upvotes: 0

danixdev1205
danixdev1205

Reputation: 68

Well, firstly,

You check if the key exists and if you don't set the value, you can just use PlayerPrefs.GetFloat("YourKey", DefaultValue) because when the player will need a different value they'll just change it in the settings and the new value will be read.

Secondly, you don't need to always update the preferences, only when they are changed, i. e. you change volume and save only volume, it's easier to write and read.

Thirdly, in ChangeQuality(float level) you can just do QualitySettings.SetQualityLevel(level) and use Mathf.Clamp(level, 0, 6) if you wanna restirct with the range from 0 to 6.

After doing that check if you call ChangeViewDistance() and ChangeQuality(), that's probably the whole cause of the problem.

Upvotes: 0

Louis Ingenthron
Louis Ingenthron

Reputation: 1368

Your ChangeVolume() function calls Save() but your ChangeQuality() function does not.

Upvotes: 0

Related Questions