说明
了解Unity的应该知道Unity提供了PlayerPrefs类去对简单数据(Int,Float,String)进行本地持久化的读写,实际上还有一个EasySave插件能对更多复杂的数据进行本地化的存储,但是其功能又过于繁杂,日常也不一定会用到,那么此处就对于Unity的PlayerPrefs进行封装,并进行一些扩展,比如将对象或对象集合转成json文件或这二进制文件持久化存储到本地
注意事项
1.由于Unity自身的JsonUtility不支持集合和字典还有哈希的序列化,所以此处使用的Litjson库
2.进行二进制序列化的时候类需要为[Serializable]可序列化的,对于Litjson则不需要
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.RegularExpressions;
using UnityEngine;
using LitJson;
using System;
//by cuiyh
public class C_PlayerPrefs
{
static System.Text.Encoding defaultEncoding = System.Text.Encoding.UTF8;
const string prefixPath = "/c_caches/";
/// <summary>
/// 存储路径
/// </summary>
static string _directory;
public static string directory
{
get
{
if (string.IsNullOrEmpty(_directory))
{
_directory = Application.persistentDataPath + "/" + prefixPath;
if (!Directory.Exists(_directory))
{
Directory.CreateDirectory(_directory);
}
}
return _directory;
}
}
/// <summary>
/// 检测输入的键是否合法
/// </summary>
/// <param name="inputKey"></param>
/// <returns></returns>
static bool CheckKeyIsLegitimate(string inputKey)
{
return !Regex.IsMatch(inputKey, @"[\\/:*?""<>|,]+"); // \/:*?"<>|, 为不符合要求的文件名称字符
}
/// <summary>
/// 根据key获取完整路径
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
static string getKeyFullPath(string key)
{
return directory + "/" + key;
}
/// <summary>
/// Int本地持久化存储
/// </summary>
/// <param name="key">键</param>
/// <param name="val">值</param>
/// <param name="useUnityDefaultFunc">是否使用默认的Unity方法</param>
public static void SetInt(string key, int val, bool useUnityDefaultFunc = true)
{
if (useUnityDefaultFunc)
{
PlayerPrefs.SetInt(key, val);
}
else
{
SetString(key, val.ToString());
}
}
/// <summary>
/// Int获取对应键值
/// </summary>
/// <param name="key">键</param>
/// <param name="useUnityDefaultFunc">是否使用默认的Unity方法</param>
public static int GetInt(string key, bool useUnityDefaultFunc = true)
{
if (useUnityDefaultFunc)
{
return PlayerPrefs.GetInt(key);
}
else
{
try
{
return int.Parse(GetString(key));
}
catch (Exception ex)
{
throw new System.Exception(ex.Message);
}
}
}
/// <summary>
/// Float本地持久化存储
/// </summary>
/// <param name="key">键</param>
/// <param name="val">值</param>
/// <param name="useUnityDefaultFunc">是否使用默认的Unity方法</param>
public static void SetFloat(string key, float val, bool useUnityDefaultFunc = true)
{
if (useUnityDefaultFunc)
{
PlayerPrefs.SetFloat(key, val);
}
else
{
SetString(key, val.ToString());
}
}
/// <summary>
/// Float获取对应键值
/// </summary>
/// <param name="key">键</param>
/// <param name="useUnityDefaultFunc">是否使用默认的Unity方法</param>
public static float GetFloat(string key, bool useUnityDefaultFunc = true)
{
if (useUnityDefaultFunc)
{
return PlayerPrefs.GetFloat(key);
}
else
{
try
{
return float.Parse(GetString(key));
}
catch (Exception ex)
{
throw new System.Exception(ex.Message);
}
}
}
/// <summary>
/// 设置本地存储字符串
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
public static void SetString(string key, string value, bool useUnityDefaultFunc = true)
{
if (useUnityDefaultFunc)
{
PlayerPrefs.SetString(key, value);
}
else
{
if (CheckKeyIsLegitimate(key))
{
File.WriteAllText(getKeyFullPath(key), value, defaultEncoding);
}
}
}
/// <summary>
/// 获取本地存储字符串
/// </summary>
/// <param name="key">键</param>
public static string GetString(string key, bool useUnityDefaultFunc = true)
{
string res = string.Empty;
if (useUnityDefaultFunc)
{
res = PlayerPrefs.GetString(key);
}
else
{
if (CheckKeyIsLegitimate(key))
{
if (File.Exists(getKeyFullPath(key)))
{
res = File.ReadAllText(getKeyFullPath(key), defaultEncoding);
}
}
}
return res;
}
/// <summary>
/// 删除key
/// </summary>
/// <param name="key"></param>
public static void DeleteKey(string key)
{
if (CheckKeyIsLegitimate(key))
{
string fullPath = getKeyFullPath(key);
if (File.Exists(fullPath))
File.Delete(fullPath);
PlayerPrefs.DeleteKey(key);
}
}
/// <summary>
/// 将对象通过json存储到本地
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="content"></param>
public static void Set_T_2_LitJson<T>(string key, T content)
{
if (CheckKeyIsLegitimate(key))
{
File.WriteAllText(getKeyFullPath(key), JsonMapper.ToJson(content), defaultEncoding);
}
}
/// <summary>
/// 将json字符串从本地读出转换为对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public static T Get_T_4_LitJson<T>(string key)
{
T tResult = default(T);
if (CheckKeyIsLegitimate(key))
{
string fullPath = getKeyFullPath(key);
if (File.Exists(fullPath))
{
string json = File.ReadAllText(fullPath, defaultEncoding);
tResult = JsonMapper.ToObject<T>(json);
}
}
return tResult;
}
/// <summary>
/// 将T通过Litjson转化为json写入到文本
/// </summary>
/// <typeparam name="T">要写入的类型,必须是可以被LitJson转化的类型</typeparam>
/// <param name="key">键</param>
/// <param name="content">写入T的内容</param>
public static void Set_T_2_Bin<T>(string key, T content)
{
if (CheckKeyIsLegitimate(key))
{
Serialization<T>(key, content);
}
}
/// <summary>
/// 将文本通过Litjson转化为T对象读取出来
/// </summary>
/// <typeparam name="T">要读取的类型,必须是可以被LitJson转化的类型</typeparam>
/// <param name="key">键</param>
/// <returns></returns>
public static T Get_T_4_Bin<T>(string key)
{
T tResult = default(T);
if (CheckKeyIsLegitimate(key))
{
tResult = DeSerialization<T>(key);
}
return tResult;
}
/// <summary>
/// 将T对象序列化写入到文件中
/// </summary>
/// <typeparam name="T">T必须是可被序列化的</typeparam>
/// <param name="fileName">文件名</param>
/// <param name="content">T</param>
public static void Serialization<T>(string fileName, T content)
{
using (FileStream fs = new FileStream(getKeyFullPath(fileName), FileMode.OpenOrCreate))
{
BinaryFormatter bfFormatter = new BinaryFormatter();
bfFormatter.Serialize(fs, content);
}
}
/// <summary>
/// 将T对象反序列化从文件中读取
/// </summary>
/// <typeparam name="T">T必须是可被序列化的</typeparam>
/// <param name="fileName">文件名</param>
/// <param name="content">T</param>
/// <returns></returns>
public static T DeSerialization<T>(string fileName)
{
using (FileStream fs = new FileStream(getKeyFullPath(fileName), FileMode.OpenOrCreate))
{
BinaryFormatter bfFormatter = new BinaryFormatter();
return (T)bfFormatter.Deserialize(fs);
}
}
}
Demo
using System;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
class Person
{
public int age;
public string name;
public List<int> luckNum = new List<int>() { 0, 1 };
}
public class ZTest : MonoBehaviour
{
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
Debug.Log("按下Q设置Key : list_cache");
Person p1 = new Person() { name = "loom1", age = 18 };
Person p2 = new Person() { name = "loom2", age = 19 };
Person p3 = new Person() { name = "loom3", age = 20 };
Person p4 = new Person() { name = "loom4", age = 21 };
Person p5 = new Person() { name = "loom5", age = 22 };
Person p6 = new Person() { name = "loom6", age = 23 };
Person p7 = new Person() { name = "loom7", age = 24 };
Person p8 = new Person() { name = "loom8", age = 25 };
List<Person> lst1 = new List<Person>() { p1, p2 };
List<Person> lst2 = new List<Person>() { p3, p4 };
List<Person> lst3 = new List<Person>() { p5, p6 };
List<Person> lst4 = new List<Person>() { p7, p8 };
List<List<Person>> lsts1 = new List<List<Person>>() { lst1, lst2 };
List<List<Person>> lsts2 = new List<List<Person>>() { lst3, lst4 };
List<List<List<Person>>> lstss = new List<List<List<Person>>>() { lsts1, lsts2 };
C_PlayerPrefs.Set_T_2_LitJson("list_cache_json", lstss);
C_PlayerPrefs.Set_T_2_Bin("list_cache_bin", lstss);
}
if (Input.GetKeyDown(KeyCode.W))
{
Debug.Log("按下W读取Key : list_cache");
List<List<List<Person>>> lst_json = C_PlayerPrefs.Get_T_4_LitJson<List<List<List<Person>>>>("list_cache_json");
List<List<List<Person>>> lst_bin = C_PlayerPrefs.Get_T_4_Bin<List<List<List<Person>>>>("list_cache_bin");
Debug.Log("json:" + lst_json.Count + "___bin:" + lst_bin.Count);
}
if (Input.GetKeyDown(KeyCode.E))
{
Debug.Log("按下E设置Key : dict_cache");
Person p1 = new Person() { name = "loom1", age = 18 };
Person p2 = new Person() { name = "loom2", age = 19 };
Person p3 = new Person() { name = "loom3", age = 20 };
Person p4 = new Person() { name = "loom4", age = 21 };
Person p5 = new Person() { name = "loom5", age = 22 };
Person p6 = new Person() { name = "loom6", age = 23 };
Person p7 = new Person() { name = "loom7", age = 24 };
Person p8 = new Person() { name = "loom8", age = 25 };
Dictionary<string, Person> dics = new Dictionary<string, Person>() {
{ p1.name,p1 },
{ p2.name,p2 },
{ p3.name,p3 },
{ p4.name,p4 },
{ p5.name,p5 },
{ p6.name,p6 },
{ p7.name,p7 },
{ p8.name,p8 },
};
C_PlayerPrefs.Set_T_2_LitJson("dict_cache_json", dics);
C_PlayerPrefs.Set_T_2_Bin("dict_cache_bin", dics);
}
if (Input.GetKeyDown(KeyCode.R))
{
Debug.Log("按下R读取Key : dict_cache");
Dictionary<string, Person> dics_json = C_PlayerPrefs.Get_T_4_LitJson<Dictionary<string, Person>>("dict_cache_json");
Dictionary<string, Person> dics_bin = C_PlayerPrefs.Get_T_4_Bin<Dictionary<string, Person>>("dict_cache_bin");
Debug.Log("json:" + dics_json.Count + "___bin:" + dics_bin.Count);
}
}
}
image.png
image.png
image.png
网友评论