PlayerPrefs - Registry Values stored as invalid DWORD

Hi Unity Answers,

Out of some weird circumstances, I need to programatically read all the values of playerprefs stored in the registry, and not simply use PlayerPrefs.GetFloat(). When using Regedit I saw that the float registry keys value was REG_DWORD and not a REG_QWORD or REG_BINARY. Also the value is listed as “(invalid DWORD (32-bit) value)”. When you view the hex-data stored it seems to have a value, but it does not correlate to the actual value stored in unity.

When I read the value stored at the keys, I get completely different values. For instance I have a float stored in unity with a value of 1, the hex value shown in Regedit is 00 00 00 00 00 00 F0 3F and the value converted to a float is 4.60718242E+18. The strange thing is that unity still can read and process these values correctly. The function I am using to process the reg values is bellow:

public void ReadRegistryKeyValues()
{
   RegistryKey rk = Registry.LocalMachine.OpenSubKey("Software\\" + PlayerSettings.companyName +"\\" + PlayerSettings.productName , false);
    foreach (string key in rk.GetValueNames())
    {
        var currentKey = rk.GetValue(key);
        if(currentKey != null)
        {
            if(currentKey.GetType().Name == "Int32")
            {
                int r = Convert.ToInt32(currentKey);
            }
            if (currentKey.GetType().Name == "Int64")
            {
                float r = Convert.ToInt64(currentKey);
            }
            if (currentKey.GetType().Name == "String")
            {
                string r = currentKey.ToString();
            }
        }
                
    }
}

Does anyone know how to read the invalid DWORD correctly in c#? Or does anyone know of a Way to force C# to read this key as QWORD? Does a Unity Software Engineer want to reveal the process they use to read these invalid reg keys?

if i understood correctly , you can use PlayerPrefs.GetFloat for reading the values…

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}");