Unity3d 如何在Unity Inspector中创建带有切换的foldout EditorGUI元素

Unity3d 如何在Unity Inspector中创建带有切换的foldout EditorGUI元素,unity3d,toggle,Unity3d,Toggle,需要您的帮助。 使用切换列表轻松创建折页元素。那样 但我需要在页眉中创建带有切换的折叠元素。那样 我认为这是可能的,因为脚本头已经有了这个 我试图在这里找到答案,但没有找到类似的答案 感谢您的帮助您可以通过创建自定义的 例子 我创建了一个属性,该属性接受一个布尔字段(由您指定),它没有像往常一样渲染它,而是将其渲染为顶部的复选框。在类中可以有任意数量的布尔字段,它们应该呈现得很好 此实现仅呈现布尔字段。如果您希望呈现除此之外的其他类型的内容,请随意扩展此解决方案 实施 用法 在水平方向上进行联合

需要您的帮助。
使用切换列表轻松创建折页元素。那样

但我需要在页眉中创建带有切换的折叠元素。那样

我认为这是可能的,因为脚本头已经有了这个

我试图在这里找到答案,但没有找到类似的答案


感谢您的帮助

您可以通过创建自定义的

例子 我创建了一个属性,该属性接受一个布尔字段(由您指定),它没有像往常一样渲染它,而是将其渲染为顶部的复选框。在类中可以有任意数量的布尔字段,它们应该呈现得很好

此实现仅呈现布尔字段。如果您希望呈现除此之外的其他类型的内容,请随意扩展此解决方案

实施 用法

在水平方向上进行联合收割机group@derHugo是的,这是最早的选择之一,而且很有效。但这不是最优雅的解决方案。为什么不呢?什么更优雅?;)好的,这是一个针对已知列表的有趣解决方案。但我从xml或json加载这些列表,它们是动态的——数量和内容。我理解你的想法——创造自己的折叠式元素
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);
    }
}
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;
}