Menu

Writing PlayerPrefs, Fast

Another way of saving data in Unity3D in a platform-independent way is to use the PlayerPrefs class.

This class works like a hash table, allowing you to store key-value pairs.

The disadvantage of the built-in PlayerPrefs class is that it’s really slow on iOS and even slower on Android. During a test we did on a Google Nexus One, we saved only 6.25 key-value pairs per second. Because we were trying to save over 300 records, this took way too long. Most likely, they are doing file I/O operations for every modification. The current PlayerPrefs class is clearly not designed to handle a larger amount of data.

So we decided to implement our own version of the PlayerPrefs class, allowing faster saving of tuning parameters in our prototypes. Now we’re saving 300+ records almost instantly on on the same device.

If you’re already using the Unity PlayerPrefs class in your project, and you’re looking for an optimization on iOS and Android devices, you can do the following:

  • Download our PlayerPrefs.cs file and add it to your project.
  • Add the following line at the beginning of the files in which PlayerPrefs is used:
    using PlayerPrefs = PreviewLabs.PlayerPrefs;
    
  • Use PlayerPrefs.Flush() to save all values. This can be done after writing a bunch of data, or when the application is quit (in your main game class):
    public void OnApplicationQuit()
    {
    	PlayerPrefs.Flush();
    }
    

To obtain this optimization, we’re keeping a Hashtable and only writing it to a file when Flush() is called.
We’re deliberately not using an XML format to do this, as this would create an overhead unwanted on these lower-end devices.

Changelog

  • March 11, 2011: Original article was posted
  • April 1, 2014: An article was written, comparing the performance of the PreviewLabs PlayerPrefs with the Unity PlayerPrefs. Read it here.
  • April 1, 2014: A major update to the source code was made.
  • April 11, 2014: Bug fixes.

Downloads

90 thoughts on “Writing PlayerPrefs, Fast”

  1. masashi wada says:

    Hi , nice work and nice code.

    I found the problem on which the PlayerPrefs does not operate by android.
    And I found your great code by the forum.

    However, your code also hit the one problem.
    InvalidCastException occurred in GetInt() after Deserialize().

    In Deserialize(), this had added values to the string type hash table.

    thanks.

  2. JakeL168 says:

    Hey, I downloaded your code, and unity get an error saying: “‘UnityEngine.Application’ does not contain a definition for ‘persistentDataPath'” at line 28

  3. JakeL168 says:

    problem solved… thanks for the code… Can I really use it for free?

  4. The code is really for free. It has been released in the public domain and thus freed from copyright.
    You can use it in any way you want!

    The persistentDataPath member may not be available or working correctly for Unity versions prior to 3.3. Make sure you update your Unity version, or modify the code so it uses the correct file path. More explanation can be read in this blog post.

    Also, please note that this code will not work for the web version. If you’re working on a game that should run both in the web player and on other platforms, you’ll have to use the following code in the beginning of the files where you want to use PlayerPrefs:

    #if !UNITY_WEBPLAYER
        using PlayerPrefs = PreviewLabs.PlayerPrefs;
    #endif
    
  5. Richard says:

    Is there anyway I can call the CS script from my js files. I only use js.

  6. Richard, to use this in JavaScript you have to put the PlayerPrefs.cs file in a folder named ‘Plugins’ in the Assets folder (you may have to create this). Then, in the beginning of your files using PlayerPrefs you have to put the following:

    import PreviewLabs.PlayerPrefs;
    

    You’ll also have to modify the code so you’re making calls to PreviewLabs.PlayerPrefs instead of PlayerPrefs.

  7. An updated PlayerPrefs.cs file has been uploaded.

    @masashi: This should fix the issue you encountered.

  8. masashi wada says:

    Hi Bernard!
    Thanks for sounds good message.

    Your new code worked by android devices.
    I thank your work and wish to use for my products.

  9. JJ says:

    Very cool, great to see someone take this on.

    I am a bit confused as to where the file is stored. I looked in the regular player prefs location on my Mac and the only file I have there for my game has no keys beyond Graphics Quality. Any hints?

  10. JJ, the player prefs of this class are stored on the following location:

    Application.persistentDataPath + "/PlayerPrefs.txt"

    If you add the following line in your code (e.g. in a Start() method), you’ll now where it is exactly, regardless of the platform you’re running it on:

    Debug.Log(Application.persistentDataPath + "/PlayerPrefs.txt");
  11. Burlak says:

    Thanks for the great code.
    But it seems that when you update the application on Android stored data is lost.

    1. Thanks, Burlak. What do you mean exactly by ‘when you update the application on Android’?

  12. rain rain says:

    how do i implement it into my scene?

  13. @rain rain: You’ll have to add it to the Assets folder of your project. To use it, you need to call the script from your source code. Please note that this only makes sense if you’re already using (or intending to use) the PlayerPrefs class – as the PreviewLabs.PlayerPrefs class is a faster version replacing it. If you’re not using PlayerPrefs to store data, there will be no optimization.

  14. Lexxx says:

    Great! Thanks a lot!
    It works on iPhone/iPod ?

    1. Yes, it does work on iOS and is actually a lot faster than the built-in PlayerPrefs – especially when storing a lot of data.

  15. Sebastian says:

    Peeerfect!
    For hours I thought I had a problem with my code, but then I tried this and found out it was just a bug with Unity’s PlayerPrefs >_< Thanks a bunch 🙂

  16. Clark says:

    Just wanted to note, we had an issue with this where the Deserialize() function might crash the game on iOS/Android devices if the PlayerPrefs file exists, but doesn’t have anything in it. We made the following changes to make it safer:

    if(serializedInput != null)
    {
    string[] parameters = serializedInput.Split(new string[] {” ” + PARAMETERS_SEPERATOR + ” “}, StringSplitOptions.None);

    foreach(string parameter in parameters)
    {
    string[] parameterContent = parameter.Split(new string[]{” ” + KEY_VALUE_SEPERATOR + ” “}, StringSplitOptions.None);

    if(parameterContent.Length == 3)
    {
    playerPrefsHashtable.Add(DeEscapeNonSeperators(parameterContent[0]), GetTypeValue(parameterContent[2], DeEscapeNonSeperators(parameterContent[1])));
    }
    else
    {
    Debug.LogWarning(“PlayerPrefs::Deserialize() parameterContent has ” + parameterContent.Length + ” elements”);
    }
    }
    }

  17. Joshery says:

    May need to add the following to the DeleteAll() function if you haven’t changed anything else in the hash table:

    hashTableChanged = true;

    Also, need to call Flush() after calling DeleteAll()

  18. andrei says:

    Hello! Thank you for the code, I extended your class with a simple auto flusher. I use SetString a lot and wanted to autoflush. Here it is:

    private const int AUTO_FLUSH_NUMBER_SETS = 20;
    private static int _autoFlushCounter = AUTO_FLUSH_NUMBER_SETS;

    public static void SetString(string key, string value)
    {
    if(!playerPrefsHashtable.ContainsKey(key))
    {
    playerPrefsHashtable.Add(key, value);
    }
    else
    {
    playerPrefsHashtable[key] = value;
    }

    hashTableChanged = true;
    _autoFlushCounter–;
    if(_autoFlushCounter <= 0)
    {
    _autoFlushCounter = AUTO_FLUSH_NUMBER_SETS;
    Flush();
    }
    }

    Cheers!

  19. Renman3000 says:

    Does this work in JS?

    1. I didn’t test this myself, but I don’t see a reason why it wouldn’t…

  20. Charles Lavigne says:

    Quick question.

    After written to a player pref, is it immediately retrievable? Or is a flush required first?

    1. Charles: no, a flush is only required to ensure that the data is stored on the device and won’t be lost if the game is closed and restarted.

  21. Jonathan B says:

    Hi,
    Thx for this great plugin. 🙂
    I need to know how save an Multi Array Data in Javascript plz.
    I’m a newbie in Unity, i tried to Join an Array and save it like a String but it doesn’t work for Multidimensionnal Array like that :

    ** code **********************
    var fruits = new Array();

    var red_fruits = new Array[2];
    red_fruits[0] = “Strawberry”;
    red_fruits[1] = “Cherry”;
    red_fruits[2] = “Raspberry”;

    fruits.Push(red_fruits);
    fruits.Push(red_fruits);

    fruits.join(“|”); // Not really the best :/
    *******************************

    Have you an issue for that, a better technique or a function wich convert/unconvert a multi array into String (Javascript) ?

    Thx for your help.
    Cheers.

    1. Jonathan, you could use an existing solution like ArrayPrefs2 and modify it slightly to work with the PreviewLabs.PlayerPrefs (don’t forget to flush). This doesn’t support twodimensional arrays, but you could save this as multiple one-dimensional arrays.

  22. Jonathan B says:

    I have added 2 functions in the code “SetStringArray()” and “GetStringArray()” :

    public static void SetStringArray(string key, string[] arr, string sep)
    {
    if(!playerPrefsHashtable.ContainsKey(key))
    {
    playerPrefsHashtable.Add(key, String.Join(sep.ToString(), arr));
    }else{
    playerPrefsHashtable[key] = String.Join(sep.ToString(), arr);
    }
    hashTableChanged = true;
    }

    public static string[] GetStringArray(string key, string sep)
    {
    if(playerPrefsHashtable.ContainsKey(key))
    return GetString(key).Split(sep[0]);
    return new string[0];
    }

    ****************************** Use in Javascript ***********************************

    var arr = new String[3];
    arr[0] = “apple”;
    arr[1] = “cherry”;
    arr[2] = “banana”;

    PreviewLabs.PlayerPrefs.SetStringArray(“ArrayData”, arr, “|”);

    PreviewLabs.PlayerPrefs.Flush();

    var return_arr = PreviewLabs.PlayerPrefs.GetStringArray(“ArrayData”, “|”);

    for(var value in return_arr)
    {
    Debug.Log(value);
    }
    ************************************************************************************

    I’m too newbie too make that with String[,] with multiple levels and a recursive function. I’m searching…
    If you have the solution thx for your help.

    Good day.

  23. Thanks for sharing, Jonathan.

    In the mean time, it seems like the performance issues may have been fixed in Unity’s built-in PlayerPrefs class. We’ll do a performance test and post some findings here soon.
    More on this can also be read in the Unity forums, in this thread.

  24. Hello guys, I found the PlayerPrefs pretty useful, but eventually ran into a performance problem with it. The Serialize function is using wayyy to many string concatenation if you have a sizeable amount of data. So here is a version with a StringBuilder. Storing 120k of data went from 1.4s to 0.02s on computer and 10 sec to 0.4s on Nook.

    private static void Serialize()
    {
    IDictionaryEnumerator myEnumerator = playerPrefsHashtable.GetEnumerator();
    System.Text.StringBuilder builder = new System.Text.StringBuilder(null, 1000000);
    string space = ” “;
    string head = ” ” + PARAMETERS_SEPERATOR + ” “;
    string valsep = ” ” + KEY_VALUE_SEPERATOR + ” “;
    while ( myEnumerator.MoveNext() )
    {
    // if(serializedOutput != “”)
    if(builder.Length != 0)
    {
    // serializedOutput += ” ” + PARAMETERS_SEPERATOR + ” “;
    builder.Append(head);
    }
    // serializedOutput += EscapeNonSeperators(myEnumerator.Key.ToString()) + ” ” + KEY_VALUE_SEPERATOR + ” ” + EscapeNonSeperators(myEnumerator.Value.ToString()) + ” ” + KEY_VALUE_SEPERATOR + ” ” + myEnumerator.Value.GetType();
    builder.Append(EscapeNonSeperators(myEnumerator.Key.ToString()));
    builder.Append(valsep);
    builder.Append(EscapeNonSeperators(myEnumerator.Value.ToString()));
    builder.Append(valsep);
    builder.Append(myEnumerator.Value.GetType());
    }

  25. Daniel says:

    My current Unity version wasn’t accepting a call to:

    fileWriter = File.CreateText(fileName);

    for whatever reason, so I had to change if for the equivalent:

    fileWriter = new StreamWriter(fileName,false);

    Thanks for sharing this class, and thanks to everyone else who shared additional improvements!

  26. Guy says:

    Using a stringBuilder is a good idea (see code provided above by Alain-Daniel Bourdages ).
    Please notice there is missing code there that should be added to the bottom of the Serialize function in order to actually use the stringBuilder:

    serializedOutput = builder.ToString();

  27. Royce says:

    I was trying to use playerPrefs to track achievements and ran into the same problem, your script has stopped that but I have a question. When I use playerPrefs in two separate scripts on two separate objects will they both see the same value? Do I need to Flush on one script in order for the other script to see the values? I have the player object updating a total distance to playerPref under “totalDistance”. Then another script will check if total distance has passed a certain value and award an achievement to the player. This worked before but has stopped since adding your script.

  28. Jason T says:

    This is a nice script, thanks so much for sharing.

    I’m having the same trouble as Royce. If I set a value with one script, but then change it with another the original value gets set after I Flush. Is there something I am doing wrong?

  29. Pétur says:

    Hello.
    Where do I find the file on the Android device?
    Btw. thanks for the code, it really helps 🙂

  30. @Pétur

    The path used to save the PlayerPrefs is Application.persistentDataPath + "/PlayerPrefs.txt". You could show the content of Application.persistentDataPath on your screen if you want to know its precise location for your game.

    According to this post on Unity Answers, it depends on whether ‘write access’ in Player Settings is set to use an external SD card or not. If it is, a path under /mnt/android/data/is used. If it isn’t, it can be found under /data/data/com.mycompany.myapp/files.

  31. @Royce, Jason T
    There should be no problems accessing PlayerPrefs from different scripts, as all data is kept as static. Meanwhile, have you been able to pinpoint the problem?
    Are you sure you’re using the PreviewLabs PlayerPrefs in both files and not mixing usage of our PlayerPrefs and Unity’s PlayerPrefs? Because not using the same PlayerPrefs class in the different scripts could result in the behavior you’re both describing.
    Note that you have to use the using PlayerPrefs = PreviewLabs.PlayerPrefs; at the top of every file where you’re using PlayerPrefs.

  32. Bawenang says:

    Hi, I stumbled on your blog here when I was searching for PlayerPrefs and persistentDataPath on Google. It looks like a pretty good solution. Haven’t tested it yet though. i just want to elaborate on one of the comments above.

    Burlak said:
    Jul 09, 11 at 4:01 pm

    Thanks for the great code.
    But it seems that when you update the application on Android stored data is lost.

    What he meant was on Android 2.2, if we update our app, everything in the app’s external storage directory will be deleted. And that includes our data, if they were written on external rather than internal. Not a Unity 3D’s or this library’s fault anyway. Just FYI.

  33. Zane Arn says:

    Thanks for sharing! It would be hard for indie developer like me to develop anything without the help from people like you.

  34. Lenn Dolling says:

    sweet stuff. I will integrate it into my upcoming game.

  35. @Zane Arn, Lenn Dolling: Nice to hear that – thanks for the kind words!

  36. Kay says:

    Hi,

    I used your PlayerPrefs for quite a long time on iOS – very nice 🙂 Last year I made some changes to get the keys sorted by name and separated by carriage returns. Furthermore migration from old format is detected and performed automatically.

    Thus if there are more than a few keys in the project it is very convenient for testing. Drop me short note if you are interested in the changes. Or even better: What do you think about putting the code in a public repository on GitHub?

  37. Kcal says:

    Anyone heard of Apple rejecting an app for using this script? Just want to make sure.

  38. I haven’t heard of it, but I did hear about multiple launched games using this. Including all games done by Crazy Monkey Studios.

    Meanwhile, we’re having a look at the performance of our PlayerPrefs implementation and have found that it dramatically outperforms Unity’s built-in implementation when it comes to saving a lot of values. This article will be updated soon, with a separate article in the works showing the performance differences in graphs.

  39. Kcal says:

    Ok sounds good. How susceptible to hacking high scores, etc is a game by storing the data as this does?

  40. Victor says:

    So, do you just use PlayerPrefs.SetInt(key, value) as you usually would and your PlayerPrefs script overwrites the normal one?

    Thank you so much, this is such a valuable resource you’re sharing. 🙂

  41. Palash Bhowmick says:

    Hi…thnx a lot for your code. I’m having an error message ‘The type or namespace name ‘PreviewLabs’ could not be found. Are you missing a using directive or an assembly reference?’ Cant get what mistake i’ve done. I’m a student & trying to use your code in my project. Followed all the methods you described, still getting error. Feeling helpless. Please help. Thanks in advance…

  42. Palash Bhowmick says:

    Got it fixed…That was a mistake from me…Just one thing to ask, is it safe to save the game states and specially power-ups and coins through this script? I mean, would it be easily editable by users? I need to confirm to ensure the security of the game. And a lot of thnx again for this beautiful code…:)

  43. @Victor: That’s right: you can continue to use the PlayerPrefs class as usually when using our implementation.

    @Kcal, Palash: It’s very easy to modify PlayerPrefs values on desktop platforms. On mobile, it’s slightly more difficult. We do have an implementation which uses encryption and makes this much more difficult. I’ll share this shortly.

  44. I’ve shared our most recent PlayerPrefs version, containing the encryption. This encryption system offers additional security against modifying values and copying over the PlayerPrefs file to a different device. We highly recommend using this in games that rely on in-app purchases where you’re saving amounts of owned items in the PlayerPrefs class. Note that you should modify the encryption key in the PlayerPrefs.cs file to a random string only you are using.

  45. Vulder says:

    Hello Bernard, nice work.
    I’ve downloaded the last version but I can’t make it work because I need the Algorithms file

    Greets

  46. Kai Molan says:

    I second Vulder’s claim, and would like to point out the error on line 260:

    public statis void EnableEncryption(bool enabled)
    securityModeEnabled = enabled;
    }

    Needs to be changed to:
    public static void EnableEncryption(bool enabled)
    {
    securityModeEnabled = enabled;
    }

  47. Patrick says:

    I have been using this script for months..working great..until today..I used DeleteAll()…Now my whole pref system is broke, and after 2 hours of trying to figure out what is really going on, I have to go back to unity’s version..IndexOutOfRangeException: Array index is out of range.
    PreviewLabs.PlayerPrefs.Deserialize () (at Assets/AirStrike/Scripts/Componet/PlayerPrefs.cs:265)

    here–PlayerPrefs Line:265—->if (parameterContent.Length > 3)

    failing on this first call–>if if(PlayerPrefs.HasKey(“LevelCompleted”))

    So How Can DeleteAll(), completely break your code, can not even use the new version, looked for Algorithims for an hour..

    please help…hate to go back..

    p-

  48. Patrick says:

    I think I fixed my problem…I just changed the name of the file, and if that does not exist, I had it create a new one..

    private static readonly string fileName = Application.persistentDataPath + “/PlayPrefs.txt”;

    static PlayerPrefs()
    {
    //load previous settings
    StreamReader fileReader = null;

    if (File.Exists(fileName))
    {
    Debug.LogWarning(“opening file for writing!!!!: ” + fileName);
    fileReader = new StreamReader(fileName);
    serializedInput = fileReader.ReadLine();
    Deserialize();
    fileReader.Close();
    }
    else
    {
    Debug.LogWarning(“opening file for writing FAILED: ” + fileName);
    Serialize();

    StreamWriter fileWriter = null;
    fileWriter = File.CreateText(fileName);

    if (fileWriter == null)
    {
    Debug.LogWarning(“PlayerPrefs::Flush() opening file for writing failed: ” + fileName);
    }

    fileWriter.WriteLine(serializedOutput);
    fileWriter.Close();
    serializedOutput = “”;
    }

  49. @Kai, Vulder: Thanks for pointing out. I’ll get this fixed asap and comment on it here.
    You can have a look again in 24 hours.

  50. These issues are fixed. You can now use the most recent version (April 11, 2014 version).

  51. Thanks I really thought I was losing my mind….This is such a great altruistic effort, I just hate to complain, I appreciate your efforts very much!! Thank You!!! – Patrick

  52. Comments like this definitely make it worth while! And we do get a lot from the Unity community, so giving something back definitely feels good!

  53. Patrick says:

    Just a quick question about the new version, I went back to the original name, PlayerPrefs.txt. I realized by changing that file name, all my existing (7,000+)players, will lose all the levels that they unlocked..not good. It works!!! but I keep getting this error message ‘SUCCEEDED(hr)’..UnityEngine.SystemInfo:get_deviceUniqueIdentifier()PreviewLabs.PlayerPrefs:.cctor()

    and it is firing here:

    MissionManager:Awake() (at Assets/AirStrike/Scripts/Player/MissionManager.cs:55)
    MissionManager:Awake() (at Assets/AirStrike/Scripts/Player/MissionManager.cs:50)

    line 50: if (PlayerPrefs.HasKey(“LevelVolume”))
    audio.volume = PlayerPrefs.GetFloat(“LevelVolume”);

    line 55 is the closing bracket..weird…

    maby the first time I call it?..I set that key yesterday, no problems..today..this. Does not repeat..no effect on game, looks like a one time deal..should I worry about this?

    Just curious..

    Patrick

  54. Kai Molan says:

    I only got back to checking it out today(got distracted with other parts of my project lol). Thanks for the fixes and this class, much appreciation.

  55. @Patrick: If this only occurred once, and only after starting to use the new version of PlayerPrefs, I wouldn’t worry about it.

    @Kai: You’re welcome. Glad you’re appreciating it!

  56. Patrick says:

    Thanx…happened again today..so ‘SUCCEEDED(hr)’ is not part of your debug messages, ctor(), is mono compile error, throwing syntax error on the return value of PlayerPrefs.HasKey(“LevelVolume”), I think succeed is is reference to ‘Stepping through that line w/o fail…so on the closing bracket, it will fire again, reapeating the process…I have not tested the reurn value of that call [PlayerPrefs.HasKey], but that is where some other character type is being inserted?? yet..but FYI

  57. Patrick says:

    well, I was wrong…It happens every time I launch unity editor for the first time, I have a bad PlayerPrefs.txt File…That is the only explanation…When I called DeleteAll() [ealier problem], that corrupted my player pref file..can you give me a clue, exactly where that file is stored? on my PC..I looked, searched, hidden files, printed the path..no luck..there is an extra Start or closing Bracket in those old keys..and when it returns that value + bracket, it errors, steps through, hits the close bracket of the function..errors again..because, that key Does Exist, and it returns a float with a bracket/or character, something other than the intended variable type..

  58. Patrick says:

    So I dumped my PlayerPref.txt, brand new/empty..and it still happens..everytime I first run my game..when a PlayerPrefs.txt file does not exist..very, very strange..

  59. Hi Patrick, I’ve sent you an email to get some specific information about the issue you’re encountering, so we can have a closer look and post the solution for everyone here.

  60. Enrico Trudu says:

    Hello Patrick, thanks for your code.

    I’m using your lib on a game with Android and Windows Phone 8.
    I have an issue on WP8.
    The building of the project ends without errors.
    When I try to upload the build to the phone, I get:

    Error building Player: Exception: Error: method `System.Text.Encoding System.Text.Encoding::get_ASCII()` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.Void PreviewLabs.PlayerPrefs::.cctor().
    Error: type `System.Security.Cryptography.DESCryptoServiceProvider` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Encrypt(System.String).
    Error: type `System.Security.Cryptography.DESCryptoServiceProvider` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Encrypt(System.String).
    Error: method `System.Void System.Security.Cryptography.DESCryptoServiceProvider::.ctor()` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Encrypt(System.String).
    Error: type `System.Security.Cryptography.DESCryptoServiceProvider` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Encrypt(System.String).
    Error: method `System.Security.Cryptography.ICryptoTransform System.Security.Cryptography.DESCryptoServiceProvider::CreateEncryptor(System.Byte[],System.Byte[])` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Encrypt(System.String).
    Error: type `System.Security.Cryptography.DESCryptoServiceProvider` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Decrypt(System.String).
    Error: type `System.Security.Cryptography.DESCryptoServiceProvider` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Decrypt(System.String).
    Error: method `System.Void System.Security.Cryptography.DESCryptoServiceProvider::.ctor()` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Decrypt(System.String).
    Error: type `System.Security.Cryptography.DESCryptoServiceProvider` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Decrypt(System.String).
    Error: method `System.Security.Cryptography.ICryptoTransform System.Security.Cryptography.DESCryptoServiceProvider::CreateDecryptor(System.Byte[],System.Byte[])` doesn’t exist in target framework. It is referenced from Assembly-CSharp.dll at System.String PreviewLabs.PlayerPrefs::Decrypt(System.String).

    On the other platforms works and builds ok.
    Do you have any tips?

    Thanks a lot, in advice.

    Enrico

  61. Enrico Trudu says:

    …I apologize for the lenght of the code. -.-

  62. Ej!4h says:

    It’s not support WP8

  63. Elvis says:

    Hello PreviewLabs!
    First, thanks for this magic code, I’ve been using it any time I need to save something on mobile, I won’t spam you here with our apps that use it, so let’s go directly to my problem.
    I want to know if the Flush method could be IEnumerator or similar to tell me when it is done flushing. You see we use it to loadasync a new level and I got the impression that sometimes It doesn’t have time to flush, I thought to use a while loop checking for the moment where “hashTableChanged” get false again or something like that, but maybe there is a “doneWithWritingOnFile” callback.
    Well, thanks again for all and please forget and forgive my english, I’m italian 😉

  64. James says:

    Hi Bernard,
    I’m trying to use your kind codes to write/store player data into playerprefs.

    So after player has exited the game/apps, and re-launch the game/apps next time, how to check if the PlayerPrefs file/data is exists ?
    – if there is already data exists, to load the player data and continue for next step ;
    – if there is no Playerprefs/data exist, the proceed to load the next step/scene/whatever.

    Thanks for your kind helps.
    James

  65. Dion says:

    Hi Bernard. I am having the exact same problem as Patrick. If I DeleteAll() it seems to corrupt my PlayerPrefs file, as I get an error (pasted below) the next time I use HasKey().

    IndexOutOfRangeException: Array index is out of range.
    at PreviewLabs.PlayerPrefs.Deserialize () [0x00000] in :0
    at PreviewLabs.PlayerPrefs..cctor () [0x00000] in :0
    Rethrow as TypeInitializationException: An exception was thrown by the type initializer for PreviewLabs.PlayerPrefs

    However, if I replace DeleteAll() with a series of DeleteKey() all is fine.

  66. Dion says:

    Hmm, I was a bit hasty with my previous comment that “all is fine” with DeleteKey(), as I inadvertently compiled a build that didn’t call the delete routine!

    Unfortunately if I delete all keys manually (with DeleteKey()) then I get the same error as above when I next try to use HasKey().

    Next up I’ll try using Unity’s default PlayerPrefs class. I only have 5 keys, so speed isn’t really an issue, so long as it works!

  67. Kazuhiko says:

    Im getting error on playerprefs,when calling playerprefs.flush..i used it many times and this time when saving a time im getting an error on line 313..which is on Serialize method..it says on the console null reference but i checked all values and it is all correct..im stuck with this error,what could be the reason for this?

  68. Ronny says:

    The download link for the PlayerPrefs.cs file don’t work anymore. Maybe you could upload it to Github or Bitbucket or something?

    1. Bernard says:

      Thanks for letting me know. This is due to our recent website update. I’ll fix it within the next couple of hours.

  69. Edgar Drake says:

    I stumbled upon this website and I want to try this class.. How can I download this? Thank you.

    1. Bernard says:

      It’s temporarily unavailable due to our recent website migration but will be online again if you check again in about 2 hours.

      1. Bernard says:

        PlayerPrefs files are available again now.

  70. MIC UNITY says:

    Please can you make a video tutorial on using this to save player position.

  71. UnityGuy says:

    Am little confused here.so how do you Encrypt a value?

    1. Bernard says:

      Encryption happens automatically. Nothing special to do. Just use the file and don’t forget to replace the encryption key in the .cs file by another arbitrary 4 character string (see //NOTE comment line in the source).

    2. UnityGuy says:

      I changed the encryption key.
      Only to get an error.
      What am I doing wrongly here?

      1. Bernard says:

        What’s the error you’re getting? You need to stick to the same amount of characters as the original one.

  72. laurent says:

    Bonjour.
    I use your previewLabs file.
    Everything works fine, except when i take a look in android/data/mycom/files/PlayersPrefs.txt in my android phone, the data was not encrypted. I can read it modify it…
    Did i miss something ?

    Thanks

  73. Joseph says:

    Does anyone have an example of storing an object using this class.

    Good work btw 🙂

  74. chihiro says:

    hi, thank you for great work.
    It seems that once app crashed from file open to close in Flush method,
    playerprefs data might be disappeared.
    I mean it overwrite data if file exist in the following logic.
    fileWriter = File.CreateText ((securityModeEnabled ? secureFileName : fileName));

    I hope it will help you to improve this great job.

  75. victor says:

    I don’t know why, but it didn’t work for me :/

    The game stoped saving

  76. Jean Marc says:

    Hi,
    Does PreviewLabs.PlayerPrefs still compatible with Unity 2018 2019 and Android, iOS, MacOS Plateforms?

    Thanks

    Happy New Year to you and your Team

    Jean-Marc

  77. Jocko says:

    Still fantastic in 2019!

  78. Bernard says:

    Great to hear that!

    Back in 2014 we had done a review of the performance and PreviewLabs.PlayerPrefs outperformed the regular PlayerPrefs in a lot of cases. For anyone interested in the details, see http://previewlabs.com/previewlabs-playerprefs-vs-unity-playerprefs/

    Perhaps at some point in the future we’ll repeat this experiment – if we do, we’ll link to it here.

Leave a comment

Your email address will not be published. Required fields are marked *