您现在的位置是:首页 >学无止境 >【unity数据持久化】游戏排行榜信息简单的存储,你还知道吗?数据管理类_PlayerPrfs网站首页学无止境
【unity数据持久化】游戏排行榜信息简单的存储,你还知道吗?数据管理类_PlayerPrfs
简介【unity数据持久化】游戏排行榜信息简单的存储,你还知道吗?数据管理类_PlayerPrfs
??个人主页:@元宇宙-秩沅
?? hallo 欢迎 点赞? 收藏⭐ 留言? 加关注✅!
?? 本文由 秩沅 原创
?? 收录于专栏:unity数据存储
⭐制作一个数据管理类(存储排行榜信息)的实践⭐
Unity公共类PlayerPrefs知识点入口
文章目录
?需求分析
?关键知识补充
?数据管理类的创建
?PlayerPrefs—各种类型的反射存储框架
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Unity.VisualScripting;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目: ______________
//___________功能: 数据管理存储
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class PlayerfabsClass
{
//单例模式的构建
static private PlayerfabsClass chats = new PlayerfabsClass();
static public PlayerfabsClass Chats { get => chats; }
//private List<object> listMess;
//private Dictionary<object, object> dictionaryMess;
/// <summary>
/// 实现对象的数据的存储
/// </summary>
/// <param name="player">玩家对象</param>
/// <param name="palyName">玩家对象信息Key字符</param>
public void SaveDataMess(object player ,string playName)
{
//-关键作用-:通过排行中的值来获取其信息
//自定义key的规则通过反射来获取对象里面的-类型名-和-类型值-
Type type = player.GetType();
Debug.Log(type);
FieldInfo[] FieldsMess = type.GetFields();
for (int i = 0; i < FieldsMess.Length; i++)
{
Debug.Log(FieldsMess[i]);
}
string temp = null;
for (int i = 0; i < FieldsMess.Length; i++) //通过字符串的拼接来,使得存储的字段具有唯一性
{
temp = $"{playName}_{type}_{FieldsMess[i].FieldType.Name}_{FieldsMess[i].Name }";
Debug.Log(playName);
HelpSave( FieldsMess[i].GetValue(player) ,temp );
}
PlayerPrefs.Save();
}
/// <summary>
/// 辅助存储
/// </summary>
/// <param name="value">由于只能设置三种类型的值就不得不用方法来进行</param>
/// <param name="playName">已经拼接好的key字符串</param>
private void HelpSave(object value , string playName )
{
Type valueTpye = value.GetType();
//----------1.常用数据类型的反射存储
if (valueTpye == typeof(int))
{
Debug.Log((int)value);
PlayerPrefs.SetInt(playName, (int)value);
}
else if (valueTpye == typeof(float ))
{
Debug.Log((float )value);
PlayerPrefs.SetFloat(playName, (float)value);
}
else if (valueTpye == typeof(string))
{
Debug.Log(value.ToString());
PlayerPrefs.SetString(playName, value.ToString());
}
//----------2.泛型List数据类型的反射存储 ——递归
else if(valueTpye.IsAssignableFrom(typeof(IList)) == true) //因为泛型不确定无法判断所以通过(判断是否为子类的API)确定类型
{
IList list = valueTpye as IList;
int index = 0;
PlayerPrefs.SetInt(playName,list.Count); //存储List数据先存储数量
foreach (object item in list )
{
HelpSave(item, item + "_" + index);
}
}
//--------3.泛型字典数据类型的反射存储 —— 递归
else if(valueTpye.IsAssignableFrom(typeof(IDictionary) )==true)
{
IDictionary dictionary = valueTpye as IDictionary;
int index = 0;
PlayerPrefs.SetInt(playName,dictionary.Count );
foreach (object item in dictionary .Keys)
{
HelpSave(item,item+"_Key_"+ index );
HelpSave(dictionary[item], dictionary[item] + "_Vaule_" + index);
}
}
//--------4.自定义类型的数据的反射存储 —— 大递归
else
{
SaveDataMess(value ,playName);
}
}
}
?PlayerPrefs—存储主方法
public void SaveDataMess(object player, string playName)
{
//-关键作用-:通过排行中的值来获取其信息
//自定义key的规则通过反射来获取对象里面的-类型名-和-类型值-
Type type = player.GetType();
Debug.Log(type);
FieldInfo[] FieldsMess = type.GetFields();
for (int i = 0; i < FieldsMess.Length; i++)
{
Debug.Log(FieldsMess[i]);
}
string temp = null;
for (int i = 0; i < FieldsMess.Length; i++) //通过字符串的拼接来,使得存储的字段具有唯一性
{
temp = $"{playName}_{type}_{FieldsMess[i].FieldType.Name}_{FieldsMess[i].Name }";
Debug.Log(playName);
HelpSave(FieldsMess[i].GetValue(player), temp);
}
PlayerPrefs.Save();
}
?PlayerPrefs—普通数据类型的反射存储
//-------------------------------------
//—————————————————————————————————————
//___________项目: ______________
//___________功能: 数据管理存储
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class PlayerfabsClass
{
//单例模式的构建
static private PlayerfabsClass chats = new PlayerfabsClass();
static public PlayerfabsClass Chats { get => chats; }
//private List<object> listMess;
//private Dictionary<object, object> dictionaryMess;
/// <summary>
/// 实现对象的数据的存储
/// </summary>
/// <param name="player">玩家对象</param>
/// <param name="palyName">玩家对象信息Key字符</param>
public void SaveDataMess(object player ,string playName)
{
//-关键作用-:通过排行中的值来获取其信息
//自定义key的规则通过反射来获取对象里面的-类型名-和-类型值-
Type type = player.GetType();
Debug.Log(type);
FieldInfo[] FieldsMess = type.GetFields();
for (int i = 0; i < FieldsMess.Length; i++)
{
Debug.Log(FieldsMess[i]);
}
string temp = null;
for (int i = 0; i < FieldsMess.Length; i++) //通过字符串的拼接来,使得存储的字段具有唯一性
{
temp = $"{playName}_{type}_{FieldsMess[i].FieldType.Name}_{FieldsMess[i].Name }";
Debug.Log(playName);
HelpSave( FieldsMess[i].GetValue(player) ,temp );
}
PlayerPrefs.Save();
}
/// <summary>
/// 辅助存储
/// </summary>
/// <param name="value">由于只能设置三种类型的值就不得不用方法来进行</param>
/// <param name="playName">已经拼接好的key字符串</param>
private void HelpSave(object value , string playName )
{
Type valueTpye = value.GetType();
if (valueTpye == typeof(int))
{
Debug.Log((int)value);
PlayerPrefs.SetInt(playName, (int)value);
}
else if (valueTpye == typeof(float ))
{
Debug.Log((float )value);
PlayerPrefs.SetFloat(playName, (float)value);
}
else if (valueTpye == typeof(string))
{
Debug.Log(value.ToString());
PlayerPrefs.SetString(playName, value.ToString());
}
}
/// <summary>
/// 实现对象的读取
/// </summary>
public void ReadMess()
{
}
?PlayerPrefs—泛型List的反射存储
//----------2.泛型List数据类型的反射存储
else if(valueTpye.IsAssignableFrom(typeof(IList)) == true) //因为泛型不确定无法判断所以通过(判断是否为子类的API)确定类型
{
IList list = valueTpye as IList;
int index = 0;
PlayerPrefs.SetInt(playName,list.Count); //存储List数据先存储数量
foreach (object item in list )
{
HelpSave(item, item + "_" + index);
}
}
?PlayerPrefs—泛型Dictionary的反射存储
//--------3.泛型字典数据类型的反射存储 —— 递归
else if(valueTpye.IsAssignableFrom(typeof(IDictionary) )==true)
{
IDictionary dictionary = valueTpye as IDictionary;
int index = 0;
PlayerPrefs.SetInt(playName,dictionary.Count );
foreach (object item in dictionary .Keys)
{
HelpSave(item,item+"_Key_"+ index );
HelpSave(dictionary[item], dictionary[item] + "_Vaule_" + index);
}
}
?PlayerPrefs—自定义类类型的反射存储
//--------4.自定义类型的数据的反射存储 —— 大递归
else
{
SaveDataMess(value ,playName);
}
?PlayerPrefs—各种类型的反射获取框架
#region 获取和赋值
/// <summary>
/// 获取存的数据,返回一个对象
/// </summary>
/// <param name="data"></param>
/// <param name="playName"></param>
/// <returns></returns>
public object GetDataMess(Type data ,string playName)
{
object player = Activator.CreateInstance(data) ;
FieldInfo[] info = data.GetFields();
string temp = "" ;
for (int i = 0; i < info.Length; i++)
{
temp = $"{playName}_{data}_{info[i].FieldType.Name}_{info [i].Name }";
//遍历每一个成员传进去设值
info[i].SetValue(data ,HelpSet(info[i].FieldType ,temp));
}
//给所有成员都设置值
return player;
}
public object HelpSet(Type type ,string playName)
{
//----------1.常用数据类型的反射获取
if (type == typeof(int) )
{
return PlayerPrefs.GetInt(playName,0); //第二个重载为设置默认值
}
else if(type == typeof(float))
{
return PlayerPrefs.GetFloat(playName, 0);
}
else if (type == typeof(string ))
{
return PlayerPrefs.GetString(playName, "");
}
else if(type ==typeof(bool))
{
return PlayerPrefs.GetInt(playName, 0) == 1 ? true : false;
}
//----------2.泛型List数据类型的反射获取
else if (type.IsAssignableFrom(typeof(IList)) == true)
{
//此时list也是对象了要实例化
IList list = Activator.CreateInstance(type) as IList;
Type Ftype = type.GetGenericArguments()[0]; //一个泛型返回下标0即可
int Count = PlayerPrefs.GetInt(playName + "_" + "Number");
for (int i = 0; i < Count; i++)
{
list.Add(HelpSet(Ftype , playName + "_" + i));
}
return list;
}
//--------3.泛型字典数据类型的反射获取
else if (type.IsAssignableFrom(typeof(IDictionary)) == true)
{
//此时list也是对象了要实例化
IDictionary dictionary = Activator.CreateInstance(type) as IDictionary;
Type Ftype1 = type.GetGenericArguments()[0]; //一个泛型返回下标0即可
Type Ftype2 = type.GetGenericArguments()[1];
int Count = PlayerPrefs.GetInt(playName + "_" + "Number");
for (int i = 0; i < Count; i++)
{
dictionary.Add(HelpSet(Ftype1, playName + "_" + i),
HelpSet(Ftype1, playName + "_" + i ) );
}
return dictionary;
}
else
{
GetDataMess(type, playName);
}
return null;
}
#endregion
?PlayerPrefs—获取主方法
public object GetDataMess(Type data ,string playName)
{
object player = Activator.CreateInstance(data) ;
FieldInfo[] info = data.GetFields();
string temp = "" ;
for (int i = 0; i < info.Length; i++)
{
temp = $"{playName}_{data}_{info[i].FieldType.Name}_{info [i].Name }";
//遍历每一个成员传进去设值
info[i].SetValue(data ,HelpSet(info[i].FieldType ,temp));
}
//给所有成员都设置值
return player;
}
?PlayerPrefs—普通数据类型的反射获取
//----------1.常用数据类型的反射获取
if (type == typeof(int) )
{
return PlayerPrefs.GetInt(playName,0); //第二个重载为设置默认值
}
else if(type == typeof(float))
{
return PlayerPrefs.GetFloat(playName, 0);
}
else if (type == typeof(string ))
{
return PlayerPrefs.GetString(playName, "");
}
else if(type ==typeof(bool))
{
return PlayerPrefs.GetInt(playName, 0) == 1 ? true : false;
}
?PlayerPrefs—泛型List的反射获取
//----------2.泛型List数据类型的反射获取
else if (type.IsAssignableFrom(typeof(IList)) == true)
{
//此时list也是对象了要实例化
IList list = Activator.CreateInstance(type) as IList;
Type Ftype = type.GetGenericArguments()[0]; //一个泛型返回下标0即可
int Count = PlayerPrefs.GetInt(playName + "_" + "Number");
for (int i = 0; i < Count; i++)
{
list.Add(HelpSet(Ftype , playName + "_" + i));
}
return list;
}
?PlayerPrefs—泛型Dictionary的反射获取
//--------3.泛型字典数据类型的反射获取
else if (type.IsAssignableFrom(typeof(IDictionary)) == true)
{
//此时list也是对象了要实例化
IDictionary dictionary = Activator.CreateInstance(type) as IDictionary;
Type Ftype1 = type.GetGenericArguments()[0]; //一个泛型返回下标0即可
Type Ftype2 = type.GetGenericArguments()[1];
int Count = PlayerPrefs.GetInt(playName + "_" + "Number");
for (int i = 0; i < Count; i++)
{
dictionary.Add(HelpSet(Ftype1, playName + "_" + i),
HelpSet(Ftype1, playName + "_" + i ) );
}
return dictionary;
}
?PlayerPrefs—自定义类类型的反射存储
else
{
GetDataMess(type, playName);
}
?PlayerPrefs—排行榜管理最终代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Unity.VisualScripting;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目: ______________
//___________功能: 数据管理类
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class PlayerfabsClass
{
//单例模式的构建
static private PlayerfabsClass chats = new PlayerfabsClass();
static public PlayerfabsClass Chats { get => chats; }
//private List<object> listMess;
//private Dictionary<object, object> dictionaryMess;
/// <summary>
/// 实现对象里的数据的存储
/// </summary>
/// <param name="player">玩家对象</param>
/// <param name="palyName">玩家对象信息Key字符</param>
///
public void SaveDataMess(object player, string playName)
{
//-关键作用-:通过排行中的值来获取其信息
//自定义key的规则通过反射来获取对象里面的-类型名-和-类型值-
Type type = player.GetType();
Debug.Log(type);
FieldInfo[] FieldsMess = type.GetFields();
for (int i = 0; i < FieldsMess.Length; i++)
{
Debug.Log(FieldsMess[i]);
}
string temp = null;
for (int i = 0; i < FieldsMess.Length; i++) //通过字符串的拼接来,使得存储的字段具有唯一性
{
temp = $"{playName}_{type}_{FieldsMess[i].FieldType.Name}_{FieldsMess[i].Name }";
Debug.Log(playName);
HelpSave(FieldsMess[i].GetValue(player), temp);
}
PlayerPrefs.Save();
}
/// <summary>
/// 辅助存储
/// </summary>
/// <param name="value">由于只能设置三种类型的值就不得不用方法来进行</param>
/// <param name="playName">已经拼接好的key字符串</param>
private void HelpSave(object value, string playName)
{
Type valueTpye = value.GetType();
//----------1.常用数据类型的反射存储
if (valueTpye == typeof(int))
{
Debug.Log((int)value);
PlayerPrefs.SetInt(playName, (int)value);
}
else if (valueTpye == typeof(float))
{
Debug.Log((float)value);
PlayerPrefs.SetFloat(playName, (float)value);
}
else if (valueTpye == typeof(string))
{
Debug.Log(value.ToString());
PlayerPrefs.SetString(playName, value.ToString());
}
else if(valueTpye == typeof(bool))
{
Debug.Log(value.ToString());
PlayerPrefs.SetInt(playName,(bool)value?1:0);
}
//----------2.泛型List数据类型的反射存储 ——递归
else if (valueTpye.IsAssignableFrom(typeof(IList)) == true) //因为泛型不确定无法判断所以通过(判断是否为子类的API)确定类型
{
IList list = valueTpye as IList;
int index = 0;
PlayerPrefs.SetInt(playName+"_"+"Number", list.Count); //存储List数据先存储数量
foreach (object item in list)
{
HelpSave(item, playName + "_" + index);
index++;
}
}
//--------3.泛型字典数据类型的反射存储 —— 递归
else if (valueTpye.IsAssignableFrom(typeof(IDictionary)) == true)
{
IDictionary dictionary = valueTpye as IDictionary;
int index = 0;
PlayerPrefs.SetInt(playName+ "_" + "Number", dictionary.Count); //先存储数量
foreach (object item in dictionary.Keys)
{
HelpSave(item, playName + "_Key_" + index);
HelpSave(dictionary[item], playName + "_Vaule_" + index);
index++;
}
}
//--------4.自定义类型的数据的反射存储 —— 大递归
else
{
SaveDataMess(value, playName);
}
}
#region 获取和赋值
/// <summary>
/// 获取存的数据,返回一个对象
/// </summary>
/// <param name="data"></param>
/// <param name="playName"></param>
/// <returns></returns>
public object GetDataMess(Type data ,string playName)
{
object player = Activator.CreateInstance(data) ;
FieldInfo[] info = data.GetFields();
string temp = "" ;
for (int i = 0; i < info.Length; i++)
{
temp = $"{playName}_{data}_{info[i].FieldType.Name}_{info [i].Name }";
//遍历每一个成员传进去设值
info[i].SetValue(data ,HelpSet(info[i].FieldType ,temp));
}
//给所有成员都设置值
return player;
}
public object HelpSet(Type type ,string playName)
{
//----------1.常用数据类型的反射获取
if (type == typeof(int) )
{
return PlayerPrefs.GetInt(playName,0); //第二个重载为设置默认值
}
else if(type == typeof(float))
{
return PlayerPrefs.GetFloat(playName, 0);
}
else if (type == typeof(string ))
{
return PlayerPrefs.GetString(playName, "");
}
else if(type ==typeof(bool))
{
return PlayerPrefs.GetInt(playName, 0) == 1 ? true : false;
}
//----------2.泛型List数据类型的反射获取
else if (type.IsAssignableFrom(typeof(IList)) == true)
{
//此时list也是对象了要实例化
IList list = Activator.CreateInstance(type) as IList;
Type Ftype = type.GetGenericArguments()[0]; //一个泛型返回下标0即可
int Count = PlayerPrefs.GetInt(playName + "_" + "Number");
for (int i = 0; i < Count; i++)
{
list.Add(HelpSet(Ftype , playName + "_" + i));
}
return list;
}
//--------3.泛型字典数据类型的反射获取
else if (type.IsAssignableFrom(typeof(IDictionary)) == true)
{
//此时list也是对象了要实例化
IDictionary dictionary = Activator.CreateInstance(type) as IDictionary;
Type Ftype1 = type.GetGenericArguments()[0]; //一个泛型返回下标0即可
Type Ftype2 = type.GetGenericArguments()[1];
int Count = PlayerPrefs.GetInt(playName + "_" + "Number");
for (int i = 0; i < Count; i++)
{
dictionary.Add(HelpSet(Ftype1, playName + "_" + i),
HelpSet(Ftype1, playName + "_" + i ) );
}
return dictionary;
}
else
{
GetDataMess(type, playName);
}
return null;
}
#endregion
#region 打印对象里面的信息
/// <summary>
/// 读取信息函数
/// </summary>
/// <param name="type">为什么这里不用Object用type,因为读取没有值,只需要类型就行简化了代码 </param>
/// <param name="playName">还是原来的Key关键标识字符</param>
public void ReadData(Type type ,string playName)
{
string temp = "";
//----------1.常用数据类型的反射打印
if (type == typeof(int))
{
Debug.Log(PlayerPrefs.GetInt(playName));
}
else if(type == typeof(float) )
{
Debug.Log(PlayerPrefs.GetFloat(playName));
}
else if (type == typeof(string) )
{
Debug.Log(PlayerPrefs.GetString(playName));
}
//----------2.泛型List数据类型的反射打印 ——递归
else if (type.IsAssignableFrom(typeof(IList)) )
{
IList list = type as IList;
Debug.Log( PlayerPrefs.GetInt(playName +"_" + "Number") ); //先读取数量
int index = 0;
foreach (Type item in list )
{
ReadData(item, playName + "_" + index);
index++;
}
}
//--------3.泛型字典数据类型的反射打印 —— 递归
else if (type.IsAssignableFrom(typeof(IDictionary)))
{
IDictionary dictionary = type as IDictionary;
int index = 0;
PlayerPrefs.GetInt(playName + "_" + "Number"); //先读取数量
foreach (Type item in dictionary.Keys)
{
ReadData(item, playName + "_Key_" + index);
ReadData(item, playName + "_Vaule_" + index);
index++;
}
}
//--------4.自定义类型的数据的反射打印 —— 大递归
else
{
FieldInfo[] FieldsMess = type.GetFields();
for (int i = 0; i < FieldsMess.Length; i++) //成员递归下去
{
temp = $"{playName}_{type}_{FieldsMess[i].FieldType.Name}_{FieldsMess[i].Name }";
ReadData(FieldsMess[i].FieldType , playName);
}
}
}
#endregion
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目: ______________
//___________功能: 排行榜数据控制器
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class Contorl : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Player player1 = new Player("孙悟空","BBBBB",66,10);
//存
PlayerfabsClass.Chats.SaveDataMess(player1,player1.playName);
//取
PlayerfabsClass.Chats.GetDataMess(player1.GetType(),player1.playName);
}
// Update is called once per frame
void Update()
{
}
}
⭐相关文章⭐
⭐【2023unity游戏制作-mango的冒险】-4.场景二的镜头和法球特效跟随
⭐【2023unity游戏制作-mango的冒险】-3.基础动作和动画API实现
⭐【2023unity游戏制作-mango的冒险】-2.始画面API制作
⭐【2023unity游戏制作-mango的冒险】-1.场景搭建
⭐本站最全-unity常用API大全(万字详解),不信你不收藏
你们的点赞? 收藏⭐ 留言? 关注✅是我持续创作,输出优质内容的最大动力!
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。