Unity study notes–Usage of PlayerPrefs for data persistence
Data persistence
PlayerPrefs related
PlayerPrefs is a class in the Unity game engine used to store and access player preferences and data in the game. It can be used to save the player’s game progress, setting options, highest scores and other information. PlayerPrefs stores data in local files so data is persisted across game restarts.
//PlayerPrefs data storage is similar to key-value pair storage, one key corresponds to one value
//Provides methods to store 3 types of data int float string
//Key: string type
//Value: int float string corresponds to 3 APIs
PlayerPrefs.SetInt("myAge", 18);
PlayerPrefs.SetFloat("myHeight", 177.5f);
PlayerPrefs.SetString("myName", "TonyChang");
//Directly calling Set-related methods will only store the data in memory.
//When the game ends, Unity will automatically save the data to the hard disk.
//If the game does not end normally but crashes, the data will not be saved to the hard disk.
//As long as this method is called, it will be stored in the hard disk immediately.
PlayerPrefs.Save();
//PlayerPrefs is limited. It can only store 3 types of data.
//If you want to store other types of data, you can only reduce the precision or increase the precision for storage.
bool sex = true;
PlayerPrefs.SetInt("sex", sex ? 1 : 0);
//If different types are stored with the same key name, they will be overwritten.
PlayerPrefs.SetFloat("myAge", 20.2f);
//Note that at runtime, as long as you set the corresponding key-value pair
//Even if you don't store Save locally immediately
//You can also read information
//int
int age = PlayerPrefs.GetInt("myAge");
print(age);
//The premise is that if the value corresponding to myAge cannot be found, the second parameter of the function will be returned to the default value.
age = PlayerPrefs.GetInt("myAge", 100);
print(age);
//float
float height = PlayerPrefs.GetFloat("myHeight", 1000f);
print(height);
//string
string name = PlayerPrefs.GetString("myName");
print(name);
//The second parameter default value is for us
//That is, when you get data that you don’t have, you can use it to initialize the basic data.
//Determine whether the data exists
if( PlayerPrefs.HasKey("myName") )
{
print("There is key-value pair data corresponding to myName");
}
//Delete the specified key-value pair
PlayerPrefs.DeleteKey("myAge");
//Delete all stored information
PlayerPrefs.DeleteAll();
Where is the data stored in PlayerPrefs stored?
PC side: PlayerPrefs are stored in the registry under HKCU\Software[company name][product name]
Where the company and product names are the names set in “Project Settings”.
Android: /data/data/package name/shared_prefs/pkg-name.xml
The uniqueness of data in PlayerPrefs. The uniqueness of data in PlayerPrefs is determined by key. Different keys determine different data. If different data keys are the same in the same project, data loss will occur. This must be ensured Uniqueness rules for data naming.
Advantages: Easy to use
Disadvantages: Limited storage data types, poor security (directly find the storage location on the device to view settings)
PlayerPrefs storage tool class:
In order to facilitate data storage, use PlayerPrefs to set the storage method and access it!
The main functionsare data reading and data retrieval~ Obtaining data types through reflection and using PlayerPrefs for data storage.
using System;
using System.Collections;
using System.Reflection;
using UnityEngine;
namespace framework
{
///
/// Playerprefs storage class
///
public class PlayerPrefsManager
{
private static PlayerPrefsManager instance=new PlayerPrefsManager();
public static PlayerPrefsManager Instance => instance;
private PlayerPrefsManager()
{
}
///
/// Methods to access data
///
/// Data entity
/// Data name
public void SaveData(object data, string keyName)
{
Type type = data.GetType();
FieldInfo[] infos = type.GetFields();
string tempKey="null";
FieldInfo tempInfo = null;
for (int i = 0; i < infos.Length; i++)
{
//Get data data type
tempInfo = infos[i];
Debug.Log("Types==="+tempInfo);
//Class name + class type + data content name + data type
//As the stored keyName key
tempKey = keyName + "_" + type.Name + "_" + tempInfo.Name
+ "_" + tempInfo.FieldType.Name;
SaveValue(tempInfo.GetValue(data),tempKey);
}
//Get the value
//tempInfo.GetValue(data);
PlayerPrefs.Save();
}
/// /// Type of read data
///
/// Data type to be read
/// The name of the data to be read
/// Return data entity
public object LoadData(Type type, string name)
{
//Get the type in the data
FieldInfo[] infos = type.GetFields();
//Create an entity to store data information
object data = Activator.CreateInstance(type);
string tempName = null;
FieldInfo tempInfo = null;
for (int i = 0; i < infos.Length; i++)
{
tempInfo = infos[i];//Data name in the data structure
tempName = name + "_" + type.Name + "_" +tempInfo.Name+"_"
+tempInfo.FieldType.Name;//Data name type in the data structure
//Loaded container data in the container
//Load data
tempInfo.SetValue(data,LoadValue(tempInfo.FieldType,tempName));
}
return data;
}
///
/// Store specific types of data
///
///
///
private void SaveValue(object value, string keyName)
{
Type fieldType = value.GetType();
if (fieldType == typeof(int))
{
Debug.Log("storage int"+value);
PlayerPrefs.SetInt(keyName,(int)value);
}else if (fieldType == typeof(float))
{
Debug.Log("Storage float"+value);
PlayerPrefs.SetFloat(keyName,(float)value);
}else if (fieldType == typeof(string))
{
Debug.Log("storage string"+value);
PlayerPrefs.SetString(keyName,value.ToString());
}
//For List storage settings
//According to the stored field type and whether the IList is a parent-child relationship
else if(typeof(IList).IsAssignableFrom(fieldType))
{
//Father class installs subclass
IList list=value as IList;
//Storage number of elements
PlayerPrefs.SetInt(keyName,list.Count);
Debug.Log("Storage List length is "+list.Count);
int index = 0;
foreach (var obj in list)
{
//Storage the content of elements in the list
//The naming format is list name + index number
//Recursive call storage
SaveValue(obj,keyName+index);
index++;
}
}else if (typeof(IDictionary).IsAssignableFrom(fieldType))
{
IDictionary dictionary = value as IDictionary;
//Number of stored data
PlayerPrefs.SetInt(keyName,dictionary.Count);
Debug.Log("The length of stored Dic is "+dictionary.Count);
int index = 0;
foreach (var key in dictionary.Keys)
{
//Storage key
SaveValue(key,keyName+"_key_"+index);
//Storage value
SaveValue(dictionary[key],keyName+"_value_"+index);
index++;
}
}//Storage of custom data types for analysis
else
{
SaveData(value,keyName);
}
}
private object LoadValue(Type type, string name)
{
if (type == typeof(int))
{
return PlayerPrefs.GetInt(name,0);
}else if (type == typeof(float))
{
return PlayerPrefs.GetFloat(name,0.0f);
}else if (type == typeof(string))
{
return PlayerPrefs.GetString(name,"");
}else if (typeof(IList).IsAssignableFrom(type))
{
//read list
int count = PlayerPrefs.GetInt(name);
IList tempList=Activator.CreateInstance(type) as IList;
for (int i = 0; i < count; i++)
{
//Get the type of elements stored in the List type.GetGenericArguments()[0]
tempList.Add(LoadValue(type.GetGenericArguments()[0],name+i));
}
return tempList;
}else if (typeof(IDictionary).IsAssignableFrom(type))
{
//Read the dictionary
int count = PlayerPrefs.GetInt(name);
IDictionary tempDictionary=Activator.CreateInstance(type) as IDictionary;
for (int i = 0; i < count; i++)
{
tempDictionary.Add(LoadValue(type.GetGenericArguments()[0], name + "_key_" + i),
LoadValue(type.GetGenericArguments()[1], name + "_value_" + i));
}
return tempDictionary;
}
else
{
//Read the settings of custom class members
return LoadData(type, name);
}
}
}
}
Attachment:
Test script
using System.Collections.Generic;
using UnityEngine;
namespace framework
{
//Notice:
//1 The custom data structure type must have a valid parameterless constructor
public class PlayerInfo
{
public int age;
public string name;
public float height;
public int sex;//0 is female and 1 is male
public ItemInfo ItemInfo;
//list storage test
public List list;
public Dictionary dic;
}
public class ItemInfo
{
public int stu_no;//student number
public int stu_class;//class
publicItemInfo()
{
}
public ItemInfo(int no,int classNo)
{
stu_no = no;
stu_class = classNo;
}
}
///
/// Test class
///
public class TestPlayerPrefsTest:MonoBehaviour
{
private PlayerInfo playerInfo;
private PlayerInfo playerInfo1;
private void Start()
{
//Read data
playerInfo = new PlayerInfo();
// Type fieldType = playerInfo.GetType();
playerInfo.age = 18;
playerInfo.name = "TonyChang";
playerInfo.height = 175.8f;
playerInfo.sex = 1;
playerInfo.ItemInfo = new ItemInfo(2001, 2);
playerInfo.list = new List(){1,5,6,8};
playerInfo.dic = new Dictionary();
playerInfo.dic.Add(1,"Tony");
playerInfo.dic.Add(2,"Jeny");
playerInfo.dic.Add(3,"JayChou");
//Save data
PlayerPrefsManager.Instance.SaveData(playerInfo,"Player1");
playerInfo1 = PlayerPrefsManager.Instance.LoadData(typeof(PlayerInfo), "Player1") as PlayerInfo;
Debug.Log("age=="+playerInfo1.age);
Debug.Log("name=="+playerInfo1.name);
Debug.Log("sex=="+playerInfo1.sex);
Debug.Log("List[1]=="+playerInfo1.list[1]);
Debug.Log("Dic[1]=="+playerInfo1.dic[1]);
}
}
}
i));
}
return tempDictionary;
}
else
{
//Read the settings of custom class members
return LoadData(type, name);
}
}
}
}
Attachment:
Test script
using System.Collections.Generic;
using UnityEngine;
namespace framework
{
//Notice:
//1 The custom data structure type must have a valid parameterless constructor
public class PlayerInfo
{
public int age;
public string name;
public float height;
public int sex;//0 is female and 1 is male
public ItemInfo ItemInfo;
//list storage test
public List list;
public Dictionary dic;
}
public class ItemInfo
{
public int stu_no;//student number
public int stu_class;//class
publicItemInfo()
{
}
public ItemInfo(int no,int classNo)
{
stu_no = no;
stu_class = classNo;
}
}
///
/// Test class
///
public class TestPlayerPrefsTest:MonoBehaviour
{
private PlayerInfo playerInfo;
private PlayerInfo playerInfo1;
private void Start()
{
//Read data
playerInfo = new PlayerInfo();
// Type fieldType = playerInfo.GetType();
playerInfo.age = 18;
playerInfo.name = "TonyChang";
playerInfo.height = 175.8f;
playerInfo.sex = 1;
playerInfo.ItemInfo = new ItemInfo(2001, 2);
playerInfo.list = new List(){1,5,6,8};
playerInfo.dic = new Dictionary();
playerInfo.dic.Add(1,"Tony");
playerInfo.dic.Add(2,"Jeny");
playerInfo.dic.Add(3,"JayChou");
//Save data
PlayerPrefsManager.Instance.SaveData(playerInfo,"Player1");
playerInfo1 = PlayerPrefsManager.Instance.LoadData(typeof(PlayerInfo), "Player1") as PlayerInfo;
Debug.Log("age=="+playerInfo1.age);
Debug.Log("name=="+playerInfo1.name);
Debug.Log("sex=="+playerInfo1.sex);
Debug.Log("List[1]=="+playerInfo1.list[1]);
Debug.Log("Dic[1]=="+playerInfo1.dic[1]);
}
}
}