using UnityEditor; using UnityEngine; namespace Jovian.InspectorTools { public class OptionalAttribute : PropertyAttribute { } } #if UNITY_EDITOR namespace Jovian.InspectorTools.Internal { [CustomPropertyDrawer(typeof(OptionalAttribute))] public class OptionalAttributePropertyDrawer : PropertyDrawer { private const float ICON_X_OFFSET = 17f; private const float ICON_SIZE = 18f; private GUIContent icon; private GUIStyle style; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (property.propertyType != SerializedPropertyType.ObjectReference) { Debug.LogError($"Optional should only be used on Unity Object references. Target='{property.serializedObject.targetObject.name}.{property.propertyPath}'"); EditorGUI.PropertyField(position, property, label); return; } if(icon == null || style == null) { icon = new GUIContent(EditorGUIUtility.IconContent("DotFrameDotted").image, "Optional"); style = new GUIStyle(GUI.skin.label) { padding = new RectOffset(0, 0, 0, 0), imagePosition = ImagePosition.ImageOnly }; } if(property.objectReferenceValue == null) { Rect iconRect = new Rect(position.x - ICON_X_OFFSET, position.y + 1, ICON_SIZE, EditorGUIUtility.singleLineHeight); GUI.Label(iconRect, icon, style); } label = EditorGUI.BeginProperty(position, label, property); position = EditorGUI.PrefixLabel(position, label); EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(position, property, GUIContent.none); if(EditorGUI.EndChangeCheck()) { property.serializedObject.ApplyModifiedProperties(); } EditorGUI.EndProperty(); } } } #endif