using UnityEngine; using UnityEditor; using System; using System.Linq; using UnityEditor.SceneManagement; namespace MLAgents { [CustomPropertyDrawer(typeof(ResetParameters))] public class ResetParameterDrawer : PropertyDrawer { private ResetParameters _Dictionary; private const float lineHeight = 17f; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { CheckInitialize(property, label); return (_Dictionary.Count + 2) * lineHeight; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { CheckInitialize(property, label); position.height = lineHeight; EditorGUI.LabelField(position, label); EditorGUI.BeginProperty(position, label, property); foreach (var item in _Dictionary) { var key = item.Key; var value = item.Value; position.y += lineHeight; // This is the rectangle for the key var keyRect = position; keyRect.x += 20; keyRect.width /= 2; keyRect.width -= 24; EditorGUI.BeginChangeCheck(); var newKey = EditorGUI.TextField(keyRect, key); if (EditorGUI.EndChangeCheck()) { EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); try { _Dictionary.Remove(key); _Dictionary.Add(newKey, value); } catch (Exception e) { Debug.Log(e.Message); } break; } // This is the Rectangle for the value var valueRect = position; valueRect.x = position.width / 2 + 15; valueRect.width = keyRect.width - 18; EditorGUI.BeginChangeCheck(); value = EditorGUI.FloatField(valueRect, value); if (EditorGUI.EndChangeCheck()) { EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); _Dictionary[key] = value; break; } } // This is the rectangle for the Add button position.y += lineHeight; var AddButtonRect = position; AddButtonRect.x += 20; AddButtonRect.width /= 2; AddButtonRect.width -= 24; if (GUI.Button(AddButtonRect, new GUIContent("Add New", "Add a new item to the default reset paramters"), EditorStyles.miniButton)) { EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); AddNewItem(); } // This is the rectangle for the Remove button var RemoveButtonRect = position; RemoveButtonRect.x = position.width / 2 + 15; RemoveButtonRect.width = AddButtonRect.width - 18; if (GUI.Button(RemoveButtonRect, new GUIContent("Remove Last", "Remove the last item to the default reset paramters"), EditorStyles.miniButton)) { EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); RemoveLastItem(); } EditorGUI.EndProperty(); } private void CheckInitialize(SerializedProperty property, GUIContent label) { if (_Dictionary == null) { var target = property.serializedObject.targetObject; _Dictionary = fieldInfo.GetValue(target) as ResetParameters; if (_Dictionary == null) { _Dictionary = new ResetParameters(); fieldInfo.SetValue(target, _Dictionary); } } } private void ClearResetParamters() { _Dictionary.Clear(); } private void RemoveLastItem() { if (_Dictionary.Count > 0) { string key = _Dictionary.Keys.ToList()[_Dictionary.Count - 1]; _Dictionary.Remove(key); } } private void AddNewItem() { string key = "Param-" + _Dictionary.Count.ToString(); var value = default(float); try { _Dictionary.Add(key, value); } catch (Exception e) { Debug.Log(e.Message); } } } }