本文共 4634 字,大约阅读时间需要 15 分钟。
在Unity开发过程中,PlayerPrefs作为一种简单易用的数据存储工具,广泛应用于游戏和应用程序中。然而,仅仅依靠PlayerPrefs可能会带来一些问题,特别是在数据复杂度提高时。因此,在本文中,我们将探讨一种结合反射机制和PlayerPrefs的通用数据存储方法。
为了实现对数据的高效存储与加载,我们设计并实现了一个基于反射机制的PlayerPrefs数据存储工具。该工具能够支持多种数据类型的存储与加载,包括基本类型和集合类型。下面是工具的主要实现代码:
public class PlayerPrefsDataMgr{ private static readonly PlayerPrefsDataMgr instance = new PlayerPrefsDataMgr(); public static PlayerPrefsDataMgr Instance { get { return instance; } } private PlayerPrefsDataMgr() { // 初始化默认值 PlayerPrefs.SetInt("defaultSetting", 1); } public void SaveData(object data, string KeyName) { Type type = data.GetType(); FieldInfo[] fieldInfos = type.GetFields(); foreach (FieldInfo field in fieldInfos) { object value = field.GetValue(data); string key = $"{KeyName}_{field.FieldType.Name}_{field.Name}"; SaveValue(value, key); } // 确保数据被及时保存 PlayerPrefs.Save(); } private void SaveValue(object value, string keyName) { Type type = value.GetType(); Type[] typeArguments = type.GetGenericArguments(); if (type == typeof(int)) { PlayerPrefs.SetInt(keyName, (int)value); } else if (type == typeof(string)) { PlayerPrefs.SetString(keyName, value.ToString()); } else if (type == typeof(float)) { PlayerPrefs.SetFloat(keyName, (float)value); } else if (type == typeof(bool)) { PlayerPrefs.SetInt(keyName, (int)value); } else if (typeof(IList).IsAssignableFrom(type)) { IList list = (IList)value; PlayerPrefs.SetInt(keyName, list.Count); for (int i = 0; i < list.Count; i++) { SaveValue(list[i], $"{keyName}_{i}"); } } else if (typeof(IDictionary).IsAssignableFrom(type)) { IDictionary dictionary = (IDictionary)value; PlayerPrefs.SetInt(keyName, dictionary.Count); for (int i = 0; i < dictionary.Count; i++) { object key = dictionary.Keys[i]; object value = dictionary.ValueEnumerable[i]; SaveValue(key, $"{keyName}_key_{i}"); SaveValue(value, $"{keyName}_key_value_{i}"); } } else { SaveData(value, keyName); } } public object LoadData(Type type, string KeyName) { object o = Activator.CreateInstance(type); FieldInfo[] fieldInfos = o.GetType().GetFields(); foreach (FieldInfo field in fieldInfos) { object value = LoadValue(field.FieldType, $"{KeyName}_{field.FieldType.Name}_{field.Name}"); field.SetValue(o, value); } return o; } private object LoadValue(Type type, string keyName) { if (type == typeof(int)) { return PlayerPrefs.GetInt(keyName); } else if (type == typeof(string)) { return PlayerPrefs.GetString(keyName); } else if (type == typeof(float)) { return PlayerPrefs.GetFloat(keyName); } else if (type == typeof(bool)) { int value = PlayerPrefs.GetInt(keyName); return value == 1 ? true : false; } else if (typeof(IList).IsAssignableFrom(type)) { int count = PlayerPrefs.GetInt(keyName, 0); IList list = (IList)Activator.CreateInstance(type); for (int i = 0; i < count; i++) { object item = LoadValue(type.GetGenericArguments()[0], $"{keyName}_{i}"); list.Add(item); } return list; } else if (typeof(IDictionary).IsAssignableFrom(type)) { int count = PlayerPrefs.GetInt(keyName); IDictionary dictionary = (IDictionary)Activator.CreateInstance(type); for (int i = 0; i < count; i++) { object key = LoadValue(type.GetGenericArguments()[0], $"{keyName}_key_{i}"); object value = LoadValue(type.GetGenericArguments()[1], $"{keyName}_key_value_{i}"); dictionary.Add(key, value); } return dictionary; } else { return LoadData(type, keyName); } }} 在实际应用中,数据存储的安全性至关重要。对于单机游戏来说,加密解密是常用的手段,通常采用对数据进行复杂规律加密来确保安全。如需了解具体实现方法,可参考相关技术博客。
本文展示了一种结合反射机制和PlayerPrefs的通用数据存储工具设计。通过这种方法,开发者可以更方便地管理和存储各种类型的数据。在实际应用中,建议结合加密技术确保数据安全性。如需了解更多详细实现细节,可参考相关技术资料。
转载地址:http://kvwzz.baihongyu.com/