using UnityEditor; using UnityEngine; #if UNITY_EDITOR namespace Jovian.InspectorTools.Internal { public interface IGUILayoutPropertyField { void GUILayoutPropertyField(SerializedProperty serializedProperty, params GUILayoutOption[] options); void GUILayoutPropertyField(SerializedProperty serializedProperty, bool includeChildren, params GUILayoutOption[] options); void GUILayoutPropertyField(SerializedProperty serializedProperty, GUIContent label, bool includeChildren, params GUILayoutOption[] options); } [CustomEditor(typeof(Object), true)] [CanEditMultipleObjects] public class UnityObjectEditor : Editor, IGUILayoutPropertyField { private FoldoutAttributeHandler foldout; private ButtonMethodHandler buttonMethod; private ShowInInspectorAttributeHandler showInInspectorHandler; private float lastShowInInspectorTime; private static ButtonMethodHandler[] previewButtonMethods; private static Vector2 previewScroll; private Rect previewRect; private void OnEnable() { if(target == null) { return; } foldout = new FoldoutAttributeHandler(target, serializedObject, this); buttonMethod = new ButtonMethodHandler(target); showInInspectorHandler = new ShowInInspectorAttributeHandler(target, serializedObject); if (previewButtonMethods == null && target is Component component) { previewScroll = Vector2.zero; var objectComponents = component.gameObject.GetComponents(); previewButtonMethods = new ButtonMethodHandler[objectComponents.Length]; for (int i = 0; i < objectComponents.Length; i++) { previewButtonMethods[i] = new ButtonMethodHandler(objectComponents[i]); } } EditorApplication.update -= OnUpdate; EditorApplication.update += OnUpdate; } private void OnDisable() { EditorApplication.update -= OnUpdate; foldout?.OnDisable(); previewButtonMethods = null; } private void OnUpdate() { if(showInInspectorHandler?.HasValues == true) { float newShowInInspectorTime = Time.realtimeSinceStartup % 1f; if(newShowInInspectorTime < lastShowInInspectorTime) { Repaint(); } lastShowInInspectorTime = newShowInInspectorTime; } } public override void OnInspectorGUI() { if (buttonMethod != null && buttonMethod.HasAnyVisibleMethods()) { buttonMethod?.OnBeforeInspectorGUI(); EditorGUILayout.Space(); } if(foldout != null) { foldout.Update(); if(!foldout.OverrideInspector) { base.OnInspectorGUI(); } else { foldout.OnInspectorGUI(); } } if(showInInspectorHandler != null) { showInInspectorHandler.Update(); if(showInInspectorHandler.HasValues) { showInInspectorHandler.OnInspectorGUI(this); } } if(buttonMethod != null && buttonMethod.HasAnyVisibleMethods()){ EditorGUILayout.Space(); buttonMethod?.OnAfterInspectorGUI(); } } private static bool HasAnyVisiblePreviewMethods() { if (previewButtonMethods == null) { return false; } foreach (var previewButtonMethod in previewButtonMethods) { if(previewButtonMethod == null) { continue; } if (previewButtonMethod.HasAnyVisibleMethods()) { return true; } } return false; } public override bool HasPreviewGUI() => targets != null && targets.Length == 1 && target != null && HasAnyVisiblePreviewMethods(); public override void OnPreviewGUI(Rect r, GUIStyle background) { // Only Repaint has the true Rect size - so store it whenever we repaint. if (Event.current.type == EventType.Repaint) { previewRect = r; } GUILayout.BeginArea(previewRect); previewScroll = GUILayout.BeginScrollView(previewScroll); foreach (var previewButtonMethod in previewButtonMethods) { if (previewButtonMethod.HasAnyVisibleMethods()) { GUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(ObjectNames.NicifyVariableName(previewButtonMethod.Target.GetType().Name), EditorStyles.boldLabel); previewButtonMethod.OnBeforeInspectorGUI(); previewButtonMethod.OnAfterInspectorGUI(); GUILayout.EndVertical(); } } GUILayout.EndScrollView(); GUILayout.EndArea(); } public void GUILayoutPropertyField(SerializedProperty serializedProperty, params GUILayoutOption[] options) { GUILayoutPropertyField(serializedProperty, true, options); } public void GUILayoutPropertyField(SerializedProperty serializedProperty, bool includeChildren, params GUILayoutOption[] options) { GUILayoutPropertyField(serializedProperty, new GUIContent(ObjectNames.NicifyVariableName(serializedProperty.name), serializedProperty.tooltip), includeChildren, options); } public void GUILayoutPropertyField(SerializedProperty serializedProperty, GUIContent label, bool includeChildren, params GUILayoutOption[] options) { if (serializedProperty.isArray) { ArrayAttributePropertyHandler.DrawArrayProperty(serializedProperty, label, includeChildren, options); } else { EditorGUILayout.PropertyField(serializedProperty, label, includeChildren, options); } } } } #endif