Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

[CLOSED] How Do I Save PlayerPrefs?

Discussion in 'Scripting' started by ChrisIsAwesome, Mar 19, 2017.

  1. ChrisIsAwesome

    ChrisIsAwesome

    Joined:
    Mar 18, 2017
    Posts:
    184
    This may sound like a dumb question coming from someone who's been using Unity for 2 years now, but it's not working no matter what I try. Here's what I have:

    Code (JavaScript):
    1. PlayerPrefs.SetFloat ("Best Distance", bestDistance);
    2. PlayerPrefs.Save ();
    The problem with the above code is it does not save. When I load the next scene, it zeroes out the PlayerPref, even though I have no code to do that in the next scene or in the transition between scenes. I don't even have the bestDistance variable in the next scene yet.

    When printing the PlayerPref from the time I change it to the time I load the next scene, it displays the correct value upon changing, but going to another scene zeroes it out. However, if I quit the game before going to the next scene, it does save. So changing scenes prevents the PlayerPrefs from saving.

    If needed, I could post my full script.

    Using Unity 5.5 / Windows 8.1 (am stuck with this filth for now)

    Any help would be greatly appreciated.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    My only guess is something is happening that is overwriting the playerpref. Or, you may be trying to read in the playerpref, but maybe you have a typo, which means it's returning a default value ( this is a thought).

    So, you may want to verify that your are getting the proper playerpref. Otherwise, you may need to show some more code for where you are dealing with your playerprefs.
     
  3. ChrisIsAwesome

    ChrisIsAwesome

    Joined:
    Mar 18, 2017
    Posts:
    184
    No typos (was first thing I checked when it wasn't working).

    Full code:
    Code (JavaScript):
    1. var player : GameObject;
    2. var bestDistanceText : UI.Text;
    3. var currentDistanceText : UI.Text;
    4. var bestDistance : float;
    5. var currentDistance : float;
    6. var isPlayerDead : boolean;
    7. function Awake ()
    8. {
    9.      bestDistance = PlayerPrefs.GetFloat ("Best Distance");
    10.      currentDistance = 0.0;
    11.  
    12.      bestDistanceText.text = bestDistance.ToString ();
    13. }
    14. function Start ()     // Add ".0 m" if number does not have anything after decimal (1 to 1.0, 2 to 2.0, 10 to 10.0, etc.)
    15. {
    16.      if (System.Math.Round (Mathf.Abs (bestDistance), 1) == bestDistance, 0))
    17.      {
    18.           bestDistanceText.text = bestDistance + ".0 m";
    19.      }
    20.      else
    21.      {
    22.           bestDistanceText.text = bestDistance + " m";
    23.      }
    24. }
    25. function Update ()
    26. {
    27.      isPlayerDead = player.GetComponent (Player_Control).isPlayerDead;
    28.    
    29.      currentDistance = System.Math.Round (Mathf.Abs (Time.timeSinceLevelLoad / 2), 1);
    30.      if (System.Math.Round (Mathf.Abs (currentDistance), 1) == System.Math.Round (currentDistance, 0))    // Add ".0 m" if number does not have anything after decimal (1 to 1.0, 2 to 2.0, 10 to 10.0, etc.)
    31.      {
    32.           currentDistanceText.text = currentDistance + ".0 m";
    33.      }
    34.      else
    35.      {
    36.           currentDistanceText.text = currentDistance + " m";
    37.      }
    38.      if (currentDistance >= bestDistance)
    39.      {
    40.           NewBestDistance ();
    41.      }
    42.    
    43.      if (isPlayerDead == true)
    44.      {
    45.           PlayerIsDead ();
    46.      }
    47. }
    48. function NewBestDistance ()
    49. {
    50.      bestDistance = currentDistance;
    51.      bestDistanceText.text = currentDistanceText.text;
    52. }
    53.  
    54. function PlayerIsDead ()
    55. {
    56.      if (currentDistance >= bestDistance)
    57.      {
    58.           PlayerPrefs.SetFloat ("Best Distance", bestDistance);
    59.      }
    60. }
     
  4. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    Are you possibly switching scenes to fast that the playerpref never gets set?

    Could test this with a print statement in your PlayerIsDead function and see if it prints out before a scene switch. You say it works when you don't switch scenes which makes me wonder if this is the case.
     
  5. ChrisIsAwesome

    ChrisIsAwesome

    Joined:
    Mar 18, 2017
    Posts:
    184
    Unless it takes more than about 10 seconds to save it. When the player dies, I have an animation that lasts about 10 seconds, so the PlayerPref is set about 10 seconds before the scene even switches.

    EDIT: I forgot to mention that when I tried the same code to do this that I had in an older project that worked (worked in an older version of Unity, 5.something), so if something's changed in the 5.5 update regarding PlayerPrefs, that might be the cause. But I haven't seen anything about any PlayerPref changes.
     
  6. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    I'm using 5.5.1 on a project at work that uses playerprefs and have no issues.

    Now, one thing to be mindful of, and I'm not sure if this could create a problem is that you are doing this in update. Which means, since you say you have an animation playing, that you PlayerPrefs is getting called several times a second. Not usually an efficient way of doing it. Generally I would suggest that when you player dies, you set the playerpref once at that point. Now, I can't say if this would create problems or not, but it's something to note.

    Otherwise, I'm not seeing any issues with the code you posted.
     
  7. mumbot

    mumbot

    Joined:
    Oct 19, 2012
    Posts:
    86
    Iv used playerprefs many times how ever i always format my names for them like so "Player_Health" "Player_ID" etc etc. So there could be a chance that having a space "Player Health" may be effecting it? not sure just a guess.
     
  8. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    Hey @ChrisIsAwesome. I had similar problem in the past. I can't remember what exactly was the issue but one thing that I would advise is take your PlayerPrefs code related code and try it on isolated project to make sure your logic is fine (syntax looks ok).

    Speaking of which there are couple of things you could check.

    Code (csharp):
    1.  
    2. function PlayerIsDead ()
    3. {
    4.     if (currentDistance >= bestDistance) {
    5.         Debug.Log("Storing best distance");    // <---- Log something out to see if you actually saving
    6.         PlayerPrefs.SetFloat ("Best Distance", bestDistance);
    7.         PlayerPrefs.Save();    // <---------- This seems to be missing in your code
    8.     }
    9. }
    10.  
     
  9. ChrisIsAwesome

    ChrisIsAwesome

    Joined:
    Mar 18, 2017
    Posts:
    184
    Forgot to put the line PlayerPrefs.Save () in the code I posted. I didn't copy/paste code because wanted to leave out unnecessary bits of code. Just forgot to write in that line.

    Anyways, I've tried doing that. My code is:

    Code (JavaScript):
    1. function PlayerIsDead ()
    2. {
    3.      if (currentDistance >= bestDistance)
    4.      {
    5.           bestDistance = currentDistance;
    6.        
    7.           print ("Current distance is: " + currentDistance);
    8.           print ("Best distance is: " + bestDistance);
    9.           PlayerPrefs.SetFloat ("Best Distance", bestDistance);
    10.           PlayerPrefs.Save ();
    11.           print ("PlayerPRefs has been saved as: " + PlayerPrefs.GetFloat ("Best Distance");
    12.      }
    13. }
    I also now call is PlayerIsDead function from the player script at the start of the death animation (so it is only called once, rather than calling it in Update). The output in the console is:

    Current distance is: 1.4
    Best distance is: 1.4
    PlayerPrefs has been saved as: 1.4

    However, in the Awake function in the script in the next scene, I have print (PlayerPrefs.GetFloat ("Best Distance"); and that returns 0.
     
  10. ChrisIsAwesome

    ChrisIsAwesome

    Joined:
    Mar 18, 2017
    Posts:
    184
    FIXED IT!!

    Problem was in another script that controlled global input (input constant across all scenes for debugging purposes), I had the line:

    Code (JavaScript):
    1. if (Input.GetKey (KeyCode.Delete))
    2. {
    3.      PlayerPrefs.DeleteAll ();
    4. }
    And apparently, even though the key wasn't being pressed, Unity was acting like it was upon loading scenes. Might be my keyboard actually because the Delete key is a function key. But problem solved! Thank you all for your help!
     
    IndieForger likes this.
  11. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    Nice one! Well done @ChrisIsAwesome