PlayerPrefs存储Vector3等结构数据
孙广东 2016.3.31
之前有网友询问这个问题, 当时我仅仅是 提供了一个思路, 使用json序列化、反序列化。
以下就写出两种(都是仅仅能变成字符串)
1、json的序列化、反序列化方式
JsonFx.Json.JsonReader.Deserialize(data);
JsonFx.Json.JsonWriter.Serialize(classObject);
使用了插件: JsonFx.dll
以下是使用的一个案例
using UnityEngine; using System.Collections; using System.Collections.Generic; public class DataManager : MonoBehaviour { //sets the different kind of data into the player prefs... //sets the coins data(position and rotation)... public void setCoinsData(GameObject coins) { int coinCounter = 0; for (int i = 0; i < coins.transform.childCount; i++) { coinCounter++; string key = coins.name + "" + coinCounter; //Coins Tag,Position,Rotation are passed in the Constructor. CoinsData coinData = new CoinsData(key, coins.transform.GetChild(i).position, coins.transform.GetChild(i).rotation); //String data stores data string data = JsonFx.Json.JsonWriter.Serialize(coinData); // Finally storing my Data i.e parsed from jason parser in Player Prefs PlayerPrefs.SetString(coins.tag + "" + coinCounter, data); } } //gets the activated gold coins data(position and rotation)... public GameObject getCoinsData() { GameObject coins = GameObject.FindGameObjectWithTag("Coin"); for (int i = 0; i < coins.transform.childCount; i++) { if (coinCounter > 0) { string data = PlayerPrefs.GetString(coins.tag + "" + coinCounter); // Storing Vector3 Data in Jason. CoinsData coinData = JsonFx.Json.JsonReader.Deserialize(data); string key = coins.name + "" + coinCounter; coinData.coinPositionData = coinData.data [key]; // Get Coin data. coins.transform.GetChild(i).position = new Vector3(coinData.coinPositionData.position.x, coinData.coinPositionData.position.y, coinData.coinPositionData.position.z); coins.transform.GetChild(i).rotation = new Quaternion(coinData.coinPositionData.rotation.x, coinData.coinPositionData.rotation.y, coinData.coinPositionData.rotation.z, coinData.coinPositionData.rotation.w); coins.transform.GetChild(i).gameObject.SetActive(true); coinCounter--; } else { coins.transform.GetChild(i).gameObject.SetActive(false); } } return coins; } class CoinsData { public PositionData coinPositionData = new PositionData(); // Storing Coin Data in Dictonary. public Dictionary data = new Dictionary(); public CoinsData(string key, Vector3 coinPosition, Quaternion coinRotation) { // Get popstion of coin at run time coinPositionData.position = new Cords(coinPosition.x, coinPosition.y, coinPosition.z); coinPositionData.rotation = new Rotation(coinRotation.x, coinRotation.y, coinRotation.z, coinRotation.w); // Add data to dictionary if (key != null) data.Add(key, coinPositionData); } // Default Constructer is needed when u r using Jason Parsing. public CoinsData() { } } //Get Coins Postion class PositionData { public Cords position; public Rotation rotation; } // Get Coins Cords class Cords { public float x, y, z; public Cords(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } public Cords() { } } // Get Coin Rotation class Rotation { public float x, y, z, w; public Rotation(float x, float y, float z, float w) { this.x = x; this.y = y; this.z = z; this.w = w; } public Rotation() { } } }
注: 当然了能够使用 Unity5.2/3之后加入 的 JsonUtility 类。 更加方便!
!!
2、自己写一个 一个形式
比方我们在存储一个数组 ,就是把每一个元素 用 “|”连接成一个字符串,
读取获取的时候在 依据 “|”截取每一个元素即可了 。
原理就是这样。
http://wiki.unity3d.com/index.php/ArrayPrefs2
虽然这些功能使它易于保存数组,PlayerPrefs 更适合少量的数据,像本地存储少于十个列表等。 PlayerPrefsX 并不打算把 PlayerPrefs 变成一个数据库系统。
假设你有大量的数据,您应改用标准磁盘 IO 功能。
PlayerPrefsX 是基于 PlayerPrefs.SetString,保存为一个数组(详细而言。一个字符数组)。所以。保存浮点数和整数的数组时,每一个数字转换为 4 个字节,并存储到字节数组中。总字节数组转换成 base64,然后另存为一个字符串。当保存一个布尔值数组,每一个布尔值被转换为一个字节数组。它再次转换为 base64 字符串,并保存在单个位。与字符串数组的字节数组索引是建造之初。当中的每一个字节包括各自的字符串输入从字符串数组的长度。
这是转换为 base64 字符串。然后在字符串数组中的全部条目都都融合成一个单一的字符串和追加到索引数组。
提供的类型都有:
- PlayerPrefsX.SetBool
- PlayerPrefsX.GetBool
- PlayerPrefsX.SetLong (fixme: C# only)
- PlayerPrefsX.GetLong (fixme: C# only)
- PlayerPrefsX.SetVector2
- PlayerPrefsX.GetVector2
- PlayerPrefsX.SetVector3
- PlayerPrefsX.GetVector3
- PlayerPrefsX.SetQuaternion
- PlayerPrefsX.GetQuaternion
- PlayerPrefsX.SetColor
- PlayerPrefsX.GetColor
- PlayerPrefsX.SetIntArray
- PlayerPrefsX.GetIntArray
- PlayerPrefsX.SetFloatArray
- PlayerPrefsX.GetFloatArray
- PlayerPrefsX.SetBoolArray
- PlayerPrefsX.GetBoolArray
- PlayerPrefsX.SetStringArray
- PlayerPrefsX.GetStringArray
- PlayerPrefsX.SetVector2Array
- PlayerPrefsX.GetVector2Array
- PlayerPrefsX.SetVector3Array
- PlayerPrefsX.GetVector3Array
- PlayerPrefsX.SetQuaternionArray
- PlayerPrefsX.GetQuaternionArray
- PlayerPrefsX.SetColorArray
- PlayerPrefsX.GetColorArray
比方 调用:
var coordinates = Vector2(.4,.2);
PlayerPrefsX.SetVector2 ("Coords", coordinates);
或者:
var aList = new List.<int>();
for (i = 0; i < 10; i++) aList.Add(i);
var anArray : int[] = aList.ToArray();
PlayerPrefsX.SetIntArray ("Numbers", anArray);
var numberArray = PlayerPrefsX.GetIntArray("Numbers");
详细代码例如以下:
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic; public class PlayerPrefsX
{
static private int endianDiff1;
static private int endianDiff2;
static private int idx;
static private byte [] byteBlock; enum ArrayType {Float, Int32, Bool, String, Vector2, Vector3, Quaternion, Color} public static bool SetBool ( String name, bool value)
{
try
{
PlayerPrefs.SetInt(name, value? 1 : 0);
}
catch
{
return false;
}
return true;
} public static bool GetBool (String name)
{
return PlayerPrefs.GetInt(name) == 1;
} public static bool GetBool (String name, bool defaultValue)
{
return (1==PlayerPrefs.GetInt(name, defaultValue?1:0));
} public static long GetLong(string key, long defaultValue)
{
int lowBits, highBits;
SplitLong(defaultValue, out lowBits, out highBits);
lowBits = PlayerPrefs.GetInt(key+"_lowBits", lowBits);
highBits = PlayerPrefs.GetInt(key+"_highBits", highBits); // unsigned, to prevent loss of sign bit.
ulong ret = (uint)highBits;
ret = (ret << 32);
return (long)(ret | (ulong)(uint)lowBits);
} public static long GetLong(string key)
{
int lowBits = PlayerPrefs.GetInt(key+"_lowBits");
int highBits = PlayerPrefs.GetInt(key+"_highBits"); // unsigned, to prevent loss of sign bit.
ulong ret = (uint)highBits;
ret = (ret << 32);
return (long)(ret | (ulong)(uint)lowBits);
} private static void SplitLong(long input, out int lowBits, out int highBits)
{
// unsigned everything, to prevent loss of sign bit.
lowBits = (int)(uint)(ulong)input;
highBits = (int)(uint)(input >> 32);
} public static void SetLong(string key, long value)
{
int lowBits, highBits;
SplitLong(value, out lowBits, out highBits);
PlayerPrefs.SetInt(key+"_lowBits", lowBits);
PlayerPrefs.SetInt(key+"_highBits", highBits);
} public static bool SetVector2 (String key, Vector2 vector)
{
return SetFloatArray(key, new float[]{vector.x, vector.y});
} static Vector2 GetVector2 (String key)
{
var floatArray = GetFloatArray(key);
if (floatArray.Length < 2)
{
return Vector2.zero;
}
return new Vector2(floatArray[0], floatArray[1]);
} public static Vector2 GetVector2 (String key, Vector2 defaultValue)
{
if (PlayerPrefs.HasKey(key))
{
return GetVector2(key);
}
return defaultValue;
} public static bool SetVector3 (String key, Vector3 vector)
{
return SetFloatArray(key, new float []{vector.x, vector.y, vector.z});
} public static Vector3 GetVector3 (String key)
{
var floatArray = GetFloatArray(key);
if (floatArray.Length < 3)
{
return Vector3.zero;
}
return new Vector3(floatArray[0], floatArray[1], floatArray[2]);
} public static Vector3 GetVector3 (String key, Vector3 defaultValue)
{
if (PlayerPrefs.HasKey(key))
{
return GetVector3(key);
}
return defaultValue;
} public static bool SetQuaternion (String key, Quaternion vector)
{
return SetFloatArray(key, new float[]{vector.x, vector.y, vector.z, vector.w});
} public static Quaternion GetQuaternion (String key)
{
var floatArray = GetFloatArray(key);
if (floatArray.Length < 4)
{
return Quaternion.identity;
}
return new Quaternion(floatArray[0], floatArray[1], floatArray[2], floatArray[3]);
} public static Quaternion GetQuaternion (String key, Quaternion defaultValue )
{
if (PlayerPrefs.HasKey(key))
{
return GetQuaternion(key);
}
return defaultValue;
} public static bool SetColor (String key, Color color)
{
return SetFloatArray(key, new float[]{color.r, color.g, color.b, color.a});
} public static Color GetColor (String key)
{
var floatArray = GetFloatArray(key);
if (floatArray.Length < 4)
{
return new Color(0.0f, 0.0f, 0.0f, 0.0f);
}
return new Color(floatArray[0], floatArray[1], floatArray[2], floatArray[3]);
} public static Color GetColor (String key , Color defaultValue )
{
if (PlayerPrefs.HasKey(key))
{
return GetColor(key);
}
return defaultValue;
} public static bool SetBoolArray (String key, bool[] boolArray)
{
// Make a byte array that's a multiple of 8 in length, plus 5 bytes to store the number of entries as an int32 (+ identifier)
// We have to store the number of entries, since the boolArray length might not be a multiple of 8, so there could be some padded zeroes
var bytes = new byte[(boolArray.Length + 7)/8 + 5];
bytes[0] = System.Convert.ToByte (ArrayType.Bool); // Identifier
var bits = new BitArray(boolArray);
bits.CopyTo (bytes, 5);
Initialize();
ConvertInt32ToBytes (boolArray.Length, bytes); // The number of entries in the boolArray goes in the first 4 bytes return SaveBytes (key, bytes);
} public static bool[] GetBoolArray (String key)
{
if (PlayerPrefs.HasKey(key))
{
var bytes = System.Convert.FromBase64String (PlayerPrefs.GetString(key));
if (bytes.Length < 5)
{
Debug.LogError ("Corrupt preference file for " + key);
return new bool[0];
}
if ((ArrayType)bytes[0] != ArrayType.Bool)
{
Debug.LogError (key + " is not a boolean array");
return new bool[0];
}
Initialize(); // Make a new bytes array that doesn't include the number of entries + identifier (first 5 bytes) and turn that into a BitArray
var bytes2 = new byte[bytes.Length-5];
System.Array.Copy(bytes, 5, bytes2, 0, bytes2.Length);
var bits = new BitArray(bytes2);
// Get the number of entries from the first 4 bytes after the identifier and resize the BitArray to that length, then convert it to a boolean array
bits.Length = ConvertBytesToInt32 (bytes);
var boolArray = new bool[bits.Count];
bits.CopyTo (boolArray, 0); return boolArray;
}
return new bool[0];
} public static bool[] GetBoolArray (String key, bool defaultValue, int defaultSize)
{
if (PlayerPrefs.HasKey(key))
{
return GetBoolArray(key);
}
var boolArray = new bool[defaultSize];
for(int i=0;i<defaultSize;i++)
{
boolArray[i] = defaultValue;
}
return boolArray;
} public static bool SetStringArray (String key, String[] stringArray)
{
var bytes = new byte[stringArray.Length + 1];
bytes[0] = System.Convert.ToByte (ArrayType.String); // Identifier
Initialize(); // Store the length of each string that's in stringArray, so we can extract the correct strings in GetStringArray
for (var i = 0; i < stringArray.Length; i++)
{
if (stringArray[i] == null)
{
Debug.LogError ("Can't save null entries in the string array when setting " + key);
return false;
}
if (stringArray[i].Length > 255)
{
Debug.LogError ("Strings cannot be longer than 255 characters when setting " + key);
return false;
}
bytes[idx++] = (byte)stringArray[i].Length;
} try
{
PlayerPrefs.SetString (key, System.Convert.ToBase64String (bytes) + "|" + String.Join("", stringArray));
}
catch
{
return false;
}
return true;
} public static String[] GetStringArray (String key)
{
if (PlayerPrefs.HasKey(key)) {
var completeString = PlayerPrefs.GetString(key);
var separatorIndex = completeString.IndexOf("|"[0]);
if (separatorIndex < 4) {
Debug.LogError ("Corrupt preference file for " + key);
return new String[0];
}
var bytes = System.Convert.FromBase64String (completeString.Substring(0, separatorIndex));
if ((ArrayType)bytes[0] != ArrayType.String) {
Debug.LogError (key + " is not a string array");
return new String[0];
}
Initialize(); var numberOfEntries = bytes.Length-1;
var stringArray = new String[numberOfEntries];
var stringIndex = separatorIndex + 1;
for (var i = 0; i < numberOfEntries; i++)
{
int stringLength = bytes[idx++];
if (stringIndex + stringLength > completeString.Length)
{
Debug.LogError ("Corrupt preference file for " + key);
return new String[0];
}
stringArray[i] = completeString.Substring(stringIndex, stringLength);
stringIndex += stringLength;
} return stringArray;
}
return new String[0];
} public static String[] GetStringArray (String key, String defaultValue, int defaultSize)
{
if (PlayerPrefs.HasKey(key))
{
return GetStringArray(key);
}
var stringArray = new String[defaultSize];
for(int i=0;i<defaultSize;i++)
{
stringArray[i] = defaultValue;
}
return stringArray;
} public static bool SetIntArray (String key, int[] intArray)
{
return SetValue (key, intArray, ArrayType.Int32, 1, ConvertFromInt);
} public static bool SetFloatArray (String key, float[] floatArray)
{
return SetValue (key, floatArray, ArrayType.Float, 1, ConvertFromFloat);
} public static bool SetVector2Array (String key, Vector2[] vector2Array )
{
return SetValue (key, vector2Array, ArrayType.Vector2, 2, ConvertFromVector2);
} public static bool SetVector3Array (String key, Vector3[] vector3Array)
{
return SetValue (key, vector3Array, ArrayType.Vector3, 3, ConvertFromVector3);
} public static bool SetQuaternionArray (String key, Quaternion[] quaternionArray )
{
return SetValue (key, quaternionArray, ArrayType.Quaternion, 4, ConvertFromQuaternion);
} public static bool SetColorArray (String key, Color[] colorArray)
{
return SetValue (key, colorArray, ArrayType.Color, 4, ConvertFromColor);
} private static bool SetValue<T> (String key, T array, ArrayType arrayType, int vectorNumber, Action<T, byte[],int> convert) where T : IList
{
var bytes = new byte[(4*array.Count)*vectorNumber + 1];
bytes[0] = System.Convert.ToByte (arrayType); // Identifier
Initialize(); for (var i = 0; i < array.Count; i++) {
convert (array, bytes, i);
}
return SaveBytes (key, bytes);
} private static void ConvertFromInt (int[] array, byte[] bytes, int i)
{
ConvertInt32ToBytes (array[i], bytes);
} private static void ConvertFromFloat (float[] array, byte[] bytes, int i)
{
ConvertFloatToBytes (array[i], bytes);
} private static void ConvertFromVector2 (Vector2[] array, byte[] bytes, int i)
{
ConvertFloatToBytes (array[i].x, bytes);
ConvertFloatToBytes (array[i].y, bytes);
} private static void ConvertFromVector3 (Vector3[] array, byte[] bytes, int i)
{
ConvertFloatToBytes (array[i].x, bytes);
ConvertFloatToBytes (array[i].y, bytes);
ConvertFloatToBytes (array[i].z, bytes);
} private static void ConvertFromQuaternion (Quaternion[] array, byte[] bytes, int i)
{
ConvertFloatToBytes (array[i].x, bytes);
ConvertFloatToBytes (array[i].y, bytes);
ConvertFloatToBytes (array[i].z, bytes);
ConvertFloatToBytes (array[i].w, bytes);
} private static void ConvertFromColor (Color[] array, byte[] bytes, int i)
{
ConvertFloatToBytes (array[i].r, bytes);
ConvertFloatToBytes (array[i].g, bytes);
ConvertFloatToBytes (array[i].b, bytes);
ConvertFloatToBytes (array[i].a, bytes);
} public static int[] GetIntArray (String key)
{
var intList = new List<int>();
GetValue (key, intList, ArrayType.Int32, 1, ConvertToInt);
return intList.ToArray();
} public static int[] GetIntArray (String key, int defaultValue, int defaultSize)
{
if (PlayerPrefs.HasKey(key))
{
return GetIntArray(key);
}
var intArray = new int[defaultSize];
for (int i=0; i<defaultSize; i++)
{
intArray[i] = defaultValue;
}
return intArray;
} public static float[] GetFloatArray (String key)
{
var floatList = new List<float>();
GetValue (key, floatList, ArrayType.Float, 1, ConvertToFloat);
return floatList.ToArray();
} public static float[] GetFloatArray (String key, float defaultValue, int defaultSize)
{
if (PlayerPrefs.HasKey(key))
{
return GetFloatArray(key);
}
var floatArray = new float[defaultSize];
for (int i=0; i<defaultSize; i++)
{
floatArray[i] = defaultValue;
}
return floatArray;
} public static Vector2[] GetVector2Array (String key)
{
var vector2List = new List<Vector2>();
GetValue (key, vector2List, ArrayType.Vector2, 2, ConvertToVector2);
return vector2List.ToArray();
} public static Vector2[] GetVector2Array (String key, Vector2 defaultValue, int defaultSize)
{
if (PlayerPrefs.HasKey(key))
{
return GetVector2Array(key);
}
var vector2Array = new Vector2[defaultSize];
for(int i=0; i< defaultSize;i++)
{
vector2Array[i] = defaultValue;
}
return vector2Array;
} public static Vector3[] GetVector3Array (String key)
{
var vector3List = new List<Vector3>();
GetValue (key, vector3List, ArrayType.Vector3, 3, ConvertToVector3);
return vector3List.ToArray();
} public static Vector3[] GetVector3Array (String key, Vector3 defaultValue, int defaultSize)
{
if (PlayerPrefs.HasKey(key)) {
return GetVector3Array(key);
}
var vector3Array = new Vector3[defaultSize];
for (int i=0; i<defaultSize;i++)
{
vector3Array[i] = defaultValue;
}
return vector3Array;
} public static Quaternion[] GetQuaternionArray (String key)
{
var quaternionList = new List<Quaternion>();
GetValue (key, quaternionList, ArrayType.Quaternion, 4, ConvertToQuaternion);
return quaternionList.ToArray();
} public static Quaternion[] GetQuaternionArray (String key, Quaternion defaultValue, int defaultSize)
{
if (PlayerPrefs.HasKey(key))
{
return GetQuaternionArray(key);
}
var quaternionArray = new Quaternion[defaultSize];
for(int i=0;i<defaultSize;i++)
{
quaternionArray[i] = defaultValue;
}
return quaternionArray;
} public static Color[] GetColorArray (String key)
{
var colorList = new List<Color>();
GetValue (key, colorList, ArrayType.Color, 4, ConvertToColor);
return colorList.ToArray();
} public static Color[] GetColorArray (String key, Color defaultValue, int defaultSize)
{
if (PlayerPrefs.HasKey(key)) {
return GetColorArray(key);
}
var colorArray = new Color[defaultSize];
for(int i=0;i<defaultSize;i++)
{
colorArray[i] = defaultValue;
}
return colorArray;
} private static void GetValue<T> (String key, T list, ArrayType arrayType, int vectorNumber, Action<T, byte[]> convert) where T : IList
{
if (PlayerPrefs.HasKey(key))
{
var bytes = System.Convert.FromBase64String (PlayerPrefs.GetString(key));
if ((bytes.Length-1) % (vectorNumber*4) != 0)
{
Debug.LogError ("Corrupt preference file for " + key);
return;
}
if ((ArrayType)bytes[0] != arrayType)
{
Debug.LogError (key + " is not a " + arrayType.ToString() + " array");
return;
}
Initialize(); var end = (bytes.Length-1) / (vectorNumber*4);
for (var i = 0; i < end; i++)
{
convert (list, bytes);
}
}
} private static void ConvertToInt (List<int> list, byte[] bytes)
{
list.Add (ConvertBytesToInt32(bytes));
} private static void ConvertToFloat (List<float> list, byte[] bytes)
{
list.Add (ConvertBytesToFloat(bytes));
} private static void ConvertToVector2 (List<Vector2> list, byte[] bytes)
{
list.Add (new Vector2(ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes)));
} private static void ConvertToVector3 (List<Vector3> list, byte[] bytes)
{
list.Add (new Vector3(ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes)));
} private static void ConvertToQuaternion (List<Quaternion> list,byte[] bytes)
{
list.Add (new Quaternion(ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes)));
} private static void ConvertToColor (List<Color> list, byte[] bytes)
{
list.Add (new Color(ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes)));
} public static void ShowArrayType (String key)
{
var bytes = System.Convert.FromBase64String (PlayerPrefs.GetString(key));
if (bytes.Length > 0)
{
ArrayType arrayType = (ArrayType)bytes[0];
Debug.Log (key + " is a " + arrayType.ToString() + " array");
}
} private static void Initialize ()
{
if (System.BitConverter.IsLittleEndian)
{
endianDiff1 = 0;
endianDiff2 = 0;
}
else
{
endianDiff1 = 3;
endianDiff2 = 1;
}
if (byteBlock == null)
{
byteBlock = new byte[4];
}
idx = 1;
} private static bool SaveBytes (String key, byte[] bytes)
{
try
{
PlayerPrefs.SetString (key, System.Convert.ToBase64String (bytes));
}
catch
{
return false;
}
return true;
} private static void ConvertFloatToBytes (float f, byte[] bytes)
{
byteBlock = System.BitConverter.GetBytes (f);
ConvertTo4Bytes (bytes);
} private static float ConvertBytesToFloat (byte[] bytes)
{
ConvertFrom4Bytes (bytes);
return System.BitConverter.ToSingle (byteBlock, 0);
} private static void ConvertInt32ToBytes (int i, byte[] bytes)
{
byteBlock = System.BitConverter.GetBytes (i);
ConvertTo4Bytes (bytes);
} private static int ConvertBytesToInt32 (byte[] bytes)
{
ConvertFrom4Bytes (bytes);
return System.BitConverter.ToInt32 (byteBlock, 0);
} private static void ConvertTo4Bytes (byte[] bytes)
{
bytes[idx ] = byteBlock[ endianDiff1];
bytes[idx+1] = byteBlock[1 + endianDiff2];
bytes[idx+2] = byteBlock[2 - endianDiff2];
bytes[idx+3] = byteBlock[3 - endianDiff1];
idx += 4;
} private static void ConvertFrom4Bytes (byte[] bytes)
{
byteBlock[ endianDiff1] = bytes[idx ];
byteBlock[1 + endianDiff2] = bytes[idx+1];
byteBlock[2 - endianDiff2] = bytes[idx+2];
byteBlock[3 - endianDiff1] = bytes[idx+3];
idx += 4;
}
}
还有 新的 针对 这个代码的封装例如以下:
using UnityEngine;
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Reflection; public class PlayerPrefsX2
{
public static T GetObject<T>(string key, T defaultValue) where T : new()
{
Type t = typeof(T);
FieldInfo[] fieldInfos = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.Static |
BindingFlags.DeclaredOnly); var newObj = new T(); foreach (var fieldInfo in fieldInfos)
{
var fieldName = fieldInfo.Name;
var fieldKey = string.Format("{0}-{1}-{2}", t, fieldInfo.MemberType, fieldName); if(fieldInfo.FieldType == typeof(int))
{
var val = PlayerPrefs.GetInt (fieldKey);
Debug.Log (val);
fieldInfo.SetValue(newObj, (int)val);
}
else if(fieldInfo.FieldType == typeof(float))
{
var val = PlayerPrefs.GetFloat (fieldKey);
fieldInfo.SetValue(newObj, (float)val);
}
else if(fieldInfo.FieldType == typeof(string))
{
var val = PlayerPrefs.GetString (fieldKey);
fieldInfo.SetValue(newObj, (string)val);
}
else if(fieldInfo.FieldType == typeof(long))
{
var val = PlayerPrefsX.GetLong (fieldKey);
fieldInfo.SetValue(newObj, (long)val);
}
else if(fieldInfo.FieldType == typeof(Vector2))
{
var val = PlayerPrefsX.GetVector2 (fieldKey, Vector2.zero);
fieldInfo.SetValue(newObj, (Vector2)val);
}
else if(fieldInfo.FieldType == typeof(Quaternion))
{
var val = PlayerPrefsX.GetQuaternion (fieldKey);
fieldInfo.SetValue(newObj, (Quaternion)val);
}
else if(fieldInfo.FieldType == typeof(Color))
{
var val = PlayerPrefsX.GetColor (fieldKey);
fieldInfo.SetValue(newObj, (Color)val);
}
// array.
else if(fieldInfo.FieldType == typeof(int[]))
{
var val = PlayerPrefsX.GetIntArray (fieldKey);
fieldInfo.SetValue(newObj, (int[])val);
}
else if(fieldInfo.FieldType == typeof(float[]))
{
var val = PlayerPrefsX.GetFloatArray (fieldKey);
fieldInfo.SetValue(newObj, (float[])val);
}
else if(fieldInfo.FieldType == typeof(string[]))
{
var val = PlayerPrefsX.GetStringArray (fieldKey);
fieldInfo.SetValue(newObj, (string[])val);
}
else if(fieldInfo.FieldType == typeof(Quaternion[]))
{
var val = PlayerPrefsX.GetQuaternionArray (fieldKey);
fieldInfo.SetValue(newObj, (Quaternion[])val);
}
else if(fieldInfo.FieldType == typeof(Color[]))
{
var val = PlayerPrefsX.GetColorArray (fieldKey);
fieldInfo.SetValue(newObj, (Color[])val);
}
// list.
else if(fieldInfo.FieldType == typeof(List<int>))
{
var val = PlayerPrefsX.GetIntArray (fieldKey);
fieldInfo.SetValue(newObj, val.OfType<int>().ToList());
}
else if(fieldInfo.FieldType == typeof(List<float>))
{
var val = PlayerPrefsX.GetFloatArray (fieldKey);
fieldInfo.SetValue(newObj, val.OfType<float>().ToList());
}
else if(fieldInfo.FieldType == typeof(List<string>))
{
var val = PlayerPrefsX.GetStringArray (fieldKey);
fieldInfo.SetValue(newObj, val.OfType<string>().ToList());
}
else if(fieldInfo.FieldType == typeof(List<Quaternion>))
{
var val = PlayerPrefsX.GetQuaternionArray (fieldKey);
fieldInfo.SetValue(newObj, (Quaternion[])val);
}
else if(fieldInfo.FieldType == typeof(List<Color>))
{
var val = PlayerPrefsX.GetColorArray (fieldKey);
fieldInfo.SetValue(newObj, (Color[])val);
}
// other.
else
{
Debug.LogError("Un known type.");
}
} if (newObj != null)
{
return newObj;
} return defaultValue;
} public static bool SetObject(string name, object value)
{
Type t = value.GetType();
FieldInfo[] fieldInfos = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.Static |
BindingFlags.DeclaredOnly); try
{
foreach (var fieldInfo in fieldInfos)
{
var fieldName = fieldInfo.Name;
var fieldKey = string.Format("{0}-{1}-{2}-{3}", name, t, fieldInfo.MemberType, fieldName); if(fieldInfo.FieldType == typeof(int))
{
var val = (int)fieldInfo.GetValue(value);
PlayerPrefs.SetInt (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(float))
{
var val = (float)fieldInfo.GetValue(value);
PlayerPrefs.SetFloat (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(string))
{
var val = (string)fieldInfo.GetValue(value);
PlayerPrefs.SetString (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(long))
{
var val = (long)fieldInfo.GetValue(value);
PlayerPrefsX.SetLong (fieldKey, val);
}
// Unity val.
else if(fieldInfo.FieldType == typeof(Vector2))
{
var val = (Vector2)fieldInfo.GetValue(value);
PlayerPrefsX.SetVector2 (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(Vector3))
{
var val = (Vector3)fieldInfo.GetValue(value);
PlayerPrefsX.SetVector3 (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(Quaternion))
{
var val = (Quaternion)fieldInfo.GetValue(value);
PlayerPrefsX.SetQuaternion (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(Color))
{
var val = (Color)fieldInfo.GetValue(value);
PlayerPrefsX.SetColor (fieldKey, val);
}
// array.
else if(fieldInfo.FieldType == typeof(int[]))
{
var val = (int[])fieldInfo.GetValue(value);
PlayerPrefsX.SetIntArray (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(float[]))
{
var val = (float[])fieldInfo.GetValue(value);
PlayerPrefsX.SetFloatArray (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(string[]))
{
var val = (string[])fieldInfo.GetValue(value);
PlayerPrefsX.SetStringArray (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(Quaternion[]))
{
var val = (Quaternion[])fieldInfo.GetValue(value);
PlayerPrefsX.SetQuaternionArray (fieldKey, val);
}
else if(fieldInfo.FieldType == typeof(Color[]))
{
var val = (Color[])fieldInfo.GetValue(value);
PlayerPrefsX.SetColorArray (fieldKey, val);
}
// list.
else if(fieldInfo.FieldType == typeof(List<int>))
{
var val = (List<int>)fieldInfo.GetValue(value);
PlayerPrefsX.SetIntArray (fieldKey, val.ToArray());
}
else if(fieldInfo.FieldType == typeof(List<float>))
{
var val = (List<float>)fieldInfo.GetValue(value);
PlayerPrefsX.SetFloatArray (fieldKey, val.ToArray());
}
else if(fieldInfo.FieldType == typeof(List<string>))
{
var val = (List<string>)fieldInfo.GetValue(value);
PlayerPrefsX.SetStringArray (fieldKey, val.ToArray());
}
else if(fieldInfo.FieldType == typeof(List<Quaternion>))
{
var val = (Quaternion[])fieldInfo.GetValue(value);
PlayerPrefsX.SetQuaternionArray (fieldKey, val.ToArray());
}
else if(fieldInfo.FieldType == typeof(List<Color>))
{
var val = (Color[])fieldInfo.GetValue(value);
PlayerPrefsX.SetColorArray (fieldKey, val.ToArray());
}
else
{
Debug.LogError("Un known type.");
}
}
}
catch
{
return false;
}
return true;
}
}
測试例如以下:
using UnityEngine;
using System.Collections; class Hoge
{
public string hogePub;
public int intPub;
private int bar;
private string fuga;
private string hoge;
} public class Test : MonoBehaviour
{
// Use this for initialization
void Start ()
{ var hoge = new Hoge{hogePub="hoge", intPub=100};
PlayerPrefsX2.SetObject("test", hoge); var a = PlayerPrefsX2.GetObject<Hoge> ("test", null);
Debug.Log (a.hogePub);
Debug.Log (a.intPub);
}
}
PlayerPrefs存储Vector3等结构数据的更多相关文章
- PlayerPrefs存储数据在本地的存储位置
PlayerPrefs存储数据时,其在windows的存储路径是注册表: HKEY_CURRENT_USER Software CompanyName ProjectName 其中的CompanyNa ...
- Unity PlayerPrefs 存储的位置
Mac OS 在Mac OS X上PlayerPrefs是存储在~/Library/Preferences文件夹,名为unity.[company name].[product name].plist ...
- 【转】 [Unity3D]手机3D游戏开发:场景切换与数据存储(PlayerPrefs 类的介绍与使用)
http://blog.csdn.net/pleasecallmewhy/article/details/8543181 在Unity中的数据存储和iOS中字典的存储基本相同,是通过关键字实现数据存储 ...
- Unity3d中的PlayerPrefs游戏存档API的扩展
功能 在游戏会话中储存和访问游戏存档.这个是持久化数据储存,比如保存游戏记录. 静态函数 DeleteAll Removes all keys and values from the preferen ...
- Unity 3D 之Playerprefs
Unity3d提供了一个用于本地持久化保存与读取的类——PlayerPrefs.工作原理非常简单,以键值对的形式将数据保存在文件中,然后程序可以根据这个名称取出上次保存的数值. 一.PlayerPre ...
- Unity PlayerPrefs
对于游戏存档,储存最高分,排行榜都需要用到储存,现在存储的方式有很多,可以存本地的Json,XML,Sqlite,还有一种就是unity自带的一种存储PlayerPrefs. 那么这个PlayerPr ...
- Unity3D脚本中文系列教程(十三)
http://dong2008hong.blog.163.com/blog/static/469688272014032334486/ Unity3D脚本中文系列教程(十二) ◆ function G ...
- django-cms 代码研究(一)djangocms是什么
首先用djangocms生成了一个站点(具体参考这里:http://www.cnblogs.com/Tommy-Yu/p/3878488.html),其文件结构如下: 本来以为会很有逼格,结果一看傻眼 ...
- Unity3D 游戏开发应用篇——每日登陆(持久化类实现)
上一篇中我们实现用本地文件实现了持久化类的保存,当然小型数据用PlayerPrefs存储,或者采用XML服务器持久化也行.因为我涉及的角色类和玩家类数据比较多,加上项目要求尽量少与服务器交互,所以采用 ...
随机推荐
- golang 获取statuscode
最近日志打印的时候需要打印状态码,但是因为interface的原因直接获取失败,http.Request里面的response不知道怎么使用,所以就自己重写writeheader,write来截取st ...
- ListView中动态显示隐藏HeaderView和FooterView
ListView中动态显示和隐藏Header&Footer 解决思路: 直接设置HeaderView和FooterView.setVisibility(View.GONE)无效, 布局仍然存在 ...
- 通过ASP.NET Ajax技术模拟实现NBA比赛文字直播功能
文字直播是满足一些观看视频直播而条件不足的球迷所设定的比赛直播方式,例如在长途车上为了能够了解比赛的实时赛况但又限于流量和网速等问题,就出现了文字直播的方式.无论是拥有无线上网卡的笔记本电脑或者手机等 ...
- java反射_01
为什么要用反射? 举个栗子: package com.imooc.reflect; public class Work { // 定义一个word方法 public void word() { Sys ...
- halcon 模板匹配 -- 转化 vector_angle_to_rigid
********************************模板匹配 ********************create_shape_model创建模板,这个函数有许多参数,其中金字塔的级数由N ...
- AI:忧郁的机器人
1.塔奇克马 塔奇克马研究起来哲学,被缴械....... 2.机器人瓦力 孤独等待EVA的瓦力 3.马文 http://www.guokr.com/post/683881/
- 安卓代码迁移:Make.exe: *** [***.o]Error 1
描述:NDK开发中显示,windows环境下NDK开发 解决办法:查找系统环境变量,找到关于Cygwin的环境变量或其他无效的环境变量删除处理.
- c++ 枚举与字符串 比较
读取字符串,然后将这个字符转换为对应的枚举. 如:从屏幕上输入'a',则转换为set枚举中对应的a,源代码如下: //关键函数为char2enum(str,temp); #include using ...
- React Native Windows下环境安装(一)
1.安装chocolatey 以管理员权限运行命令提示符(cmd.exe) @powershell -NoProfile -ExecutionPolicy Bypass -Command " ...
- javascript匿名函数及闭包深入理解及应用
1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没有函数名的函数. 1.1 函数的定义,首先简单介绍一下函数的定义,大致可分为三种方式 第一种: ...