playerprefs record

I have a script which uses playerprefs to store the time to finish the game, so when players finishes, they would see if they have the best and shortest time so far on the last page and the main menu. I tried the following code and print keys to make sure the function runs correctly.

However, no matter how I change the save name “TimeLeft#”, it always shows that Playerprefs has key and move to the next part. And I don’t know why scoretemp never got updated and stayed at 0, which cause the function always print “2key” and show 0 on the time record.

Could anybody help me? I don’t need a ranking or name, just a string shows the current best record…

var timeGUI : GUIText;
static var scoretemp : int;

var timeLeftInt4 : int;




function Update () 
{
	
timeLeftInt4 = PlayerPrefs.GetInt("TimeLeft6");


if(PlayerPrefs.HasKey("TimeLeft6") == false)
{
	print("0key");
	scoretemp = timeLeftInt4;
	timeGUI.guiText.text = "" + scoretemp;
	return;	
}


if(PlayerPrefs.HasKey("TimeLeft6") == true)
	{
		
		
	if (scoretemp > timeLeftInt4)
		{
			
			timeGUI.guiText.text = "" + timeLeftInt4;
			print("1key");	
			scoretemp = timeLeftInt4;
			return;
		}
	if (scoretemp < timeLeftInt4)
		{
			print("2key");	
			
			timeGUI.guiText.text = "" + scoretemp;
		return;
		
		}
}
}

It’s a little difficult to figure it out because of your variable names. I’ve re-written it below, try this and see if it works.

function Update () 
{
	if(PlayerPrefs.HasKey("TimeLeft") == false) 
	{ 
   		print("No Stored Key."); 
   		timeGUI.guiText.text = "" + scoretemp; 
	} 

	else if(PlayerPrefs.HasKey("TimeLeft6") == true) 
	{ 
		print("Key Found."); 

		timeLeft = PlayerPrefs.GetInt("TimeLeft"); 
       
		// current time is equal to or better than saved time
   		if (currentTime >= timeLeft) 
      	{ 
   			print("Current Time is better."); 
          
         	timeGUI.guiText.text = "" + timeLeft; 
         	currenTime = timeLeft; 
      
		} 
   		// saved time is better
		else if (currentTime < timeLeft) 
      	{ 
   			print("Saved Time is better."); 
     
        	timeGUI.guiText.text = "" + scoretemp; 
     	} 
	} 
}

One problem was had was in your first case:

timeLeftInt4 = PlayerPrefs.GetInt("TimeLeft6"); 

if(PlayerPrefs.HasKey("TimeLeft6") == false) 
{ 
   scoretemp = timeLeftInt4; 
}

This doesn’t make sense. If the key didn’t exist, you shouldn’t have been using the value you assigned to timeLeftInt4.

thank you Tempest!! HasKey problem makes sense to me now…
I just rewrote my code based on what you provided, but the problem still exists.

  1. Even if I changed the PlayerPrefs save name, it still passed the first part and move to the HasKey == true part.

  2. Then currentTime still didn’t get updated, so it stayed at 0, which made the save time is always the better one…

var timeGUI : GUIText;
static var currentTime : int;
var timeLeft : int;




function Update () 
{ 
   if(PlayerPrefs.HasKey("TimeLeft7") == false) 
   { 
         print("No Stored Key."); 
         timeGUI.guiText.text = "" + currentTime; 
   } 

   else if(PlayerPrefs.HasKey("TimeLeft7") == true) 
   { 
      print("Key Found."); 

      timeLeft = PlayerPrefs.GetInt("TimeLeft7"); 
        
      // current time is equal to or better than saved time 
         if (currentTime >= timeLeft) 
         { 
            print("Current Time is better."); 
          
            timeGUI.guiText.text = "" + timeLeft; 
            currenTime = timeLeft; 
      
      } 
         // saved time is better 
      else if (currentTime < timeLeft) 
         { 
            print("Saved Time is better."); 
      
           timeGUI.guiText.text = "" + currentTime; 
        } 
   } 
}

Nothing in the snippet you’ve provided gives currentTime a value, so there is no reason why currentTime is 0.

Is there another game script, or another function, which is supposed to give currentTime the value? Can you post a bit more of the script, and explain what you want the script to do?

No, I only use currentTime here to save the length of time when player finishes the game for further comparison with the new record.

This is the script I post on my main menu, which shows the "“Best time is ### seconds.” No ranking. No name. Just the shortest time the player ever finished the game.

I have another script attached to the last level before goal, which basically store the time spent so far (“TimeLeft7”). It works accurate though.

So maybe there is something wrong with my script or my approach is not right from the beginning…

I think what they are saying is the you never SET currentTime. If you never set it then it will be 0, because an empty int == 0 (I think).

It looks like the only place you set currenTime is in if (currentTime >= timeLeft), which might be never, because current time is 0 and your ‘time left’ should be more than that I assume. I’m not sure what “time left” means though.

It probably isn’t the cause, but your variable names are a bit confusing:

print("Saved Time is better."); 
timeGUI.guiText.text = "" + currentTime;

Why would the saved time be called ‘currentTime’. Usually the current is the current one, not the saved one.

I’m a stickler for readability because I teach scripting. I believe clean code and good names lead to less bugs and quick debugging.

Even if what I think I see here is not helpful, you might want to try just going through it statement by statement, adding one at a time, naming things differently, and maybe the cause will reveal itself…divide and conquer.

Thank you rsx. Yeah it was a bit confusing, so I rewrote the following code.
I am sure the problem is the currentSavedTime was never assigned, which makes it 0 and always the best time in the record. But I don’t know where I could assign the first newTime as the currentSavedTime, so the record could be updated…

var timeGUI : GUIText;
static var currentSavedTime : int;

var newTime : int;




function Update () 
{ 
	currentSavedTime = newTime;
	
   if(PlayerPrefs.HasKey("TimeSpent") == false) 
   { 
         print("No Stored Key."); 
         timeGUI.guiText.text = "" + currentSavedTime; 
   } 

   else if(PlayerPrefs.HasKey("TimeSpent") == true) 
   { 
      print("Key Found."); 

      newTime = PlayerPrefs.GetInt("TimeSpent"); 
        
      // current time is equal to or better than saved time 
         if (currentSavedTime >= newTime) 
         { 
            print("New Time is better."); 
          
            timeGUI.guiText.text = "" + newTime; 
            currentSavedTime = newTime; 
      
      } 
         // saved time is better 
      else if (currentSavedTime < newTime) 
         { 
            print("Saved Time is better."); 
      
           timeGUI.guiText.text = "" + currentSavedTime; 
        } 
   } 
}

Why are you doing this:

currentSavedTime = newTime;

at the beginning of the Update function?

Oh, that was something I was testing before posting the code.
Should have taken that out…
Here is:

var timeGUI : GUIText; 
static var currentSavedTime : int; 

var newTime : int; 




function Update () 
{ 
    
    
   if(PlayerPrefs.HasKey("TimeSpent") == false) 
   { 
         print("No Stored Key."); 
         timeGUI.guiText.text = "" + currentSavedTime; 
   } 

   else if(PlayerPrefs.HasKey("TimeSpent") == true) 
   { 
      print("Key Found."); 

      newTime = PlayerPrefs.GetInt("TimeSpent"); 
        
      // current time is equal to or better than saved time 
         if (currentSavedTime >= newTime) 
         { 
            print("New Time is better."); 
          
            timeGUI.guiText.text = "" + newTime; 
            currentSavedTime = newTime; 
      
      } 
         // saved time is better 
      else if (currentSavedTime < newTime) 
         { 
            print("Saved Time is better."); 
      
           timeGUI.guiText.text = "" + currentSavedTime; 
        } 
   } 
}

Anybody? I have tried some more combinations, but still didn’t work…

What exactly do you want it to do? Then I can write an example.

It looks like, in this script, you have two times, neither of which are being set, but you’re trying to load one and compare it to the other.

Is there another script which is saving the time, or calculating the new time?

Thank you Tempest!

My game is a series of puzzle games, so I want the last scene and the main menu show the shortest time to finish, which is the best record. I have the playerprefs to store the length of time spent before moving on to the last scene, which is called “TimeSpent”. I am able to show the time stored in “TimeSpent” with no problem, but my goal is to show the best record, which I have problem with it…

Okay, correct me if I’m wrong.

You have two variables: BestTime and CurrentTime.

BestTime is the fastest time the player has completed all the puzzles.

CurrentTime is the player’s current time.

At the end of the game, you want to compare the BestTime to the CurrentTime. If their CurrentTime is better, it should be assigned to BestTime. If it is not better, then nothing should happen.

You said a series of puzzles. Does this also mean the game has a series of scenes? Or is it all in one scene?

Yes, this is what I am trying to do. Whenever the player finishes the game, the current time spent will be compared with the current best time. In my game, I have around 20 scenes before finishing. So unless the player finish the last puzzle, no record will be saved to compare with the best time. If there is no record ever, it should show “Not Completed” or 0.

If I understand PlayerPrefs (and I literally only looked for 20 seconds), you want to do this:

    if (currentTime < PlayerPrefs.GetInt("BestTime"))
    {
        PlayerPrefs.SetInt("BestTime", currentTime);
    }

Then somewhere else, when you want to print something to the GUI, just PlayerPrefs.GetInt(“BestTime”) again and use the output.

It seems to me that this is simple logic that should be separate. Deal with setting the result first. Then deal with the GUI. Always separate GUI code from main code when possible.

It seems like you should treat PlayerPrefs like a global variable. Write to it once, when there is a change, then read it as often as you need in various scenes and GUIs.

Does this help?

That does help, but still needs to revise quite a lot…
I am still trying to figure out what to do…

Here’s an idea:

In Level 1, in your Start function, put this:

PlayerPrefs.SetFloat("CurrentTime", 0);

At the end of every level, put this:

float currentTime = PlayerPrefs.GetFloat( "CurrentTime" );
currentTime = currentTime + PlayerPrefs.Time.timeSinceLevelLoad;
PlayerPrefs.SetFloat( "CurrentTime", currentTime );

At the end of the last level, put this:

float currentTime = PlayerPrefs.GetFloat( "CurrentTime" );
currentTime = currentTime + PlayerPrefs.Time.timeSinceLevelLoad;

if (currentTime < PlayerPrefs.GetFloat("BestTime") || PlayerPrefs.GetFloat("BestTime") == 0 ) 
{ 
        PlayerPrefs.SetFloat("BestTime", currentTime); 
}

This will keep track of the time it took you to complete all the levels, and then at the end, save it to BestTime if it beats the previous best time. Keep in mind that you can’t just compare BestTime and currentTime, because BestTime starts out at 0, and 0 is always less than currentTime.

So, in that final IF statement, we have a second case that checks to see if BestTime is 0, in which case currentTime IS the best Time, and should be saved in the BestTime field.

Thanks!!! I am trying to see if it works now.
Update: An error happens when I insert the code below into the end of each level, the error shows that I need to insert semicolon at the end (“float currentTime = PlayerPrefs.GetFloat( “CurrentTime” );”), which I did…
Weird…

float currentTime = PlayerPrefs.GetFloat( "CurrentTime" );
currentTime = currentTime + PlayerPrefs.Time.timeSinceLevelLoad;
PlayerPrefs.SetFloat( "CurrentTime", currentTime );

That is my fault. I gave you C#, when your script is written in JavaScript.

Try this instead:

var currentTime : float = PlayerPrefs.GetFloat( "CurrentTime" ); 
currentTime = currentTime + PlayerPrefs.Time.timeSinceLevelLoad; 
PlayerPrefs.SetFloat( "CurrentTime", currentTime );

and for the final:

var currentTime : float= PlayerPrefs.GetFloat( "CurrentTime" ); 
currentTime = currentTime + PlayerPrefs.Time.timeSinceLevelLoad; 

if (currentTime < PlayerPrefs.GetFloat("BestTime") || PlayerPrefs.GetFloat("BestTime") == 0 ) 
{ 
        PlayerPrefs.SetFloat("BestTime", currentTime); 
}

Great thanks,
But still an error shows that “Time” is not a member of UnityEngine.PlayerPrefs
with (“PlayerPrefs.Time.timeSinceLevelLoad;”)