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;
}