private void DrawMainList() { // The bold table headings EditorGUILayout.BeginHorizontal(); GUILayout.Label("Key", EditorStyles.boldLabel); GUILayout.Label("Value", EditorStyles.boldLabel); GUILayout.Label("Type", EditorStyles.boldLabel, GUILayout.Width(37)); GUILayout.Label("Del", EditorStyles.boldLabel, GUILayout.Width(25)); EditorGUILayout.EndHorizontal(); // Create a GUIStyle that can be manipulated for the various text fields GUIStyle textFieldStyle = new GUIStyle(GUI.skin.textField); // Could be dealing with either the full list or search results, so get the right list List <PlayerPrefPair> activePlayerPrefs = deserializedPlayerPrefs; if (!string.IsNullOrEmpty(searchFilter)) { activePlayerPrefs = filteredPlayerPrefs; } // Cache the entry count int entryCount = activePlayerPrefs.Count; // Record the last scroll position so we can calculate if the user has scrolled this frame lastScrollPosition = scrollPosition; // Start the scrollable area scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); // Ensure the scroll doesn't go below zero if (scrollPosition.y < 0) { scrollPosition.y = 0; } // The following code has been optimised so that rather than attempting to draw UI for every single PlayerPref // it instead only draws the UI for those currently visible in the scroll view and pads above and below those // results to maintain the right size using GUILayout.Space(). This enables us to work with thousands of // PlayerPrefs without slowing the interface to a halt. // Fixed height of one of the rows in the table float rowHeight = 18; // Determine how many rows are visible on screen. For simplicity, use Screen.height (the overhead is negligible) int visibleCount = Mathf.CeilToInt(Screen.height / rowHeight); // Determine the index of the first player pref that should be drawn as visible in the scrollable area int firstShownIndex = Mathf.FloorToInt(scrollPosition.y / rowHeight); // Determine the bottom limit of the visible player prefs (last shown index + 1) int shownIndexLimit = firstShownIndex + visibleCount; // If the actual number of player prefs is smaller than the caculated limit, reduce the limit to match if (entryCount < shownIndexLimit) { shownIndexLimit = entryCount; } // If the number of displayed player prefs is smaller than the number we can display (like we're at the end // of the list) then move the starting index back to adjust if (shownIndexLimit - firstShownIndex < visibleCount) { firstShownIndex -= visibleCount - (shownIndexLimit - firstShownIndex); } // Can't have a negative index of a first shown player pref, so clamp to 0 if (firstShownIndex < 0) { firstShownIndex = 0; } // Pad above the on screen results so that we're not wasting draw calls on invisible UI and the drawn player // prefs end up in the same place in the list GUILayout.Space(firstShownIndex * rowHeight); // For each of the on screen results for (int i = firstShownIndex; i < shownIndexLimit; i++) { // Detect if it's an encrypted player pref (these have key prefixes) bool isEncryptedPair = PlayerPrefsUtility.IsEncryptedKey(activePlayerPrefs[i].Key); // Colour code encrypted player prefs blue if (isEncryptedPair) { if (UsingProSkin) { textFieldStyle.normal.textColor = new Color(0.5f, 0.5f, 1); textFieldStyle.focused.textColor = new Color(0.5f, 0.5f, 1); } else { textFieldStyle.normal.textColor = new Color(0, 0, 1); textFieldStyle.focused.textColor = new Color(0, 0, 1); } } else { // Normal player prefs are just black textFieldStyle.normal.textColor = GUI.skin.textField.normal.textColor; textFieldStyle.focused.textColor = GUI.skin.textField.focused.textColor; } // The full key is the key that's actually stored in player prefs string fullKey = activePlayerPrefs[i].Key; // Display key is used so in the case of encrypted keys, we display the decrypted version instead (in // auto-decrypt mode). string displayKey = fullKey; // Used for accessing the type information stored against the player pref object deserializedValue = activePlayerPrefs[i].Value; // Track whether the auto decrypt failed, so we can instead fallback to encrypted values and mark it red bool failedAutoDecrypt = false; // If this is an encrypted play pref and we're attempting to decrypt them, try to decrypt it! if (isEncryptedPair && automaticDecryption) { // This may throw exceptions (e.g. if private key changes), so wrap in a try-catch try { deserializedValue = PlayerPrefsUtility.GetEncryptedValue(fullKey, (string)deserializedValue); displayKey = PlayerPrefsUtility.DecryptKey(fullKey); } catch { // Change the colour to red to highlight the decrypt failed textFieldStyle.normal.textColor = Color.red; textFieldStyle.focused.textColor = Color.red; // Track that the auto decrypt failed, so we can prevent any editing failedAutoDecrypt = true; } } EditorGUILayout.BeginHorizontal(); // The type of player pref being stored (in auto decrypt mode this works with the decrypted values too) Type valueType; // If it's an encrypted playerpref, we're automatically decrypting and it didn't fail the earlier // auto decrypt test if (isEncryptedPair && automaticDecryption && !failedAutoDecrypt) { // Get the encrypted string string encryptedValue = PlayerPrefs.GetString(fullKey); // Set valueType appropiately based on which type identifier prefix the encrypted string starts with if (encryptedValue.StartsWith(PlayerPrefsUtility.VALUE_FLOAT_PREFIX)) { valueType = typeof(float); } else if (encryptedValue.StartsWith(PlayerPrefsUtility.VALUE_INT_PREFIX)) { valueType = typeof(int); } else if (encryptedValue.StartsWith(PlayerPrefsUtility.VALUE_STRING_PREFIX) || string.IsNullOrEmpty(encryptedValue)) { // Special case here, empty encrypted values will also report as strings valueType = typeof(string); } else { throw new InvalidOperationException("Could not decrypt item, no match found in known encrypted key prefixes"); } } else { // Otherwise fallback to the type of the cached value (for non-encrypted values this will be // correct). For encrypted values when not in auto-decrypt mode, this will return string type valueType = deserializedValue.GetType(); } // Display the PlayerPref key EditorGUILayout.TextField(displayKey, textFieldStyle); // Value display and user editing // If we're dealing with a float if (valueType == typeof(float)) { float initialValue; if (isEncryptedPair && automaticDecryption) { // Automatically decrypt the value if encrypted and in auto-decrypt mode initialValue = PlayerPrefsUtility.GetEncryptedFloat(displayKey); } else { // Otherwise fetch the latest plain value from PlayerPrefs in memory initialValue = PlayerPrefs.GetFloat(fullKey); } // Display the float editor field and get any changes in value float newValue = EditorGUILayout.FloatField(initialValue, textFieldStyle); // If the value has changed if (newValue != initialValue) { // Store the changed value in player prefs, encrypting if necessary if (isEncryptedPair) { string encryptedValue = PlayerPrefsUtility.VALUE_FLOAT_PREFIX + SimpleEncryption.EncryptFloat(newValue); PlayerPrefs.SetString(fullKey, encryptedValue); } else { PlayerPrefs.SetFloat(fullKey, newValue); } // Save PlayerPrefs PlayerPrefs.Save(); } // Display the PlayerPref type GUILayout.Label("float", GUILayout.Width(37)); } else if (valueType == typeof(int)) // if we're dealing with an int { int initialValue; if (isEncryptedPair && automaticDecryption) { // Automatically decrypt the value if encrypted and in auto-decrypt mode initialValue = PlayerPrefsUtility.GetEncryptedInt(displayKey); } else { // Otherwise fetch the latest plain value from PlayerPrefs in memory initialValue = PlayerPrefs.GetInt(fullKey); } // Display the int editor field and get any changes in value int newValue = EditorGUILayout.IntField(initialValue, textFieldStyle); // If the value has changed if (newValue != initialValue) { // Store the changed value in player prefs, encrypting if necessary if (isEncryptedPair) { string encryptedValue = PlayerPrefsUtility.VALUE_INT_PREFIX + SimpleEncryption.EncryptInt(newValue); PlayerPrefs.SetString(fullKey, encryptedValue); } else { PlayerPrefs.SetInt(fullKey, newValue); } // Save PlayerPrefs PlayerPrefs.Save(); } // Display the PlayerPref type GUILayout.Label("int", GUILayout.Width(37)); } else if (valueType == typeof(string)) // if we're dealing with a string { string initialValue; if (isEncryptedPair && automaticDecryption && !failedAutoDecrypt) { // Automatically decrypt the value if encrypted and in auto-decrypt mode initialValue = PlayerPrefsUtility.GetEncryptedString(displayKey); } else { // Otherwise fetch the latest plain value from PlayerPrefs in memory initialValue = PlayerPrefs.GetString(fullKey); } // Display the text (string) editor field and get any changes in value string newValue = EditorGUILayout.TextField(initialValue, textFieldStyle); // If the value has changed if (newValue != initialValue && !failedAutoDecrypt) { // Store the changed value in player prefs, encrypting if necessary if (isEncryptedPair) { string encryptedValue = PlayerPrefsUtility.VALUE_STRING_PREFIX + SimpleEncryption.EncryptString(newValue); PlayerPrefs.SetString(fullKey, encryptedValue); } else { PlayerPrefs.SetString(fullKey, newValue); } // Save PlayerPrefs PlayerPrefs.Save(); } if (isEncryptedPair && !automaticDecryption && !string.IsNullOrEmpty(initialValue)) { // Because encrypted values when not in auto-decrypt mode are stored as string, determine their // encrypted type and display that instead for these encrypted PlayerPrefs PlayerPrefType playerPrefType = (PlayerPrefType)(int)char.GetNumericValue(initialValue[0]); GUILayout.Label(playerPrefType.ToString().ToLower(), GUILayout.Width(37)); } else { // Display the PlayerPref type GUILayout.Label("string", GUILayout.Width(37)); } } // Delete button if (GUILayout.Button("X", GUILayout.Width(25))) { // Delete the key from player prefs PlayerPrefs.DeleteKey(fullKey); // Tell Unity to Save PlayerPrefs PlayerPrefs.Save(); // Delete the cached record so the list updates immediately DeleteCachedRecord(fullKey); } EditorGUILayout.EndHorizontal(); } // Calculate the padding at the bottom of the scroll view (because only visible player pref rows are drawn) float bottomPadding = (entryCount - shownIndexLimit) * rowHeight; // If the padding is positive, pad the bottom so that the layout and scroll view size is correct still if (bottomPadding > 0) { GUILayout.Space(bottomPadding); } EditorGUILayout.EndScrollView(); // Display the number of player prefs GUILayout.Label("Entry Count: " + entryCount); }
private void DrawAddEntry() { // Create a GUIStyle that can be manipulated for the various text fields GUIStyle textFieldStyle = new GUIStyle(GUI.skin.textField); // Create a space EditorGUILayout.Space(); // Heading GUILayout.Label("Add Player Pref", EditorStyles.boldLabel); // UI for whether the new player pref is encrypted and what type it is EditorGUILayout.BeginHorizontal(); newEntryIsEncrypted = GUILayout.Toggle(newEntryIsEncrypted, "Encrypt"); newEntryType = (PlayerPrefType)GUILayout.SelectionGrid((int)newEntryType, new string[] { "float", "int", "string" }, 3); EditorGUILayout.EndHorizontal(); // Key and Value headings EditorGUILayout.BeginHorizontal(); GUILayout.Label("Key", EditorStyles.boldLabel); GUILayout.Label("Value", EditorStyles.boldLabel); EditorGUILayout.EndHorizontal(); // If the new value will be encrypted tint the text boxes blue (in line with the display style for existing // encrypted player prefs) if (newEntryIsEncrypted) { if (UsingProSkin) { textFieldStyle.normal.textColor = new Color(0.5f, 0.5f, 1); textFieldStyle.focused.textColor = new Color(0.5f, 0.5f, 1); } else { textFieldStyle.normal.textColor = new Color(0, 0, 1); textFieldStyle.focused.textColor = new Color(0, 0, 1); } } EditorGUILayout.BeginHorizontal(); // Track the next control so we can detect key events in it GUI.SetNextControlName("newEntryKey"); // UI for the new key text box newEntryKey = EditorGUILayout.TextField(newEntryKey, textFieldStyle); // Track the next control so we can detect key events in it GUI.SetNextControlName("newEntryValue"); // Display the correct UI field editor based on what type of player pref is being created if (newEntryType == PlayerPrefType.Float) { newEntryValueFloat = EditorGUILayout.FloatField(newEntryValueFloat, textFieldStyle); } else if (newEntryType == PlayerPrefType.Int) { newEntryValueInt = EditorGUILayout.IntField(newEntryValueInt, textFieldStyle); } else { newEntryValueString = EditorGUILayout.TextField(newEntryValueString, textFieldStyle); } // If the user hit enter while either the key or value fields were being edited bool keyboardAddPressed = Event.current.isKey && Event.current.keyCode == KeyCode.Return && Event.current.type == EventType.KeyUp && (GUI.GetNameOfFocusedControl() == "newEntryKey" || GUI.GetNameOfFocusedControl() == "newEntryValue"); // If the user clicks the Add button or hits return (and there is a non-empty key), create the player pref if ((GUILayout.Button("Add", GUILayout.Width(40)) || keyboardAddPressed) && !string.IsNullOrEmpty(newEntryKey)) { // If the player pref we're creating is encrypted if (newEntryIsEncrypted) { // Encrypt the key string encryptedKey = PlayerPrefsUtility.KEY_PREFIX + SimpleEncryption.EncryptString(newEntryKey); // Note: All encrypted values are stored as string string encryptedValue; // Calculate the encrypted value if (newEntryType == PlayerPrefType.Float) { encryptedValue = PlayerPrefsUtility.VALUE_FLOAT_PREFIX + SimpleEncryption.EncryptFloat(newEntryValueFloat); } else if (newEntryType == PlayerPrefType.Int) { encryptedValue = PlayerPrefsUtility.VALUE_INT_PREFIX + SimpleEncryption.EncryptInt(newEntryValueInt); } else { encryptedValue = PlayerPrefsUtility.VALUE_STRING_PREFIX + SimpleEncryption.EncryptString(newEntryValueString); } // Record the new player pref in PlayerPrefs PlayerPrefs.SetString(encryptedKey, encryptedValue); // Cache the addition CacheRecord(encryptedKey, encryptedValue); } else { if (newEntryType == PlayerPrefType.Float) { // Record the new player pref in PlayerPrefs PlayerPrefs.SetFloat(newEntryKey, newEntryValueFloat); // Cache the addition CacheRecord(newEntryKey, newEntryValueFloat); } else if (newEntryType == PlayerPrefType.Int) { // Record the new player pref in PlayerPrefs PlayerPrefs.SetInt(newEntryKey, newEntryValueInt); // Cache the addition CacheRecord(newEntryKey, newEntryValueInt); } else { // Record the new player pref in PlayerPrefs PlayerPrefs.SetString(newEntryKey, newEntryValueString); // Cache the addition CacheRecord(newEntryKey, newEntryValueString); } } // Tell Unity to save the PlayerPrefs PlayerPrefs.Save(); // Force a repaint since hitting the return key won't invalidate layout on its own Repaint(); // Reset the values newEntryKey = ""; newEntryValueFloat = 0; newEntryValueInt = 0; newEntryValueString = ""; // Deselect GUI.FocusControl(""); } EditorGUILayout.EndHorizontal(); }
private void DrawAddEntry() { GUIStyle textFieldStyle = new GUIStyle(GUI.skin.textField); // Create a GUIStyle that can be manipulated for the various text fields EditorGUILayout.Space(); // Create a space GUILayout.Label("Add Player Pref", EditorStyles.boldLabel); // Heading // UI for whether the new player pref is encrypted and what type it is EditorGUILayout.BeginHorizontal(); newEntryIsEncrypted = GUILayout.Toggle(newEntryIsEncrypted, "Encrypt"); newEntryType = (PlayerPrefType)GUILayout.SelectionGrid((int)newEntryType, new string[] { "float", "int", "string", "bool", "Color", "Color32", "Vector2", "Vector3", "Vector4", "Quaternion", "Matrix4x4", "Rect", "Bounds" /*,"int[]","string[]", "float[]", "bool[]", "Color[]", "Color32[]", "Vector2[]", "Vector3[]", "Vector4[]", "Quaternion[]", * "Matrix4x4[]", "Rect[]", "Bounds[]"*/}, 6); EditorGUILayout.EndHorizontal(); // Key and Value headings EditorGUILayout.BeginHorizontal(); GUILayout.Label("Key", EditorStyles.boldLabel); GUILayout.Label("Value", EditorStyles.boldLabel); EditorGUILayout.EndHorizontal(); // If the new value will be encrypted tint the text boxes blue (in line with the display style for existing // encrypted player prefs) if (newEntryIsEncrypted) { if (UsingProSkin) { textFieldStyle.normal.textColor = new Color(0.5f, 0.5f, 1); textFieldStyle.focused.textColor = new Color(0.5f, 0.5f, 1); } else { textFieldStyle.normal.textColor = new Color(0, 0, 1); textFieldStyle.focused.textColor = new Color(0, 0, 1); } } EditorGUILayout.BeginHorizontal(); GUI.SetNextControlName("newEntryKey"); // Track the next control so we can detect key events in it newEntryKey = EditorGUILayout.TextField(newEntryKey, textFieldStyle); // UI for the new key text box GUI.SetNextControlName("newEntryValue");// Track the next control so we can detect key events in it // Display the correct UI field editor based on what type of player pref is being created switch (newEntryType) { case PlayerPrefType.Float: newEntryValueFloat = EditorGUILayout.FloatField(newEntryValueFloat, textFieldStyle); break; case PlayerPrefType.Int: newEntryValueInt = EditorGUILayout.IntField(newEntryValueInt, textFieldStyle); break; case PlayerPrefType.String: newEntryValueString = EditorGUILayout.TextField(newEntryValueString, textFieldStyle); break; case PlayerPrefType.Bool: newEntryValueBool = EditorGUILayout.Toggle(newEntryValueBool); break; case PlayerPrefType.Color: newEntryValueColor = EditorGUILayout.ColorField(newEntryValueColor); break; case PlayerPrefType.Color32: newEntryValueColor32 = EditorGUILayout.ColorField(newEntryValueColor32); break; case PlayerPrefType.Vector2: newEntryValueVector2 = EditorGUILayout.Vector2Field(":Vector2:", newEntryValueVector2); break; case PlayerPrefType.Vector3: newEntryValueVector3 = EditorGUILayout.Vector3Field(":Vector3:", newEntryValueVector3); break; case PlayerPrefType.Vector4: newEntryValueVector4 = EditorGUILayout.Vector4Field(":Vector4:", newEntryValueVector4); break; case PlayerPrefType.Rect: newEntryValueRect = EditorGUILayout.RectField(newEntryValueRect); break; case PlayerPrefType.Bounds: newEntryValueBounds = EditorGUILayout.BoundsField(newEntryValueBounds); break; case PlayerPrefType.IntArray: break; } //else if (newEntryType == PlayerPrefType.Quaternion) newEntryValueQuaternion = (Quaternion)EditorGUILayout.Vector4Field(":Quaternion:", (Vector4)newEntryValueQuaternion); //else if (newEntryType == PlayerPrefType.Matrix4x4) newEntryValueMatrix4x4 = EditorGUILayout.Matrix4x4; // If the user hit enter while either the key or value fields were being edited bool keyboardAddPressed = Event.current.isKey && Event.current.keyCode == KeyCode.Return && Event.current.type == EventType.KeyUp && (GUI.GetNameOfFocusedControl() == "newEntryKey" || GUI.GetNameOfFocusedControl() == "newEntryValue"); // If the user clicks the Add button or hits return (and there is a non-empty key), create the player pref if ((GUILayout.Button("Add", GUILayout.Width(40)) || keyboardAddPressed) && !string.IsNullOrEmpty(newEntryKey)) { // If the player pref we're creating is encrypted if (newEntryIsEncrypted) { // Encrypt the key string encryptedKey = PlayerPrefsUtility.KEY_PREFIX + SimpleEncryption.EncryptString(newEntryKey); // Note: All encrypted values are stored as string string encryptedValue = string.Empty; switch (newEntryType) { case PlayerPrefType.Float: encryptedValue = PlayerPrefsUtility.floatValuePrefix + SimpleEncryption.EncryptFloat(newEntryValueFloat); break; case PlayerPrefType.Int: encryptedValue = PlayerPrefsUtility.intValuePrefix + SimpleEncryption.EncryptInt(newEntryValueInt); break; case PlayerPrefType.String: encryptedValue = PlayerPrefsUtility.stringValuePrefix + SimpleEncryption.EncryptString(newEntryValueString); break; case PlayerPrefType.Bool: encryptedValue = PlayerPrefsUtility.boolValuePrefix + SimpleEncryption.EncryptString(newEntryValueBool ? "1" : "0"); break; case PlayerPrefType.Color: encryptedValue = PlayerPrefsUtility.colorValuePrefix + SimpleEncryption.EncryptString(newEntryValueColor.r + "," + newEntryValueColor.g + "," + newEntryValueColor.b + "," + newEntryValueColor.a); break; case PlayerPrefType.Color32: encryptedValue = PlayerPrefsUtility.color32ValuePrefix + SimpleEncryption.EncryptString(newEntryValueColor32.r + "," + newEntryValueColor32.g + "," + newEntryValueColor32.b + "," + newEntryValueColor32.a); break; case PlayerPrefType.Vector2: encryptedValue = PlayerPrefsUtility.vector2ValuePrefix + SimpleEncryption.EncryptString(newEntryValueVector2.x + "," + newEntryValueVector2.y); break; case PlayerPrefType.Vector3: encryptedValue = PlayerPrefsUtility.vector3ValuePrefix + SimpleEncryption.EncryptString(newEntryValueVector3.x + "," + newEntryValueVector3.y + "," + newEntryValueVector3.z); break; case PlayerPrefType.Vector4: encryptedValue = PlayerPrefsUtility.vector4ValuePrefix + SimpleEncryption.EncryptString(newEntryValueVector4.x + "," + newEntryValueVector4.y + "," + newEntryValueVector4.z + "," + newEntryValueVector4.w); break; case PlayerPrefType.Quaternion: encryptedValue = PlayerPrefsUtility.quaternionValuePrefix + SimpleEncryption.EncryptString(newEntryValueQuaternion.x + "," + newEntryValueQuaternion.y + "," + newEntryValueQuaternion.z + "," + newEntryValueQuaternion.w); break; case PlayerPrefType.Matrix4x4: encryptedValue = PlayerPrefsUtility.quaternionValuePrefix + SimpleEncryption.EncryptString(newEntryValueMatrix4x4.m00 + "," + newEntryValueMatrix4x4.m01 + "," + newEntryValueMatrix4x4.m02 + "," + newEntryValueMatrix4x4.m03 + "," + newEntryValueMatrix4x4.m10 + "," + newEntryValueMatrix4x4.m11 + "," + newEntryValueMatrix4x4.m12 + "," + newEntryValueMatrix4x4.m13 + "," + newEntryValueMatrix4x4.m20 + "," + newEntryValueMatrix4x4.m21 + "," + newEntryValueMatrix4x4.m22 + "," + newEntryValueMatrix4x4.m23 + "," + newEntryValueMatrix4x4.m30 + "," + newEntryValueMatrix4x4.m31 + "," + newEntryValueMatrix4x4.m32 + "," + newEntryValueMatrix4x4.m33 + ","); break; case PlayerPrefType.Rect: encryptedValue = PlayerPrefsUtility.rectValuePrefix + SimpleEncryption.EncryptString(newEntryValueRect.x + "," + newEntryValueRect.y + "," + newEntryValueRect.width + "," + newEntryValueRect.height); break; case PlayerPrefType.Bounds: encryptedValue = PlayerPrefsUtility.boundsValuePrefix + SimpleEncryption.EncryptString(newEntryValueBounds.center.x + "," + newEntryValueBounds.center.y + "," + newEntryValueBounds.center.z + "," + newEntryValueBounds.extents.x + "," + newEntryValueBounds.extents.y + "," + newEntryValueBounds.extents.z); break; } // Calculate the encrypted value // Record the new player pref in PlayerPrefs PlayerPrefs.SetString(encryptedKey, encryptedValue); // Cache the addition CacheRecord(encryptedKey, encryptedValue); } else { switch (newEntryType) { case PlayerPrefType.Float: PlayerPrefs.SetFloat(newEntryKey, newEntryValueFloat); // Record the new player pref in PlayerPrefs CacheRecord(newEntryKey, newEntryValueFloat); // Cache the addition break; case PlayerPrefType.Int: PlayerPrefs.SetInt(newEntryKey, newEntryValueInt); // Record the new player pref in PlayerPrefs CacheRecord(newEntryKey, newEntryValueInt); // Cache the addition break; case PlayerPrefType.String: PlayerPrefs.SetString(newEntryKey, newEntryValueString); // Record the new player pref in PlayerPrefs CacheRecord(newEntryKey, newEntryValueString); // Cache the addition break; case PlayerPrefType.Bool: PlayerPrefsUtility.SetBool(newEntryKey, newEntryValueBool); CacheRecord(newEntryKey, newEntryValueBool); break; case PlayerPrefType.Color: PlayerPrefsUtility.SetColor(newEntryKey, newEntryValueColor); CacheRecord(newEntryKey, newEntryValueColor); break; case PlayerPrefType.Color32: PlayerPrefsUtility.SetColor32(newEntryKey, newEntryValueColor32); CacheRecord(newEntryKey, newEntryValueColor32); break; case PlayerPrefType.Vector2: PlayerPrefsUtility.SetVector2(newEntryKey, newEntryValueVector2); CacheRecord(newEntryKey, newEntryValueVector2); break; case PlayerPrefType.Vector3: PlayerPrefsUtility.SetVector3(newEntryKey, newEntryValueVector3); CacheRecord(newEntryKey, newEntryValueVector3); break; case PlayerPrefType.Vector4: PlayerPrefsUtility.SetVector4(newEntryKey, newEntryValueVector4); CacheRecord(newEntryKey, newEntryValueVector4); break; case PlayerPrefType.Quaternion: PlayerPrefsUtility.SetQuaternion(newEntryKey, newEntryValueQuaternion); CacheRecord(newEntryKey, newEntryValueQuaternion); break; case PlayerPrefType.Matrix4x4: PlayerPrefsUtility.SetMatrix4x4(newEntryKey, newEntryValueMatrix4x4); CacheRecord(newEntryKey, newEntryValueMatrix4x4); break; case PlayerPrefType.Rect: PlayerPrefsUtility.SetRect(newEntryKey, newEntryValueRect); CacheRecord(newEntryKey, newEntryValueRect); break; case PlayerPrefType.Bounds: PlayerPrefsUtility.SetBounds(newEntryKey, newEntryValueBounds); CacheRecord(newEntryKey, newEntryValueBounds); break; } } // Tell Unity to save the PlayerPrefs PlayerPrefs.Save(); // Force a repaint since hitting the return key won't invalidate layout on its own Repaint(); // Reset the values newEntryKey = ""; newEntryValueFloat = 0; newEntryValueInt = 0; newEntryValueString = ""; // Deselect GUI.FocusControl(""); } EditorGUILayout.EndHorizontal(); }