- Home /
Using DuplicateCommand and DeleteCommand with Properties
So I'm working with PropertyDrawers in Unity3D, and I feel like I have most things figured out except for the DuplicateCommand and DeleteCommand. By default, when serialized properties are placed into a list or array, Delete will remove the selected item from the list, and Ctrl+D will duplicate and insert a copy. However, when you create a PropertyDrawer for a class and use that class into an array or list, you lose this functionality. I've found a way to implement it, but it seems extremely "hacky". Here is my test sample. This first code is a MonoBehaviour that takes an array of strings, which work with delete and ctrl+D and an array of custom classes:
using UnityEngine;
using System.Collections;
public class TestMono : MonoBehaviour {
public string[] stringArray;
public TestClass[] testClassArray;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
Here is the custom class:
using UnityEngine;
using System.Collections;
[System.Serializable()]
public class TestClass
{
public string id;
public int index;
public float fValue;
}
Here is the property drawer for said class with my hack:
using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomPropertyDrawer(typeof(TestClass))]
public class TestClassDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
int i = GUIUtility.GetControlID(FocusType.Keyboard);
label = EditorGUI.BeginProperty(position, label, property);
bool focus = (i - GUIUtility.keyboardControl == -1);
Debug.Log("Has focus: " + focus);
if (focus)
{
if (Event.current.commandName.Contains("Delete"))
{
EditorGUI.EndProperty();
property.DeleteCommand();
return;
}
}
Rect r = position;
r.height = 16f;
property.isExpanded = EditorGUI.Foldout(r, property.isExpanded, label, true);
if (!property.isExpanded)
{
EditorGUI.EndProperty();
return;
}
EditorGUI.indentLevel += 2;
r.y += r.height;
EditorGUI.PropertyField(r, property.FindPropertyRelative("id"));
r.y += r.height;
EditorGUI.PropertyField(r, property.FindPropertyRelative("index"));
r.y += r.height;
EditorGUI.PropertyField(r, property.FindPropertyRelative("fValue"));
EditorGUI.indentLevel -= 2;
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float finalSize = base.GetPropertyHeight(property, label);
if (property.isExpanded)
{
finalSize += 48f;
}
return finalSize;
}
}
Essentially, I'm creating a keyboard control and getting the current keyboard control and if the difference between the created control and the current control is -1, meaning the control was created right before the keyboard focus, than to react appropriately when deleting or duplicating. Also, if I delete the last item in an array I get an error in the console but it seems relatively harmless. Overall, has anyone worked with PropertyDrawers in this case more and have any insight?