|
数据持久化
PlayerPrefs相关
PlayerPrefs是Unity游戏引擎中的一个类,用于在游戏中存储和访问玩家的偏好设置和数据。它可以用来保存玩家的游戏进度、设置选项、最高分数等信息。PlayerPrefs将数据存储在本地文件中,因此可以在游戏重新启动时保持数据的持久性。- //PlayerPrefs的数据存储 类似于键值对存储 一个键对应一个值
- //提供了存储3种数据的方法 int float string
- //键: string类型
- //值:int float string 对应3种API
- PlayerPrefs.SetInt("myAge", 18);
- PlayerPrefs.SetFloat("myHeight", 177.5f);
- PlayerPrefs.SetString("myName", "TonyChang");
- //直接调用Set相关方法 只会把数据存到内存里
- //当游戏结束时 Unity会自动把数据存到硬盘中
- //如果游戏不是正常结束的 而是崩溃 数据是不会存到硬盘中的
- //只要调用该方法 就会马上存储到硬盘中
- PlayerPrefs.Save();
- //PlayerPrefs是有局限性的 它只能存3种类型的数据
- //如果你想要存储别的类型的数据 只能降低精度 或者上升精度来进行存储
- bool sex = true;
- PlayerPrefs.SetInt("sex", sex ? 1 : 0);
- //如果不同类型用同一键名进行存储 会进行覆盖
- PlayerPrefs.SetFloat("myAge", 20.2f);
- //注意 运行时 只要你Set了对应键值对
- //即使你没有马上存储Save在本地
- //也能够读取出信息
- //int
- int age = PlayerPrefs.GetInt("myAge");
- print(age);
- //前提是 如果找不到myAge对应的值 就会返回函数的第二个参数 默认值
- age = PlayerPrefs.GetInt("myAge", 100);
- print(age);
- //float
- float height = PlayerPrefs.GetFloat("myHeight", 1000f);
- print(height);
- //string
- string name = PlayerPrefs.GetString("myName");
- print(name);
- //第二个参数 默认值 对于我们的作用
- //就是 在得到没有的数据的时候 就可以用它来进行基础数据的初始化
- //判断数据是否存在
- if( PlayerPrefs.HasKey("myName") )
- {
- print("存在myName对应的键值对数据");
- }
- //删除指定键值对
- PlayerPrefs.DeleteKey("myAge");
- //删除所有存储的信息
- PlayerPrefs.DeleteAll();
复制代码 PlayerPrefs中存储的数据存储在哪里?
PC端: PlayerPrefs 存储在 HKCU\Software[公司名称][产品名称] 项下的注册表中
其中公司和产品名称是 在“Project Settings”中设置的名称。
安卓: /data/data/包名/shared_prefs/pkg-name.xml
PlayerPrefs中数据的唯一性,PlayerPrefs中数据的唯一性是由key决定的,不同的key决定了不同的数据,同一个项目中如果不同数据key相同会造成数据丢失,要保证数据名称命名的唯一性规则。
优点:使用简单
缺点:存储数据类型有限、安全性差(直接找到在设备上的存储的位置查看设置)
PlayerPrefs存储工具类:
为了方便进行数据的存储,使用PlayerPrefs中进行存储方法的设置的存取!
主要实现功能是数据的读和数据的取~ 通过反射进行数据类型的获取,利用PlayerPrefs进行数据存储。- using System;
- using System.Collections;
- using System.Reflection;
- using UnityEngine;
- namespace Framwork
- {
- /// <summary>
- /// Playerprefs 存储类
- /// </summary>
- public class PlayerPrefsManager
- {
- private static PlayerPrefsManager instance=new PlayerPrefsManager();
- public static PlayerPrefsManager Instance => instance;
- private PlayerPrefsManager()
- {
-
- }
- /// <summary>
- /// 存取数据的方法
- /// </summary>
- /// <param name="obj">数据实体</param>
- /// <param name="name">数据名称</param>
- public void SaveData(object data, string keyName)
- {
- Type type = data.GetType();
- FieldInfo[] infos = type.GetFields();
- string tempKey="null";
- FieldInfo tempInfo = null;
- for (int i = 0; i < infos.Length; i++)
- {
- //获取数据数据类型
- tempInfo = infos[i];
- Debug.Log("Types==="+tempInfo);
- //类的名字+类的类型 + 数据内容名字+数据类型
- //作为存储的keyName键
- tempKey = keyName + "_" + type.Name + "_" + tempInfo.Name
- + "_" + tempInfo.FieldType.Name;
- SaveValue(tempInfo.GetValue(data),tempKey);
- }
- //进行值的获取
- //tempInfo.GetValue(data);
- PlayerPrefs.Save();
- }
- /// <summary>
- /// 读取数据的类型
- /// </summary>
- /// <param name="type">要读取的数据类型</param>
- /// <param name="name">要读取的数据名称</param>
- /// <returns>返回数据实体</returns>
- public object LoadData(Type type, string name)
- {
- //获取数据中的类型
- FieldInfo[] infos = type.GetFields();
- //创建存储数据信息的实体
- object data = Activator.CreateInstance(type);
- string tempName = null;
- FieldInfo tempInfo = null;
- for (int i = 0; i < infos.Length; i++)
- {
- tempInfo = infos[i];//数据结构中的数据名称
- tempName = name + "_" + type.Name + "_" +tempInfo.Name+"_"
- +tempInfo.FieldType.Name;//数据结构中的数据名称类型
- //装载的容器 容器中的数据
- //进行数据装载
- tempInfo.SetValue(data,LoadValue(tempInfo.FieldType,tempName));
- }
- return data;
- }
- /// <summary>
- /// 进行具体的类型数据的存储
- /// </summary>
- /// <param name="data"></param>
- /// <param name="keyName"></param>
- private void SaveValue(object value, string keyName)
- {
- Type fieldType = value.GetType();
- if (fieldType == typeof(int))
- {
- Debug.Log("存储int"+value);
- PlayerPrefs.SetInt(keyName,(int)value);
- }else if (fieldType == typeof(float))
- {
- Debug.Log("存储float"+value);
- PlayerPrefs.SetFloat(keyName,(float)value);
- }else if (fieldType == typeof(string))
- {
- Debug.Log("存储string"+value);
- PlayerPrefs.SetString(keyName,value.ToString());
- }
- //对于List存储的设置
- //根据存储的字段类型和IList是否是父子关系
- else if(typeof(IList).IsAssignableFrom(fieldType))
- {
- //父类装子类
- IList list=value as IList;
- //存储元素数量
- PlayerPrefs.SetInt(keyName,list.Count);
- Debug.Log("存储List长度为"+list.Count);
- int index = 0;
- foreach (var obj in list)
- {
- //存储list列表中元素内容
- //命名形式是 list名字+索引编号
- //递归调用存储
- SaveValue(obj,keyName+index);
- index++;
- }
- }else if (typeof(IDictionary).IsAssignableFrom(fieldType))
- {
- IDictionary dictionary = value as IDictionary;
- //存储数据个数
- PlayerPrefs.SetInt(keyName,dictionary.Count);
- Debug.Log("存储Dic长度为"+dictionary.Count);
- int index = 0;
- foreach (var key in dictionary.Keys)
- {
- //存储键
- SaveValue(key,keyName+"_key_"+index);
- //存储值
- SaveValue(dictionary[key],keyName+"_value_"+index);
- index++;
- }
- }//自定义数据类型的存储 进行解析
- else
- {
- SaveData(value,keyName);
- }
- }
- private object LoadValue(Type type, string name)
- {
- if (type == typeof(int))
- {
- return PlayerPrefs.GetInt(name,0);
- }else if (type == typeof(float))
- {
- return PlayerPrefs.GetFloat(name,0.0f);
- }else if (type == typeof(string))
- {
- return PlayerPrefs.GetString(name,"");
- }else if (typeof(IList).IsAssignableFrom(type))
- {
- //读取列表
- int count = PlayerPrefs.GetInt(name);
- IList tempList=Activator.CreateInstance(type) as IList;
- for (int i = 0; i < count; i++)
- {
- //获取List中存储元素的类型 type.GetGenericArguments()[0]
- tempList.Add(LoadValue(type.GetGenericArguments()[0],name+i));
- }
- return tempList;
- }else if (typeof(IDictionary).IsAssignableFrom(type))
- {
- //进行对字典的读取
- int count = PlayerPrefs.GetInt(name);
- IDictionary tempDictionary=Activator.CreateInstance(type) as IDictionary;
- for (int i = 0; i < count; i++)
- {
- tempDictionary.Add(LoadValue(type.GetGenericArguments()[0], name + "_key_" + i),
- LoadValue(type.GetGenericArguments()[1], name + "_value_" + i));
- }
- return tempDictionary;
- }
- else
- {
- //读取自定义类成员的设置
- return LoadData(type, name);
- }
- }
- }
- }
复制代码 附:
测试脚本- using System.Collections.Generic;
- using UnityEngine;
- namespace Framwork
- {
- //注意:
- //1 自定义数据结构类型中要有有效的无参构造函数
-
- public class PlayerInfo
- {
- public int age;
- public string name;
- public float height;
- public int sex;//0是女 1是男
- public ItemInfo ItemInfo;
- //list存储测试
- public List<int> list;
- public Dictionary<int, string> dic;
-
- }
- public class ItemInfo
- {
- public int stu_no;//学号
- public int stu_class;//班级
- public ItemInfo()
- {
-
- }
- public ItemInfo(int no,int classNo)
- {
- stu_no = no;
- stu_class = classNo;
- }
- }
- /// <summary>
- /// 测试类
- /// </summary>
- public class TestPlayerPrefsTest:MonoBehaviour
- {
- private PlayerInfo playerInfo;
- private PlayerInfo playerInfo1;
- private void Start()
- {
- //读取数据
- playerInfo = new PlayerInfo();
- // Type fieldType = playerInfo.GetType();
- playerInfo.age = 18;
- playerInfo.name = "TonyChang";
- playerInfo.height = 175.8f;
- playerInfo.sex = 1;
- playerInfo.ItemInfo = new ItemInfo(2001, 2);
- playerInfo.list = new List<int>(){1,5,6,8};
- playerInfo.dic = new Dictionary<int, string>();
- playerInfo.dic.Add(1,"Tony");
- playerInfo.dic.Add(2,"Jeny");
- playerInfo.dic.Add(3,"JayChou");
- //进行数据保存
- PlayerPrefsManager.Instance.SaveData(playerInfo,"Player1");
-
- playerInfo1 = PlayerPrefsManager.Instance.LoadData(typeof(PlayerInfo), "Player1") as PlayerInfo;
- Debug.Log("age=="+playerInfo1.age);
- Debug.Log("name=="+playerInfo1.name);
- Debug.Log("sex=="+playerInfo1.sex);
- Debug.Log("List[1]=="+playerInfo1.list[1]);
- Debug.Log("Dic[1]=="+playerInfo1.dic[1]);
- }
- }
- }
复制代码 来源:https://www.cnblogs.com/TonyCode/archive/2023/11/19/17842598.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|