using UnityEditor; using UnityEngine; using Interactions; namespace Editor { /// /// Custom editor for TriggerAnimationOnInteraction with helpful validation and feedback /// [CustomEditor(typeof(TriggerAnimationOnInteraction))] public class TriggerAnimationOnInteractionEditor : UnityEditor.Editor { private SerializedProperty _interactable; private SerializedProperty _animator; private SerializedProperty _triggerName; private void OnEnable() { _interactable = serializedObject.FindProperty("interactable"); _animator = serializedObject.FindProperty("animator"); _triggerName = serializedObject.FindProperty("triggerName"); } public override void OnInspectorGUI() { serializedObject.Update(); // Draw script field (read-only) EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField("Script", MonoScript.FromMonoBehaviour((MonoBehaviour)target), GetType(), false); EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); // Component References EditorGUILayout.LabelField("Component References (Optional)", EditorStyles.boldLabel); EditorGUILayout.PropertyField(_interactable); EditorGUILayout.PropertyField(_animator); if (_interactable.objectReferenceValue == null || _animator.objectReferenceValue == null) { EditorGUILayout.HelpBox("Leave fields empty to auto-discover components on this GameObject or children.", MessageType.Info); } EditorGUILayout.Space(); // Animation Settings EditorGUILayout.LabelField("Animation Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(_triggerName); if (string.IsNullOrEmpty(_triggerName.stringValue)) { EditorGUILayout.HelpBox("Assign a trigger name that matches a trigger parameter in the Animator.", MessageType.Warning); } EditorGUILayout.Space(); // Component Discovery Info EditorGUILayout.LabelField("Component Discovery Status", EditorStyles.boldLabel); var component = (TriggerAnimationOnInteraction)target; // Check what will be used at runtime InteractableBase resolvedInteractable = _interactable.objectReferenceValue as InteractableBase; if (resolvedInteractable == null) { resolvedInteractable = component.GetComponent(); } if (resolvedInteractable == null) { resolvedInteractable = component.GetComponentInChildren(); } Animator resolvedAnimator = _animator.objectReferenceValue as Animator; if (resolvedAnimator == null) { resolvedAnimator = component.GetComponent(); } if (resolvedAnimator == null) { resolvedAnimator = component.GetComponentInChildren(); } // Show discovered components if (resolvedInteractable != null) { string source = _interactable.objectReferenceValue != null ? "Assigned" : "Auto-discovered"; EditorGUILayout.HelpBox($"✓ Interactable: {resolvedInteractable.gameObject.name} ({source})", MessageType.Info); } else { EditorGUILayout.HelpBox("✗ No Interactable found! Assign one or ensure an Interactable exists on this GameObject or children.", MessageType.Error); } if (resolvedAnimator != null) { string source = _animator.objectReferenceValue != null ? "Assigned" : "Auto-discovered"; EditorGUILayout.HelpBox($"✓ Animator: {resolvedAnimator.gameObject.name} ({source})", MessageType.Info); } else { EditorGUILayout.HelpBox("✗ No Animator found! Assign one or ensure an Animator exists on this GameObject or children.", MessageType.Error); } EditorGUILayout.Space(); // Behavior explanation EditorGUILayout.HelpBox( "Behavior:\n" + "• Components can be manually assigned or auto-discovered\n" + "• Auto-discovery searches: this GameObject → children\n" + "• Listens to interactionComplete event from Interactable\n" + "• Triggers animation ONLY when interaction succeeds (success = true)\n" + "• Uses SetTrigger() with the specified trigger name", MessageType.None ); serializedObject.ApplyModifiedProperties(); } } }