123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- using UnityEngine;
- using UnityEditor;
- using System;
- using System.Linq;
- using UnityEditor.SceneManagement;
-
- namespace MLAgents
- {
- /// <summary>
- /// PropertyDrawer for ResetParameters. Defines how ResetParameters are displayed in the
- /// Inspector.
- /// </summary>
- [CustomPropertyDrawer(typeof(ResetParameters))]
- public class ResetParameterDrawer : PropertyDrawer
- {
- private ResetParameters _parameters;
- // The height of a line in the Unity Inspectors
- private const float LineHeight = 17f;
- // This is the prefix for the key when you add a reset parameter
- private const string NewKeyPrefix = "Param-";
-
- /// <summary>
- /// Computes the height of the Drawer depending on the property it is showing
- /// </summary>
- /// <param name="property">The property that is being drawn.</param>
- /// <param name="label">The label of the property being drawn.</param>
- /// <returns>The vertical space needed to draw the property.</returns>
- public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
- {
- LazyInitializeParameters(property, label);
- return (_parameters.Count + 2) * LineHeight;
- }
-
- /// <inheritdoc />
- public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
- {
- LazyInitializeParameters(property, label);
- position.height = LineHeight;
- EditorGUI.LabelField(position, label);
- position.y += LineHeight;
- var width = position.width / 2 - 24;
- var keyRect = new Rect(position.x + 20, position.y, width, position.height);
- var valueRect = new Rect(position.x + width + 30, position.y, width, position.height);
- DrawAddRemoveButtons(keyRect, valueRect);
- EditorGUI.BeginProperty(position, label, property);
- foreach (var parameter in _parameters)
- {
- var key = parameter.Key;
- var value = parameter.Value;
- keyRect.y += LineHeight;
- valueRect.y += LineHeight;
- EditorGUI.BeginChangeCheck();
- var newKey = EditorGUI.TextField(keyRect, key);
- if (EditorGUI.EndChangeCheck())
- {
- MarkSceneAsDirty();
- try
- {
- _parameters.Remove(key);
- _parameters.Add(newKey, value);
- }
- catch (Exception e)
- {
- Debug.Log(e.Message);
- }
- break;
- }
-
- EditorGUI.BeginChangeCheck();
- value = EditorGUI.FloatField(valueRect, value);
- if (EditorGUI.EndChangeCheck())
- {
- MarkSceneAsDirty();
- _parameters[key] = value;
- break;
- }
- }
- EditorGUI.EndProperty();
- }
-
- /// <summary>
- /// Draws the Add and Remove buttons.
- /// </summary>
- /// <param name="addRect">The rectangle for the Add New button.</param>
- /// <param name="removeRect">The rectangle for the Remove Last button.</param>
- private void DrawAddRemoveButtons(Rect addRect, Rect removeRect)
- {
- // This is the Add button
- if (_parameters.Count == 0)
- {
- addRect.width *= 2;
- }
- if (GUI.Button(addRect,
- new GUIContent("Add New", "Add a new item to the default reset parameters"),
- EditorStyles.miniButton))
- {
- MarkSceneAsDirty();
- AddParameter();
- }
-
- // If there are no items in the ResetParameters, Hide the Remove button
- if (_parameters.Count == 0)
- {
- return;
- }
- // This is the Remove button
- if (GUI.Button(removeRect,
- new GUIContent(
- "Remove Last", "Remove the last item from the default reset parameters"),
- EditorStyles.miniButton))
- {
- MarkSceneAsDirty();
- RemoveLastParameter();
- }
- }
-
- /// <summary>
- /// Signals that the property has been modified and requires the scene to be saved for
- /// the changes to persist. Only works when the Editor is not playing.
- /// </summary>
- private static void MarkSceneAsDirty()
- {
- if (!EditorApplication.isPlaying)
- {
- EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
- }
- }
-
- /// <summary>
- /// Ensures that the state of the Drawer is synchronized with the property.
- /// </summary>
- /// <param name="property">The SerializedProperty of the ResetParameters
- /// to make the custom GUI for.</param>
- /// <param name="label">The label of this property.</param>
- private void LazyInitializeParameters(SerializedProperty property, GUIContent label)
- {
- if (_parameters != null)
- {
- return;
- }
- var target = property.serializedObject.targetObject;
- _parameters = fieldInfo.GetValue(target) as ResetParameters;
- if (_parameters == null)
- {
- _parameters = new ResetParameters();
- fieldInfo.SetValue(target, _parameters);
- }
- }
-
- /// <summary>
- /// Removes the last ResetParameter from the ResetParameters
- /// </summary>
- private void RemoveLastParameter()
- {
- if (_parameters.Count > 0)
- {
- string key = _parameters.Keys.ToList()[_parameters.Count - 1];
- _parameters.Remove(key);
- }
- }
-
- /// <summary>
- /// Adds a new ResetParameter to the ResetParameters with a default name.
- /// </summary>
- private void AddParameter()
- {
- string key = NewKeyPrefix + _parameters.Count;
- var value = default(float);
- try
- {
- _parameters.Add(key, value);
- }
- catch (Exception e)
- {
- Debug.Log(e.Message);
- }
- }
- }
- }
|