|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
|
|
|
|
namespace NaughtyAttributes.Editor
|
|
|
|
|
{
|
|
|
|
|
[CustomPropertyDrawer(typeof(ExpandableAttribute))]
|
|
|
|
|
public class ExpandablePropertyDrawer : PropertyDrawerBase
|
|
|
|
|
{
|
|
|
|
|
protected override float GetPropertyHeight_Internal(SerializedProperty property, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
if (property.objectReferenceValue == null)
|
|
|
|
|
{
|
|
|
|
|
return GetPropertyHeight(property);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
System.Type propertyType = PropertyUtility.GetPropertyType(property);
|
|
|
|
|
if (typeof(ScriptableObject).IsAssignableFrom(propertyType))
|
|
|
|
|
{
|
|
|
|
|
ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject;
|
|
|
|
|
if (scriptableObject == null)
|
|
|
|
|
{
|
|
|
|
|
return GetPropertyHeight(property);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (property.isExpanded)
|
|
|
|
|
{
|
|
|
|
|
using (SerializedObject serializedObject = new SerializedObject(scriptableObject))
|
|
|
|
|
{
|
|
|
|
|
float totalHeight = EditorGUIUtility.singleLineHeight;
|
|
|
|
|
|
|
|
|
|
using (var iterator = serializedObject.GetIterator())
|
|
|
|
|
{
|
|
|
|
|
if (iterator.NextVisible(true))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
SerializedProperty childProperty = serializedObject.FindProperty(iterator.name);
|
|
|
|
|
if (childProperty.name.Equals("m_Script", System.StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool visible = PropertyUtility.IsVisible(childProperty);
|
|
|
|
|
if (!visible)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float height = GetPropertyHeight(childProperty);
|
|
|
|
|
totalHeight += height;
|
|
|
|
|
}
|
|
|
|
|
while (iterator.NextVisible(false));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalHeight += EditorGUIUtility.standardVerticalSpacing;
|
|
|
|
|
return totalHeight;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return GetPropertyHeight(property);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return GetPropertyHeight(property) + GetHelpBoxHeight();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
EditorGUI.BeginProperty(rect, label, property);
|
|
|
|
|
|
|
|
|
|
if (property.objectReferenceValue == null)
|
|
|
|
|
{
|
|
|
|
|
EditorGUI.PropertyField(rect, property, label, false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
System.Type propertyType = PropertyUtility.GetPropertyType(property);
|
|
|
|
|
if (typeof(ScriptableObject).IsAssignableFrom(propertyType))
|
|
|
|
|
{
|
|
|
|
|
ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject;
|
|
|
|
|
if (scriptableObject == null)
|
|
|
|
|
{
|
|
|
|
|
EditorGUI.PropertyField(rect, property, label, false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Draw a foldout
|
|
|
|
|
Rect foldoutRect = new Rect()
|
|
|
|
|
{
|
|
|
|
|
x = rect.x,
|
|
|
|
|
y = rect.y,
|
|
|
|
|
width = EditorGUIUtility.labelWidth,
|
|
|
|
|
height = EditorGUIUtility.singleLineHeight
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, label, toggleOnLabelClick: true);
|
|
|
|
|
|
|
|
|
|
// Draw the scriptable object field
|
|
|
|
|
Rect propertyRect = new Rect()
|
|
|
|
|
{
|
|
|
|
|
x = rect.x,
|
|
|
|
|
y = rect.y,
|
|
|
|
|
width = rect.width,
|
|
|
|
|
height = EditorGUIUtility.singleLineHeight
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
EditorGUI.PropertyField(propertyRect, property, label, false);
|
|
|
|
|
|
|
|
|
|
property.serializedObject.ApplyModifiedProperties();
|
|
|
|
|
|
|
|
|
|
// Draw the child properties
|
|
|
|
|
if (property.isExpanded)
|
|
|
|
|
{
|
|
|
|
|
DrawChildProperties(rect, property);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
string message = $"{typeof(ExpandableAttribute).Name} can only be used on scriptable objects";
|
|
|
|
|
DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EditorGUI.EndProperty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawChildProperties(Rect rect, SerializedProperty property)
|
|
|
|
|
{
|
|
|
|
|
ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject;
|
|
|
|
|
if (scriptableObject == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Rect boxRect = new Rect()
|
|
|
|
|
{
|
|
|
|
|
x = 0.0f,
|
|
|
|
|
y = rect.y + EditorGUIUtility.singleLineHeight,
|
|
|
|
|
width = rect.width * 2.0f,
|
|
|
|
|
height = rect.height - EditorGUIUtility.singleLineHeight
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GUI.Box(boxRect, GUIContent.none);
|
|
|
|
|
|
|
|
|
|
using (new EditorGUI.IndentLevelScope())
|
|
|
|
|
{
|
|
|
|
|
SerializedObject serializedObject = new SerializedObject(scriptableObject);
|
|
|
|
|
|
|
|
|
|
using (var iterator = serializedObject.GetIterator())
|
|
|
|
|
{
|
|
|
|
|
float yOffset = EditorGUIUtility.singleLineHeight;
|
|
|
|
|
|
|
|
|
|
if (iterator.NextVisible(true))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
SerializedProperty childProperty = serializedObject.FindProperty(iterator.name);
|
|
|
|
|
if (childProperty.name.Equals("m_Script", System.StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool visible = PropertyUtility.IsVisible(childProperty);
|
|
|
|
|
if (!visible)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float childHeight = GetPropertyHeight(childProperty);
|
|
|
|
|
Rect childRect = new Rect()
|
|
|
|
|
{
|
|
|
|
|
x = rect.x,
|
|
|
|
|
y = rect.y + yOffset,
|
|
|
|
|
width = rect.width,
|
|
|
|
|
height = childHeight
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
NaughtyEditorGUI.PropertyField(childRect, childProperty, true);
|
|
|
|
|
|
|
|
|
|
yOffset += childHeight;
|
|
|
|
|
}
|
|
|
|
|
while (iterator.NextVisible(false));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|