Unity的PlayerPrefab 只能保存 Int float string 三种类型。
下面提供可保存所有类型,并且可直接读取的方式。
#region Namespace
using System;
using Newtonsoft.Json;
using UnityEngine;
#endregion
/// <summary>
/// 本地数据存储 运用json 序列化 反序列化
/// </summary>
public class DataStorageHelper
{
// 所有的本地存储数据KEY都提供在这里
public const string DsStudentsStorage = "DsStudentsStorage";
public static T LoadData<T>(string key)
{
if (!PlayerPrefs.HasKey(key))
{
Debug.Log("Use default data: " + key);
return default(T);
}
try
{
T ret;
if (typeof(T) == typeof(int) || typeof(T) == typeof(uint))
{
ret = (T) Convert.ChangeType(PlayerPrefs.GetInt(key), typeof(T));
}
else if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
{
ret = (T) Convert.ChangeType(PlayerPrefs.GetFloat(key), typeof(T));
}
else if (typeof(T) == typeof(string))
{
ret = (T) Convert.ChangeType(PlayerPrefs.GetString(key), typeof(T));
}
else
{
string txt = PlayerPrefs.GetString(key);
ret = JsonConvert.DeserializeObject<T>(txt);
}
return ret;
}
catch (Exception e)
{
Debug.LogWarning("读取配置错误, key = " + key + ", " + e);
}
return default(T);
}
public static bool SaveData<T>(string key, T source, bool immedSave = true)
{
Type sourceType = typeof(T);
try
{
string valueStr;
if (sourceType == typeof(int) || sourceType == typeof(uint))
{
int value = (int) Convert.ChangeType(source, typeof(int));
PlayerPrefs.SetInt(key, value);
}
else if (sourceType == typeof(float) || sourceType == typeof(double))
{
float value = (float) Convert.ChangeType(source, typeof(float));
PlayerPrefs.SetFloat(key, value);
}
else if (sourceType == typeof(string))
{
valueStr = (string) Convert.ChangeType(source, typeof(string));
PlayerPrefs.SetString(key, valueStr);
}
else
{
valueStr = JsonConvert.SerializeObject(source);
PlayerPrefs.SetString(key, valueStr);
}
if (immedSave)
{
PlayerPrefs.Save();
}
return true;
}
catch (Exception e)
{
}
return false;
}
// 清除某个特定KEY的本地数据
public static void ClearData(string key)
{
PlayerPrefs.DeleteKey(key);
}
// 清楚所有的本地数据
public static void ClearAllData()
{
ClearData(DsStudentsStorage);
}
}
运用到json的序列化和反序列化:Newtonsoft.Json (点击可下载)。
测试代码:我们每次开启的时候读取本地数据。关闭的时候,自动的加一条数据做测试用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Student
{
public int Number; // 学号
public string Name;
public int Age;
}
// 测试代码,随便挂在哪个GameObject下
public class Main : MonoBehaviour
{
private Dictionary<int, Student> m_dicStudents = new Dictionary<int, Student>();
private bool m_bStart = false;
// Start is called before the first frame update
void Start()
{
m_bStart = true;
// 根据类型,key 读取本地数据
m_dicStudents = DataStorageHelper.LoadData<Dictionary<int, Student>>(DataStorageHelper.DsStudentsStorage);
if (null == m_dicStudents)
{
m_dicStudents = new Dictionary<int, Student>();
}
// 打印本地数据
foreach (var item in m_dicStudents.Values)
{
Debug.Log("Number:" + item.Number + " Name:" + item.Name + " Age:" + item.Age);
}
}
private void AddStudents()
{
// 学号和数量一致,递增
int nCount = m_dicStudents.Count + 1;
Student st = new Student();
st.Name = "张 " + nCount.ToString();
st.Age = Random.Range(6, 18);
st.Number = nCount;
m_dicStudents.Add(nCount, st);
}
private void OnDestroy()
{
if (m_bStart)
{
// 关闭运行的时候,加入一个学生信息
AddStudents();
// 保存到本地
DataStorageHelper.SaveData(DataStorageHelper.DsStudentsStorage, m_dicStudents);
}
}
// Update is called once per frame
void Update()
{
}
}
运行结果:
谢谢!