翼度科技»论坛 编程开发 .net 查看内容

Unity学习笔记--数据持久化之PlayerPrefs的使用

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
数据持久化

PlayerPrefs相关

PlayerPrefs是Unity游戏引擎中的一个类,用于在游戏中存储和访问玩家的偏好设置和数据。它可以用来保存玩家的游戏进度、设置选项、最高分数等信息。PlayerPrefs将数据存储在本地文件中,因此可以在游戏重新启动时保持数据的持久性。
  1. //PlayerPrefs的数据存储 类似于键值对存储 一个键对应一个值
  2. //提供了存储3种数据的方法 int float string
  3. //键: string类型
  4. //值:int float string 对应3种API
  5. PlayerPrefs.SetInt("myAge", 18);
  6. PlayerPrefs.SetFloat("myHeight", 177.5f);
  7. PlayerPrefs.SetString("myName", "TonyChang");
  8. //直接调用Set相关方法 只会把数据存到内存里
  9. //当游戏结束时 Unity会自动把数据存到硬盘中
  10. //如果游戏不是正常结束的 而是崩溃 数据是不会存到硬盘中的
  11. //只要调用该方法 就会马上存储到硬盘中
  12. PlayerPrefs.Save();
  13. //PlayerPrefs是有局限性的 它只能存3种类型的数据
  14. //如果你想要存储别的类型的数据 只能降低精度 或者上升精度来进行存储
  15. bool sex = true;
  16. PlayerPrefs.SetInt("sex", sex ? 1 : 0);
  17. //如果不同类型用同一键名进行存储 会进行覆盖
  18. PlayerPrefs.SetFloat("myAge", 20.2f);
  19. //注意 运行时 只要你Set了对应键值对
  20. //即使你没有马上存储Save在本地
  21. //也能够读取出信息
  22. //int
  23. int age = PlayerPrefs.GetInt("myAge");
  24. print(age);
  25. //前提是 如果找不到myAge对应的值 就会返回函数的第二个参数 默认值
  26. age = PlayerPrefs.GetInt("myAge", 100);
  27. print(age);
  28. //float
  29. float height = PlayerPrefs.GetFloat("myHeight", 1000f);
  30. print(height);
  31. //string
  32. string name = PlayerPrefs.GetString("myName");
  33. print(name);
  34. //第二个参数 默认值 对于我们的作用
  35. //就是 在得到没有的数据的时候 就可以用它来进行基础数据的初始化
  36. //判断数据是否存在
  37. if( PlayerPrefs.HasKey("myName") )
  38. {
  39.     print("存在myName对应的键值对数据");
  40. }
  41. //删除指定键值对
  42. PlayerPrefs.DeleteKey("myAge");
  43. //删除所有存储的信息
  44. PlayerPrefs.DeleteAll();
复制代码
PlayerPrefs中存储的数据存储在哪里?
PC端: PlayerPrefs 存储在 HKCU\Software[公司名称][产品名称] 项下的注册表中
其中公司和产品名称是 在“Project Settings”中设置的名称。
安卓: /data/data/包名/shared_prefs/pkg-name.xml
PlayerPrefs中数据的唯一性,PlayerPrefs中数据的唯一性是由key决定的,不同的key决定了不同的数据,同一个项目中如果不同数据key相同会造成数据丢失,要保证数据名称命名的唯一性规则。
优点:使用简单
缺点:存储数据类型有限、安全性差(直接找到在设备上的存储的位置查看设置)
PlayerPrefs存储工具类:

为了方便进行数据的存储,使用PlayerPrefs中进行存储方法的设置的存取!
主要实现功能是数据的读和数据的取~ 通过反射进行数据类型的获取,利用PlayerPrefs进行数据存储。
  1. using System;
  2. using System.Collections;
  3. using System.Reflection;
  4. using UnityEngine;
  5. namespace Framwork
  6. {
  7.     /// <summary>
  8.     /// Playerprefs 存储类
  9.     /// </summary>
  10.     public class PlayerPrefsManager
  11.     {
  12.         private static PlayerPrefsManager instance=new PlayerPrefsManager();
  13.         public static PlayerPrefsManager Instance => instance;
  14.         private PlayerPrefsManager()
  15.         {
  16.            
  17.         }
  18.         /// <summary>
  19.         /// 存取数据的方法
  20.         /// </summary>
  21.         /// <param name="obj">数据实体</param>
  22.         /// <param name="name">数据名称</param>
  23.         public void SaveData(object data, string keyName)
  24.         {
  25.             Type type = data.GetType();
  26.             FieldInfo[] infos = type.GetFields();
  27.             string tempKey="null";
  28.             FieldInfo tempInfo = null;
  29.             for (int i = 0; i < infos.Length; i++)
  30.             {
  31.                 //获取数据数据类型
  32.                 tempInfo = infos[i];
  33.                 Debug.Log("Types==="+tempInfo);
  34.                 //类的名字+类的类型 + 数据内容名字+数据类型
  35.                 //作为存储的keyName键
  36.                 tempKey = keyName + "_" + type.Name + "_" + tempInfo.Name
  37.                             + "_" + tempInfo.FieldType.Name;
  38.                 SaveValue(tempInfo.GetValue(data),tempKey);
  39.             }
  40.             //进行值的获取
  41.            //tempInfo.GetValue(data);
  42.             PlayerPrefs.Save();
  43.         }
  44.         /// <summary>
  45.         /// 读取数据的类型
  46.         /// </summary>
  47.         /// <param name="type">要读取的数据类型</param>
  48.         /// <param name="name">要读取的数据名称</param>
  49.         /// <returns>返回数据实体</returns>
  50.         public object LoadData(Type type, string name)
  51.         {
  52.             //获取数据中的类型
  53.             FieldInfo[] infos = type.GetFields();
  54.             //创建存储数据信息的实体
  55.             object data = Activator.CreateInstance(type);
  56.             string tempName = null;
  57.             FieldInfo tempInfo = null;
  58.             for (int i = 0; i < infos.Length; i++)
  59.             {
  60.                 tempInfo = infos[i];//数据结构中的数据名称
  61.                 tempName = name + "_" + type.Name + "_" +tempInfo.Name+"_"
  62.                     +tempInfo.FieldType.Name;//数据结构中的数据名称类型
  63.                 //装载的容器  容器中的数据
  64.                 //进行数据装载
  65.                 tempInfo.SetValue(data,LoadValue(tempInfo.FieldType,tempName));
  66.             }
  67.             return data;
  68.         }
  69.         /// <summary>
  70.         /// 进行具体的类型数据的存储
  71.         /// </summary>
  72.         /// <param name="data"></param>
  73.         /// <param name="keyName"></param>
  74.         private void SaveValue(object value, string keyName)
  75.         {
  76.             Type fieldType = value.GetType();
  77.             if (fieldType == typeof(int))
  78.             {
  79.                 Debug.Log("存储int"+value);
  80.                 PlayerPrefs.SetInt(keyName,(int)value);
  81.             }else if (fieldType == typeof(float))
  82.             {
  83.                 Debug.Log("存储float"+value);
  84.                 PlayerPrefs.SetFloat(keyName,(float)value);
  85.             }else if (fieldType == typeof(string))
  86.             {
  87.                 Debug.Log("存储string"+value);
  88.                 PlayerPrefs.SetString(keyName,value.ToString());
  89.             }
  90.             //对于List存储的设置
  91.             //根据存储的字段类型和IList是否是父子关系
  92.             else if(typeof(IList).IsAssignableFrom(fieldType))
  93.             {
  94.                 //父类装子类
  95.                 IList list=value as IList;
  96.                 //存储元素数量
  97.                 PlayerPrefs.SetInt(keyName,list.Count);
  98.                 Debug.Log("存储List长度为"+list.Count);
  99.                 int index = 0;
  100.                 foreach (var obj in list)
  101.                 {
  102.                     //存储list列表中元素内容
  103.                     //命名形式是 list名字+索引编号
  104.                     //递归调用存储
  105.                     SaveValue(obj,keyName+index);
  106.                     index++;
  107.                 }
  108.             }else if (typeof(IDictionary).IsAssignableFrom(fieldType))
  109.             {
  110.                 IDictionary dictionary = value as IDictionary;
  111.                 //存储数据个数
  112.                 PlayerPrefs.SetInt(keyName,dictionary.Count);
  113.                 Debug.Log("存储Dic长度为"+dictionary.Count);
  114.                 int index = 0;
  115.                 foreach (var key in dictionary.Keys)
  116.                 {
  117.                     //存储键
  118.                     SaveValue(key,keyName+"_key_"+index);
  119.                     //存储值
  120.                     SaveValue(dictionary[key],keyName+"_value_"+index);
  121.                     index++;
  122.                 }
  123.             }//自定义数据类型的存储 进行解析
  124.             else
  125.             {
  126.                 SaveData(value,keyName);
  127.             }
  128.         }
  129.         private object LoadValue(Type type, string name)
  130.         {
  131.             if (type == typeof(int))
  132.             {
  133.                 return PlayerPrefs.GetInt(name,0);
  134.             }else if (type == typeof(float))
  135.             {
  136.                 return PlayerPrefs.GetFloat(name,0.0f);
  137.             }else if (type == typeof(string))
  138.             {
  139.                 return PlayerPrefs.GetString(name,"");
  140.             }else if (typeof(IList).IsAssignableFrom(type))
  141.             {
  142.                 //读取列表
  143.                 int count = PlayerPrefs.GetInt(name);
  144.                 IList tempList=Activator.CreateInstance(type) as IList;
  145.                 for (int i = 0; i < count; i++)
  146.                 {
  147.                     //获取List中存储元素的类型 type.GetGenericArguments()[0]
  148.                     tempList.Add(LoadValue(type.GetGenericArguments()[0],name+i));
  149.                 }
  150.                 return tempList;
  151.             }else if (typeof(IDictionary).IsAssignableFrom(type))
  152.             {
  153.                 //进行对字典的读取
  154.                 int count = PlayerPrefs.GetInt(name);
  155.                 IDictionary tempDictionary=Activator.CreateInstance(type) as IDictionary;
  156.                 for (int i = 0; i < count; i++)
  157.                 {
  158.                     tempDictionary.Add(LoadValue(type.GetGenericArguments()[0], name + "_key_" + i),
  159.                         LoadValue(type.GetGenericArguments()[1], name + "_value_" + i));
  160.                 }
  161.                 return tempDictionary;
  162.             }
  163.             else
  164.             {
  165.                 //读取自定义类成员的设置
  166.                 return LoadData(type, name);
  167.             }
  168.         }
  169.     }
  170. }
复制代码
附:
测试脚本
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace Framwork
  4. {
  5.     //注意:
  6.     //1 自定义数据结构类型中要有有效的无参构造函数
  7.    
  8.     public class PlayerInfo
  9.     {
  10.         public int age;
  11.         public string name;
  12.         public float height;
  13.         public int sex;//0是女 1是男
  14.         public ItemInfo ItemInfo;
  15.         //list存储测试
  16.         public List<int> list;
  17.         public Dictionary<int, string> dic;
  18.         
  19.     }
  20.     public class ItemInfo
  21.     {
  22.         public int stu_no;//学号
  23.         public int stu_class;//班级
  24.         public ItemInfo()
  25.         {
  26.             
  27.         }
  28.         public ItemInfo(int no,int classNo)
  29.         {
  30.             stu_no = no;
  31.             stu_class = classNo;
  32.         }
  33.     }
  34.     /// <summary>
  35.     /// 测试类
  36.     /// </summary>
  37.     public class TestPlayerPrefsTest:MonoBehaviour
  38.     {
  39.         private PlayerInfo playerInfo;
  40.         private PlayerInfo playerInfo1;
  41.         private void Start()
  42.         {
  43.              //读取数据
  44.              playerInfo = new PlayerInfo();         
  45.             // Type fieldType = playerInfo.GetType();
  46.              playerInfo.age = 18;
  47.              playerInfo.name = "TonyChang";
  48.              playerInfo.height = 175.8f;
  49.              playerInfo.sex = 1;
  50.              playerInfo.ItemInfo = new ItemInfo(2001, 2);
  51.              playerInfo.list = new List<int>(){1,5,6,8};
  52.              playerInfo.dic = new Dictionary<int, string>();
  53.              playerInfo.dic.Add(1,"Tony");
  54.              playerInfo.dic.Add(2,"Jeny");
  55.              playerInfo.dic.Add(3,"JayChou");
  56.              //进行数据保存
  57.              PlayerPrefsManager.Instance.SaveData(playerInfo,"Player1");
  58.             
  59.              playerInfo1 = PlayerPrefsManager.Instance.LoadData(typeof(PlayerInfo), "Player1") as PlayerInfo;
  60.              Debug.Log("age=="+playerInfo1.age);
  61.              Debug.Log("name=="+playerInfo1.name);
  62.              Debug.Log("sex=="+playerInfo1.sex);
  63.              Debug.Log("List[1]=="+playerInfo1.list[1]);
  64.              Debug.Log("Dic[1]=="+playerInfo1.dic[1]);
  65.         }
  66.     }
  67. }
复制代码
来源:https://www.cnblogs.com/TonyCode/archive/2023/11/19/17842598.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具