👨💻个人主页:@元宇宙-秩沅
👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!
👨💻 本文由 秩沅 原创
👨💻 收录于专栏:unity数据存储
⭐制作一个数据管理类(存储排行榜信息)的实践⭐
Unity公共类PlayerPrefs知识点入口
文章目录
- ⭐制作一个数据管理类(存储排行榜信息)的实践⭐
- Unity公共类PlayerPrefs知识点入口
- 🎶需求分析
- 🎶关键知识补充
- 🎶数据管理类的创建
- 🎶PlayerPrefs—各种类型的反射存储框架
- 🎶PlayerPrefs—存储主方法
- 🎶PlayerPrefs—普通数据类型的反射存储
- 🎶PlayerPrefs—泛型List的反射存储
- 🎶PlayerPrefs—泛型Dictionary的反射存储
- 🎶PlayerPrefs—自定义类类型的反射存储
- 🎶PlayerPrefs—各种类型的反射获取框架
- 🎶PlayerPrefs—获取主方法
- 🎶PlayerPrefs—普通数据类型的反射获取
- 🎶PlayerPrefs—泛型List的反射获取
- 🎶PlayerPrefs—泛型Dictionary的反射获取
- 🎶PlayerPrefs—自定义类类型的反射存储
- 🎶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大全(万字详解),不信你不收藏
你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!