Unity PlayerPrefs注册表:WPF读取float转DWORD32异常排查
解决Unity PlayerPrefs DWORD格式float在WPF中的读写问题
问题根源
你的转换逻辑存在两个核心错误:
- 错误的数据类型接收:注册表中Unity存储的float是32位DWORD(无符号整数),用
long(64位)接收会导致高位补0,后续字节处理完全偏离原数据。 - 多余的字节序反转:Windows平台下Unity和WPF均采用小端字节序,反转字节会直接破坏float的二进制结构,最终得到极小的非规格化浮点数(如1.35E-43)。
正确转换方案
Unity的PlayerPrefs本质是将float的4字节二进制内容直接转成32位无符号整数(DWORD)存储,因此只需还原这个二进制对应关系即可。
非安全代码实现(高效直接)
如果项目允许unsafe代码,这是最直接的方式:
// 将DWORD(uint)转回float public static unsafe float UInt32ToFloat(uint dwordValue) { return *(float*)&dwordValue; } // 将float转成DWORD(uint)用于写入 public static unsafe uint FloatToUInt32(float floatValue) { return *(uint*)&floatValue; }
安全代码实现(无需unsafe)
如果禁用unsafe,用BitConverter处理字节数组:
// 将DWORD(uint)转回float public static float UInt32ToFloat(uint dwordValue) { byte[] bytes = BitConverter.GetBytes(dwordValue); // Windows是小端序,Unity和WPF一致,无需反转 return BitConverter.ToSingle(bytes, 0); } // 将float转成DWORD(uint)用于写入 public static uint FloatToUInt32(float floatValue) { byte[] bytes = BitConverter.GetBytes(floatValue); return BitConverter.ToUInt32(bytes, 0); }
完整读写示例
读取注册表中的PlayerPrefs float值
using Microsoft.Win32; // 替换为你的Unity项目的CompanyName和ProductName var registryPath = @"Software\YourCompanyName\YourGameName"; using var key = Registry.CurrentUser.OpenSubKey(registryPath); if (key != null) { // 读取DWORD类型值,转为uint var dwordValue = (uint)key.GetValue("YourFloatKey", 0u); var floatValue = UInt32ToFloat(dwordValue); // 使用floatValue }
写入float到注册表(模拟PlayerPrefs逻辑)
using Microsoft.Win32; var registryPath = @"Software\YourCompanyName\YourGameName"; using var key = Registry.CurrentUser.CreateSubKey(registryPath); if (key != null) { float targetValue = 1.5f; var dwordValue = FloatToUInt32(targetValue); key.SetValue("YourFloatKey", dwordValue, RegistryValueKind.DWord); }
内容的提问来源于stack exchange,提问作者Azule
相关产品推荐
相关产品推荐

