Search Unity

lists and player prefs adding more than one entry

Discussion in 'Scripting' started by PvTGreg, Sep 23, 2014.

  1. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    Hi im looking for a way to add an entry to the list when the player finishes the game i cant get head around it can i have some help please here is the main script for creating and storing the list in player prefs

    i use this currently
    Code (CSharp):
    1. Times.Add(newTimeEntry{ name ="Time", time =PlayerPrefs.GetInt("Time")});
    to set the times but it is only one entry id like to use something like this to set the times when the player finishes the level
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using System.Linq;
    3. using UnityEngine;
    4. using System.Collections;
    5. //You must include these namespaces
    6. //to use BinaryFormatter
    7. using System;
    8. using System.Runtime.Serialization.Formatters.Binary;
    9. using System.IO;
    10.  
    11. public class HighScores : MonoBehaviour {
    12.     //High score entry
    13.     public class TimeEntry
    14.     {
    15.         //Players name
    16.         public string name;
    17.         //Score
    18.         public int time;
    19.     }
    20.    
    21.     //High score table
    22.     public List<TimeEntry> Times = new List<TimeEntry>();
    23.    
    24.     void SaveTimes()
    25.     {
    26.         //Get a binary formatter
    27.         var b = new BinaryFormatter();
    28.         //Create an in memory stream
    29.         var m = new MemoryStream();
    30.         //Save the scores
    31.         b.Serialize(m, Times);
    32.         //Add it to player prefs
    33.         PlayerPrefs.SetString("Times",Convert.ToBase64String(m.GetBuffer()) );
    34.                    
    35.     }
    36.    
    37.     void Start()
    38.     {
    39.  
    40.         Times.Add(new TimeEntry { name = "Time", time = PlayerPrefs.GetInt("Time") });
    41.         //Get the data
    42.         var data = PlayerPrefs.GetString("Times");
    43.         //If not blank then load it
    44.         if(!string.IsNullOrEmpty(data))
    45.         {
    46.             //Binary formatter for loading back
    47.             var b = new BinaryFormatter();
    48.             //Create a memory stream with the data
    49.             var m = new MemoryStream(Convert.FromBase64String(data));
    50.             //Load back the scores
    51.             Times = (List<TimeEntry>)b.Deserialize(m);
    52.         }
    53.     }
    54.  
    55.     void OnGUI()
    56.     {
    57.  
    58.         foreach(var time in Times)
    59.         {  
    60.              
    61.             GUILayout.Label(string.Format("{0} : {1:#,0}",   time.name, time.time));                      
    62.         }
    63.  
    64.     }
    65.    
    66. }
    and this is the next level script where the name and time will be set
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.   using System.Collections.Generic;
    4. public class NextLevel : MonoBehaviour {
    5.     public int LevelName;
    6.     public bool SetTime;
    7.     // Use this for initialization
    8.  
    9.  
    10.  
    11.  
    12.  
    13.  
    14.  
    15.     void OnTriggerEnter2D(Collider2D col)
    16.     {
    17.    
    18.         if (col.tag == "NextLevel")
    19.         {
    20.             if (SetTime == true)
    21.             {  
    22.  
    23.             }
    24.             Application.LoadLevel (LevelName);
    25.         }
    26.     }
    27.  
    28.  
    29. }
    30.  
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Sorry, I don't understand your question. You can call SetInt and GetInt on PlayerPrefs as many times as you like, using different keys to store different bits of data. What exactly is the problem you're having?
     
  3. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    my question is how do i add an entry to the list when the user completes the level
    i would use this to add an enty
    Code (CSharp):
    1. Times.Add(newTimeEntry{ name ="Time", time =PlayerPrefs.GetInt("Time")});

    but how do i get to use that in the next level script
     
  4. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    also ignore the binarry formater bit and the player prefs that isnt needed for what i need to do
     
  5. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    i would think this would work but it does not

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.   using System.Collections.Generic;
    4. public class NextLevel : MonoBehaviour {
    5.     public int LevelName;
    6.     public bool SetTime;
    7.     HighScores time;
    8.     // Use this for initialization
    9.  
    10.  
    11.  
    12.  
    13.     void Start()
    14.     {
    15.         time = GetComponent<HighScores>();
    16.     }
    17.    
    18.  
    19.     void OnTriggerEnter2D(Collider2D col)
    20.     {
    21.        
    22.         if (col.tag == "NextLevel")
    23.         {
    24.             if (SetTime == true)
    25.             {  
    26.                 time.Times.Add(new TimeEntry { name = "Time", time = PlayerPrefs.GetInt("Time") });
    27.             }
    28.             Application.LoadLevel (LevelName);
    29.         }
    30.     }
    31.  
    32.  
    33. }
    34.  
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I can see that that code wouldn't work — you're assigning an integer (the result of PlayerPrefs.GetInt) to an object of type HighScores (your time property). This couldn't possibly work unless you have an implicit conversion operator in your HighScores class, which seems very unlikely.

    What I can't quite see is what you're intending this to do. You're pulling a "Time" integer out of the prefs, creating a TimeEntry for it, stuffing this into time.Times (which I presume is a List<TimeEntry>)... and then throwing all that out and calling Application.LoadLevel. (I'm assuming here that you haven't called DontDestroyOnLoad on this object.)

    Taking a wild stab, I'm going to guess that what you intended to do here was to store (rather than retrieve) the value of Time in the prefs, and then load the next level, and in some script that runs at the start of the next level, pull that value back out.

    First, let me say that if the only reason you're doing this is to get the value from one level to another, you're working too hard; there are much easier (and more efficient) ways to do this than using PlayerPrefs.

    But, in case you also want these values stored between levels in case the game crashes or the player quits or whatever, then...
    1. In the script that runs at the end of this level, you want to set the value, like so:
      Code (CSharp):
      1. PlayerPrefs.SetInt("Time", currentTime);
    2. In some script that runs at the start of the next level, you should pull the value back out:
      Code (CSharp):
      1. currentTime = PlayerPrefs.GetInt("Time");
    Hope this helps,
    - Joe
     
  7. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.IO;
    4. using System;
    5. public class Score : MonoBehaviour {
    6.    
    7.     public int Time;
    8.  
    9.    
    10.    
    11.     void Start ()
    12.     {  
    13.         Time = PlayerPrefs.GetInt("Time");
    14.         InvokeRepeating("Points", 2, 0.3F);
    15.     }
    16.    
    17.    
    18.     // Update is called once per frame
    19.     void Points ()
    20.     {
    21.         Time += 1;
    22.         PlayerPrefs.SetInt("Time",Time);
    23.  
    24.     }
    25.  
    26.     void OnGUI()
    27.     {
    28.         Time = PlayerPrefs.GetInt("Time");
    29.         GUI.Box(new Rect(200,10,100,30),"Time:"+Time.ToString());
    30.  
    31.     }
    32. }
    33.  

    this is the script that puts time into player prefs and highscore is only going to be displayed in the main menu but the script will be on all scenes running in the background just to make sure it is getting the correct times as i will eventulay chnage it to store the times for each level then display it but atm i am just making it take the time it took the player to complete the 3 levels and at the end of the game the next level bool is ticked and it then adds the time to the list as well as the players name which is just "time" for testing atm then in the highscore script in t he ongui part i will put a bool that if ticked displays the contents of the list
     
  8. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    and the only reason i save the list in player prefs is so that i can pass the part in my adv higher computing project as it requiers me to save it to a file i will probaly later change it from player prefs to a txt document but that is for later