引擎自身只给了3种保存的的方法,而有时候我们要保存一个自己定义的类型,如:
public class Weapon
{
public int id;
public string name;
public float damage;
public int bullet;
public int price;
//还有一个接口和两个方法没有写出来,下文讲到的时候再给出完整的类
}
如果这些数据是固定的话,我们可以用JSON来保存并读取,但是如果每一个实例的数据都不一样呢,我们要是用自带的方法来保存的话是很费劲的。
而游戏自带的保存字符串的方法,给了我们发挥的空间。用这个方法,我们可以保存上面自己定义的类型:
using System.Text;
public static void SetArray<T>(string key, params T[] array)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.Length; i++)
{
sb.Append(array[i].ToString());
if (i < array.Length - 1)
sb.Append("|");
}
PlayerPrefs.SetString(key, sb.ToString());
}
然后就是读取的方法:
public static T[] GetArray<T>(string key)
where T:IAssignedWithString,new()
{
//有时候会保存一个空的数组,当读取到的是空的时返回一个空的数组
if (PlayerPrefs.HasKey(key) && PlayerPrefs.GetString(key)!="")
{
string[] arraySlipt = PlayerPrefs.GetString(key).Split('|');
T[] array = new T[arraySlipt.Length];
for (int i = 0; i < array.Length; i++)
{
array[i] = (T)new T().AssignedWithString(arraySlipt[i]);
}
return array;
}
return new T[0];
}
这个方法有两个约束:
1.new()约束:保证这个方法能实例出该类型。
2.IAssignedWithString接口约束:保证每个自定义类都有该实例方法。
这个约束的定义为:
public interface IAssignedWithString
{
object AssignedWithString(string tempString);
}
这个接口方法的作用是通过接收一个字符串,给实现该接口的类的实例赋值,并返回该实例:
下面是这个类的完整定义:
public class Weapon : IAssignedWithString
{
public int id;
public string name;
public float damage;
public int bullet;
public int price;
//不要使用“|”做分割符,否则会和上面的读取方法冲突
public override string ToString()
{
return string.Format("{0},{1},{2},{3},{4}", id, name, damage, bullet, price);
}
public object AssignedWithString(string tempString)
{
string[] s = tempString.Split(',');
Weapon w = new Weapon();
//下面可以用2个构造方法代替
w.id = int.Parse(s[0]);
w.name = s[1];
w.damage = float.Parse(s[2]);
w.bullet = int.Parse(s[3]);
w.price = int.Parse(s[4]);
return w;
}
}
下面是一个使用方法:
//声明一个数组
public List<Weapon> weapons = new List<weapon>();
//保存,ps:该方法我写在PlayerPrsX类下。
PlayerPrsX.SetArray("weapons",weapons.ToArray());
//读取
weapons = new List<Weapon>(PlayerPrsX.GetArray<Weapon>("weapons"));