Search Unity

PlayerPrefs Management system

Discussion in 'Scripting' started by User340, Jun 8, 2014.

  1. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    We all know that PlayerPrefs can at times be annoying to deal with directly. Problems include spelling keys differently in different places and inconsistent default values to name a few.

    Thus I've come up with a decent system for managing PlayerPrefs, and it works like this. You make a static class, called Prefs, and expose PlayerPrefs Get/Set methods via static properties. This class is the sole class that communicates with PlayerPrefs. All other classes go through Prefs in order to read/write from PlayerPrefs. It offers many advantages including:

    1) Allows consistent default value for all prefs.
    2) Eliminates the risk of misspelling a pref key.
    3) Allows you to document the intent/purpose of each pref.
    4) Allows you to easily increment an int for example via Prefs.LastScore += 10
    5) Allows you to make a pref of any type (bool for example), by doing all the conversion inside of Prefs.

    Here's a sample code:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public static class Prefs
    5. {
    6.    // Static constructor useful for version checking
    7.    static Prefs()
    8.    {
    9.       if (Version != "1.5")
    10.       {
    11.          // Invoke upgrade process if necessary.
    12.       }
    13.    }
    14.  
    15.    ///<summary>
    16.    /// Gets the version.
    17.    ///</summary>
    18.    ///<value>Theversion.</value>
    19.    public static string Version
    20.    {
    21.       get { returnPlayerPrefs.GetString("version", "1.0"); }
    22.    }
    23.  
    24.    ///<summary>
    25.    /// The score of the most recently played game. Insert more descriptive info here.
    26.    ///</summary>
    27.    public static int LastScore
    28.    {
    29.       get { return PlayerPrefs.GetInt("last score", 0); }
    30.       set { PlayerPrefs.SetInt("last score", value); }
    31.    }
    32.  
    33.    ///<summary>
    34.    /// Prefs allows any type to become a pref key, and is not limited to the basic
    35.    /// int, float, and string types.
    36.    ///</summary>
    37.    public static bool MusicEnabled
    38.    {
    39.       get { return PlayerPrefs.GetInt("music enabled", 1) != 0; }
    40.       set { PlayerPrefs.SetInt("music enabled", value != 0); }
    41.    }
    42.  
    43. }
    Then the rest of your code does very little work to read, write, and modify PlayerPrefs.

    Code (csharp):
    1. void OnTriggerEnter()
    2. {
    3.    Prefs.LastScore = 250;
    4. }
    5. void OnMusicButton()
    6. {
    7.    Prefs.MusicEnabled = !Prefs.MusicEnabled;
    8. }
    I've shipped many games with this system and it's really works great.
     
    raviraj_vdy likes this.
  2. yzaroui

    yzaroui

    Joined:
    Nov 23, 2014
    Posts:
    24
    User340 likes this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Personally, I always change this...

    Code (csharp):
    1.    public static int LastScore
    2.    {
    3.       get { return PlayerPrefs.GetInt("last score", 0); }
    4.       set { PlayerPrefs.SetInt("last score", value); }
    5.    }
    to this:

    Code (csharp):
    1.    private const string s_LastScore = "last score";
    2.    public static int LastScore
    3.    {
    4.       get { return PlayerPrefs.GetInt(s_LastScore, 0); }
    5.       set { PlayerPrefs.SetInt(s_LastScore, value); }
    6.    }
    Otherwise you STILL have the "I mistyped the string one time" problem. You just moved it somewhere else. This eliminates it.

    (Wow, sorry, didn't notice this was a necro post... my bad)
     
    User340 likes this.
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Since it has been necro'd. :)

    I tend to save in to parts. The data class just serialise a regular class, and turn the resulting data into a string. The save class dumps the string into player prefs, or a server, or a file.

    This way the set up is pretty system agnostic. The data class doesn't care how the data is saved. The save class doesn't care how the data is used or generated.
     
    User340 likes this.