PropertyDrawer: Foldout open all at once

I have a classe that use a property drawer with a single foldout, then I have an array of that class.
When I fold or unfold one element of the array, every other open at once.

[CustomPropertyDrawer(typeof(CarouselElement))]
public class CarouselDrawer : PropertyDrawer {
	public bool unfold = false;

	public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){
		position.height = 16;
		unfold = EditorGUI.Foldout (position, unfold, label);
		if (unfold){
			/*Draw some properties*/
		}
	}

	public override float GetPropertyHeight(SerializedProperty property, GUIContent label){
   		return unfold ? 16*4 : 16;
	}
}

I take it that ‘unfold’ is being shared across all instances of the class? How am I supposed to keep track of every possible instance individually?

**Edit : **
I did make the check, when creating several different property on a Monobehaviour they will unfold properly with this code, it’s really when creating a array of properties that they somehow get all kined together. Is this some kind of bug or is this by design?

You can use the property.isExpanded flag for this.

 [CustomPropertyDrawer(typeof(CarouselElement))]
 public class CarouselDrawer : PropertyDrawer {
 
     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){
         position.height = 16;
         
         property.isExpanded = EditorGUI.Foldout (position, property.isExpanded, label);
 
         if (property.isExpanded) {
             /*Show folded subproperty*/
         }
     }
         public override float GetPropertyHeight(SerializedProperty property, GUIContent label){
             return property.isExpanded ? 16*4 : 16;
     }
 }

The way I usually handle a situation like this is to make unfold a Dictionary<string, bool>, where each key is property.propertyPath

Here is my version. Using Unity fold control.

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(DisplayScriptableObjectPropertiesAttribute))]
public class DisplayScriptableObjectPropertiesDrawer : PropertyDrawer
{
    bool _showProperty = false;
    float _drawerHeight;

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        int indent = EditorGUI.indentLevel;

        _drawerHeight = 0;
        position.height = 16;

        EditorGUI.PropertyField(position, property);

        _showProperty = EditorGUI.Foldout(position, _showProperty, "");

        position.y += 20;

        position.x += 20;
        position.width -= 40;

        if (!_showProperty)
            return;

        var so = new SerializedObject(property.objectReferenceValue);
        so.Update();
        var prop = so.GetIterator();
        prop.NextVisible(true);
        int depthChilden = 0;
        bool showChilden = false;
        while (prop.NextVisible(true))
        {
            if (prop.depth == 0)
            {
                showChilden = false;
                depthChilden = 0;
            }
            if (showChilden && prop.depth > depthChilden)
            {
                continue;
            }
            position.height = 16;
            EditorGUI.indentLevel = indent + prop.depth;
            if (EditorGUI.PropertyField(position, prop))
            {
                showChilden = false;
            }
            else
            {
                showChilden = true;
                depthChilden = prop.depth;
            }
            position.y += 20;
            _drawerHeight += 20;
        }


        if (GUI.changed)
        {
            so.ApplyModifiedProperties();
        }
    }

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        float height = base.GetPropertyHeight(property, label);
        height += _drawerHeight;
        return height;
    }
}