Files
2026-04-02 07:22:33 +02:00

107 lines
4.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using System.Reflection;
using UnityEditor;
#endif
namespace Jovian.InspectorTools {
[AttributeUsage(AttributeTargets.Field)]
public abstract class ArrayAttribute : Attribute {
#if UNITY_EDITOR
public virtual void OnPreGUI(ref Rect position, SerializedProperty property, ref GUIContent label) {
}
public virtual void OnPostGUI(ref Rect position, SerializedProperty property, ref GUIContent label) {
}
#endif
}
#if UNITY_EDITOR
public static class ArrayAttributePropertyHandler {
public static bool DrawArrayProperty(SerializedProperty property) {
return DrawArrayProperty(property,
new GUIContent(ObjectNames.NicifyVariableName(property.name), property.tooltip),
true
);
}
public static bool DrawArrayProperty(SerializedProperty property, GUIContent label, bool includeChildren, params GUILayoutOption[] options) {
Rect rect = EditorGUILayout.GetControlRect(LabelHasContent(label), EditorGUI.GetPropertyHeight(property, label, includeChildren), options);
bool hasArrayAttributes = TryGetAttributes(property, true, out List<ArrayAttribute> arrayAttributes);
bool isGuiEnabled = GUI.enabled;
Color contentColor = GUI.contentColor;
Color backgroundColor = GUI.backgroundColor;
Color guiColor = GUI.color;
Rect preRect = new Rect(rect);
Rect postRect = new Rect(rect);
if (hasArrayAttributes) {
foreach (ArrayAttribute arrayAttribute in arrayAttributes) {
arrayAttribute.OnPreGUI(ref preRect, property, ref label);
}
}
bool hasChildPropertiesNotShown = EditorGUI.PropertyField(preRect, property, label, includeChildren);
if (hasArrayAttributes) {
foreach (ArrayAttribute arrayAttribute in arrayAttributes) {
arrayAttribute.OnPostGUI(ref postRect, property, ref label);
}
}
GUI.enabled = isGuiEnabled;
GUI.contentColor = contentColor;
GUI.backgroundColor = backgroundColor;
GUI.color = guiColor;
return hasChildPropertiesNotShown;
}
private static bool LabelHasContent(GUIContent label)
{
return label == null || label.text != string.Empty || (UnityEngine.Object) label.image != (UnityEngine.Object) null;
}
public static bool TryGetAttributes<TAttribute>(SerializedProperty serializedProperty, bool inherit, out List<TAttribute> attributes)
where TAttribute : Attribute {
if(serializedProperty == null) {
throw new ArgumentNullException(nameof(serializedProperty));
}
Type targetObjectType = serializedProperty.serializedObject.targetObject.GetType();
if(targetObjectType == null) {
throw new ArgumentException($"Could not find the {nameof(targetObjectType)} of {nameof(serializedProperty)}");
}
attributes = new List<TAttribute>();
foreach(string pathSegment in serializedProperty.propertyPath.Split('.')) {
FieldInfo fieldInfo = targetObjectType.GetRuntimeField(pathSegment);
if(fieldInfo != null) {
IEnumerable<TAttribute> fieldAttributes = fieldInfo.GetCustomAttributes<TAttribute>(inherit);
foreach (TAttribute fieldAttribute in fieldAttributes) {
attributes.Add(fieldAttribute);
}
}
PropertyInfo propertyInfo = targetObjectType.GetRuntimeProperty(pathSegment);
if(propertyInfo != null) {
IEnumerable<TAttribute> fieldAttributes = propertyInfo.GetCustomAttributes<TAttribute>(inherit);
foreach (TAttribute fieldAttribute in fieldAttributes) {
attributes.Add(fieldAttribute);
}
}
}
return attributes.Count > 0;
}
}
#endif
}