I’m trying to make a custom editor for a component that contains an array of sprites, but it seems that the editor refuses to let me add items to this array.
I’m making my own drag and drop operation resolution. If you add the two following scripts in your project, you’ll get the inspector layout as in the screenshot linked to this post.
So, if you drag a Sprite in the drag and drop area of the component, you’ll see the array with 1 item during a frame, then resets to 0 item.
I have the same issue on Unity 2017.4 and 2018.3.
Does someone know why it happens and how can I fix it? Thanks in advance !
Test this behavior in your projet by adding these scripts:
Here is the code of my component:
using UnityEngine;
public class SpriteArrayTester : MonoBehaviour
{
public Sprite[] sprites = { };
}
And here is my custom editor:
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(SpriteArrayTester))]
public class SpriteArrayTesterEditor : Editor
{
private SerializedProperty _spritesArrayProperty = null;
private Object[] _referencesToAdd = null;
private void OnEnable()
{
_spritesArrayProperty = serializedObject.FindProperty("sprites");
}
public override void OnInspectorGUI()
{
// Adds object references if there's one or more.
// I need to do that at a different moment of the drag and drop resolution to avoid errors.
AddObjectReferences(_spritesArrayProperty);
// Draw drag and drop area
Rect dropArea = EditorGUILayout.GetControlRect(false, 200f);
GUI.Box(dropArea, "Drag and drop sprites here...");
ManageDragAndDrop(dropArea);
// Display array elements
EditorGUILayout.LabelField("Array content (" + _spritesArrayProperty.arraySize + ")", EditorStyles.boldLabel);
for(int i = 0; i < _spritesArrayProperty.arraySize; i++)
{
SerializedProperty itemProperty = _spritesArrayProperty.GetArrayElementAtIndex(i);
EditorGUILayout.LabelField(i + ": " + itemProperty.displayName);
}
}
private void ManageDragAndDrop(Rect dropArea)
{
switch (Event.current.type)
{
// If user dropped something out of the area, ignore the event
case EventType.DragUpdated:
case EventType.DragPerform:
if (!dropArea.Contains(Event.current.mousePosition))
break;
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (Event.current.type == EventType.DragPerform)
{
// Accept drag and drop operation, and store dragged objects references
DragAndDrop.AcceptDrag();
_referencesToAdd = DragAndDrop.objectReferences;
Debug.Log("Accepting drag , nb references to add = " + _referencesToAdd.Length);
}
break;
}
}
private void AddObjectReferences(SerializedProperty arrayProperty)
{
if(_referencesToAdd != null)
{
foreach (Object draggedObject in _referencesToAdd)
{
int index = arrayProperty.arraySize;
// Add an item at the last index
arrayProperty.InsertArrayElementAtIndex(index);
// Set the object reference to the added item
arrayProperty.GetArrayElementAtIndex(index).objectReferenceValue = draggedObject;
Debug.Log("Adding object reference = " + draggedObject.name + " at index " + index + ", reference is: " + arrayProperty.GetArrayElementAtIndex(index).objectReferenceValue);
}
// Apply changes
serializedObject.ApplyModifiedProperties();
_referencesToAdd = null;
}
}
}
Thanks in advance !