unity:playerprefs封装复杂类型存储

本模型支持int、string、float、字典、list等类型及封装类的存取。(已实测)

在测试的时候,发现一旦在类中声明了list的变量成员,用playerprefs可以存储,但是读取的时候,列表中第二个值会有问题,因此对int类型的存取整体改为了强转为string进行存取。

有什么问题可以评论,我会回复。

另外,引入几个知识点:

  1. typeof(IList).IsAssignableFrom(type)  用来判断IList是否为type的基类
  2. type.GetGenericArguments()[0]   获取type类的所有参数的类型,0代表第一个参数
  3. IList是所有List的基类,IDictionary是所有Dictionary的基类。

以下是具体代码:

using System;
using System.Collections;
using System.Reflection;
using UnityEngine;

public class SaveMyData
{
    //建立一个Instance
    private static SaveMyData instance = new SaveMyData();
    public static SaveMyData Instance
    {
        get
        {
            return instance;
        }
    }

    private SaveMyData()
    {

    }


    //存储数据值
    public void SaveValue(object value, string keyName)
    {
        Type valueType = value.GetType();
        //int类型存储
        if (valueType == typeof(int))
        {
            //转换为string存储(正常按int存储时,类结构下的list会有数据读取错误-估计是unity的bug)
            int v =(int)value;
            PlayerPrefs.SetString(keyName+"tostr", v.ToString());

            // //正常int存储
            // PlayerPrefs.SetInt(keyName, v);

        }
        //float类型存储
        else if (valueType == typeof(float))
        {
            PlayerPrefs.SetFloat(keyName, (float)value);
        }
        //string类型存储
        else if (valueType == typeof(string))
        {
            PlayerPrefs.SetString(keyName, (string)value);
        }
        //bool类型存储,转为Int类型
        else if (valueType == typeof(bool))
        {
            PlayerPrefs.SetInt(keyName, (bool)value ? 1 : 0);
        }
        //List列表存储
        else if (typeof(IList).IsAssignableFrom(valueType))
        {
            IList list = value as IList;
            //先存储数量
            PlayerPrefs.SetInt(keyName, list.Count);
            //再存储子项
            for (int i = 0; i < list.Count; i++)
            {
                SaveValue(list[i], keyName + i);
            }
        }
        //Dictionary字典存储
        else if (typeof(IDictionary).IsAssignableFrom(valueType))
        {
            IDictionary dic = value as IDictionary;
            //先存储数量
            PlayerPrefs.SetInt(keyName, dic.Count);
            //再存储子项
            int i = 0;
            foreach (var item in dic.Keys)
            {
                SaveValue(item, keyName + "_key_" + i);
                SaveValue(dic[item], keyName + "_value_" + i);
                i++;
            }

        }
        //自定义类型,需换取成员变量
        else
        {
            //获取Type
            Type dataType = value.GetType();
            //获取成员变量
            FieldInfo[] fields = dataType.GetFields();
            //存储数据,命名规则:keyName_数据类型_字段类型_字段名
            foreach (var item in fields)
            {
                // string name = keyName + "_" + dataType.Name + "_" + item.FieldType.Name + "_" + item.Name;
                string name = keyName + "_" + item.Name;
                SaveValue(item.GetValue(value), name);
            }
        }
        //同步数据
        PlayerPrefs.Save();
    }


    //读取数据值
    public object LoadValue(Type type , string keyName)
    {
        //获取int
        if (type == typeof(int))
        {
            //转换存储的string-获取int
            string v = PlayerPrefs.GetString(keyName+"tostr", "0");
            return Convert.ToInt32(v);

            //正常获取int
            // return PlayerPrefs.GetInt(keyName, 0);

        }
        //获取float
        else if (type == typeof(float))
        {
            return PlayerPrefs.GetFloat(keyName, 0);
        }
        //获取string
        else if (type == typeof(string))
        {
            return PlayerPrefs.GetString(keyName, "");
        }
        //获取bool
        else if (type == typeof(bool))
        {
            return PlayerPrefs.GetInt(keyName, 0) == 1;
        }
        //获取List
        else if (typeof(IList).IsAssignableFrom(type))
        {
            //获取长度
            int count = PlayerPrefs.GetInt(keyName, 0);
            // //实例化list

            IList list  = Activator.CreateInstance(type) as IList;
            for (int i = 0; i < count; i++)
            {
                //获取对应的子项数据,放入列表
                list.Add(LoadValue(type.GetGenericArguments()[0], keyName + i));
            }
            return list;
        }
        //获取Dictinary字典
        else if (typeof(IDictionary).IsAssignableFrom(type))
        {
            //获取长度
            int count = PlayerPrefs.GetInt(keyName, 0);
            //实例化Dictionary
            IDictionary dic = Activator.CreateInstance(type) as IDictionary;
            for (int i = 0; i < count; i++)
            {
                //获取对应的子项 
                dic.Add(LoadValue(type.GetGenericArguments()[0], keyName + "_key_" + i), LoadValue(type.GetGenericArguments()[1], keyName + "_value_" + i));
            }
            return dic;
        }
        //获取其他类型
        else
        {
            //实例化对象
            object data = Activator.CreateInstance(type);
            //获取成员变量
            FieldInfo[] fields = type.GetFields();
            //根据成员变量获取对应名称,keyname_类名_成员类型_成员名
            for (int i = 0; i < fields.Length; i++)
            {
                FieldInfo info = fields[i];
                // string name = keyName + "_" + type.Name + "_" + info.FieldType.Name + "_" + info.Name;
                string name = keyName + "_" + info.Name;
                //读取数据,设置给data对象
                info.SetValue(data, LoadValue(info.FieldType, name));
            }
            return data;
        }
    }

}

如果你也在学习unity,请关注及点赞,关注和点赞越多,更新越多。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值