孙广东 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 字符串,然后在字符串数组中的所有条目都都融合成一个单一的字符串和追加到索引数组。
提供的类型都有:
比如 调用:
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); } }