[CLOSED] PlayerPrefs bug on Windows ?

Hi everyone, Happy New Year !

I’ve just discovered PlayerPrefs ( after using Unity for 5 years, shame on me ), and my script doesn’t seems to work. I check if there is some data already saved, if yes, load those datas, else I set new data to default values and save them. On the doc page, I’ve seen that PlayerPrefs in the Editor and Windows builds are saved into the registry.

So I decided to go there to see if there were any problem during save. All I saw was my variables saved, but with a “0” value. Plus, all my floats variables seems to be glitched, my registry says “Invalid 32bits DWORD value” for them. Is that supposed to work like this ? I’m on Windows 7 x64.

By the way, does the user need to be an Administrator to save data correctly ? I run Unity as a standard user.
And why is there no GetBool() and SetBool() methods ? Problem with the registry or OS X system that could mess up something ? I got some bools to save, but I need to convert them to int when saving, and converting those int to bool when loading.

I put a screenshot of this “strange” behaviour.

Thanks everyone for reading me, hoping someone got a solution :slight_smile:

PS: On Windows 7, in the registry, “HKCU.…” is “HKEY_CURRENT_USER.…”. It took me nearly a minute to notice that. I don’t know if it change on other Windows versions.

Edit: if someone wonders, I use Unity 5.3.1f1.

Are you able to retrieve the proper values using code? If so, the internal storage format used by Unity isn’t strictly relevant. It does seem odd that it says “invalid dword”… how is that even possible - it’s just bits.

I can retrieve values, but I just got “0” in all my values. Maybe related to user rights on Windows. I will try to run Unity as Administrator to see if something change and I will edit my message.

Edit: After running as Administrator, I’ve realised that something was wrong, all values were reset to 0 before saving. But I still got this strange phenomenon about floats being “invalid 32bits DWORD value”, but those save and load normally. Maybe Windows got a problem with those kind of values, I don’t know.

After doing some reading, it seems that registry entries are effectively just binary data. The type (DWORD in this case) is just a hint for tools like regedit so they can display the binary data in a meaningful way, but you can store any amount of data in that key. So it would seem that Unity uses the DWORD type hint for floats, but stores more than 32 bits (maybe they’re actually storing doubles?) so RegEdit doesn’t know how to display the actual value.

1 Like

Ok thanks so this is not a bug then. I just don’t like to have strange values or invalid values in my registry because it can break pretty easily… The only thing we need now is GetBool() and SetBool() methods, because I store my video settings, and those are modified by toggles, which return booleans. Having those methods would save me the pain of converting when saving and loading. Thanks you again for helping me :slight_smile:

Those methods are static so I don’t believe you can create an extension method to add Get/Set Bool. But you can create a helper class, or probably a descendant class and add the methods in that. No need to convert every time.

Something around like this, if I remember my coding class:

class PlayerPrefsV2: PlayerPrefs {

    // Redefining already existing methods

    bool GetBool(){

        // blablabla
    }

    void SetBool(){

        //blablabla
    }
}

I had to deal with this today, and TL;DR:

Float values in playerprefs are stored as 64-bit doubles.
You need to pull them down like this:

    string keyName = @"Software\\MATTCO\\TESTFLOATS";
    RegistryKey key = Registry.CurrentUser.OpenSubKey(keyName);
    Object o = key.GetValue(value);
    long lData = (long)o;
    var bytes = BitConverter.GetBytes(lData);
    double dubs = BitConverter.ToDouble(bytes, 0);
    Console.WriteLine($"Double Value: {dubs}");