'How can I create foldout EditorGUI element with toggle in Unity Inspector

Need your help.
Easily create a foldout element with toggle list. Like that 1

But I need to create foldout element with toggle in a header. Like that 2

I think it's possible because scripts header already have this 3

I tried to find the answer here but didn't find anything like it.

Thank you for help



Solution 1:[1]

You can override how your Serializable class is rendered using EditorGUI by creating a custom PropertyAttribute and PropertyDrawer.

Example

I cooked up an attribute that takes a boolean field (specified by you) and instead of rendering it as usual, it renders it as a checkbox at the top. You can have any number of boolean fields inside your class, they should render just fine.

This implementation renders only boolean fields. If you wish to render other kind of stuff besides that, feel free to extend this solution.

Implementation

using UnityEngine;

public class ToggleListAttribute : PropertyAttribute
{
    public string StatusPropertyName { get; private set; }

    public ToggleListAttribute(string statusPropertyName)
    {
        StatusPropertyName = statusPropertyName;
    }
}
using System;
using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(ToggleListAttribute))]
public class ToggleListDrawer : PropertyDrawer
{
    private bool show;

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        var statusProperty = GetStatusPropertyFrom(property);
        var foldoutRect = GetLinePositionFrom(position, 1);

        show = EditorGUI.Foldout(
            foldoutRect,
            show,
            string.Empty,
            false);

        statusProperty.boolValue = EditorGUI.ToggleLeft(
            foldoutRect,
            property.displayName,
            statusProperty.boolValue);

        if (show)
            RenderSubproperties(property, position);
    }

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        if (show)
            return EditorGUIUtility.singleLineHeight * (GetBooleanPropertyCount(property) + 1);
        else
            return EditorGUIUtility.singleLineHeight;
    }

    private SerializedProperty GetStatusPropertyFrom(SerializedProperty property)
    {
        var listAttribute = attribute as ToggleListAttribute;

        var statusProperty = property.FindPropertyRelative(
            listAttribute.StatusPropertyName);

        if (statusProperty == null)
            throw new Exception($"No property named \"{listAttribute.StatusPropertyName}\" found!");

        return statusProperty;
    }

    private void RenderSubproperties(SerializedProperty property, Rect position)
    {
        var innerPosition = new Rect(
                position.x + EditorGUIUtility.standardVerticalSpacing * 4,
                position.y,
                position.width,
                position.height);

        var statusProperty = GetStatusPropertyFrom(property);
        int line = 2;

        foreach (var instance in property)
        {
            var subproperty = instance as SerializedProperty;

            if (subproperty.propertyType != SerializedPropertyType.Boolean ||
                subproperty.name == statusProperty.name)
            {
                continue;
            }

            subproperty.boolValue = EditorGUI.ToggleLeft(
                GetLinePositionFrom(innerPosition, line),
                subproperty.displayName,
                subproperty.boolValue);

            line++;
        }
    }

    private int GetBooleanPropertyCount(SerializedProperty property)
    {
        int count = 0;

        foreach (var instance in property)
        {
            var subproperty = instance as SerializedProperty;

            if (subproperty.propertyType != SerializedPropertyType.Boolean)
                continue;

            count++;
        }

        return count - 1;
    }

    private Rect GetLinePositionFrom(Rect rect, int line)
    {
        float heightModifier = EditorGUIUtility.singleLineHeight * (line - 1);

        return new Rect(
            rect.x,
            rect.y + heightModifier,
            rect.width,
            EditorGUIUtility.singleLineHeight);
    }
}

Usage

using System;
using UnityEngine;

public class Example : MonoBehaviour
{
    [ToggleList("enabled")]
    public RenderList list1;

    [ToggleList("enabled")]
    public RenderList2 list2;
}

[Serializable]
public class RenderList
{
    public bool enabled;

    public bool floor;
    public bool car;
    public bool train;
}

[Serializable]
public class RenderList2
{
    public bool enabled;

    public bool one;
    public bool two;
    public bool three;
    public bool four;
    public bool five;
    public bool six;
    public bool seven;
}

enter image description here

Solution 2:[2]

Use EditorGUILayout.InspectorTitlebar(foldout: foldout, editor: targetEditor);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Quickz
Solution 2 Sylux Dev