/// <summary> /// Draws the inspector, complete with helpbox, init mode selection, list of feedbacks, feedback selection and test buttons /// </summary> public override void OnInspectorGUI() { var e = Event.current; serializedObject.Update(); Undo.RecordObject(target, "Modified Feedback Manager"); EditorGUILayout.Space(); if (!MMFeedbacks.GlobalMMFeedbacksActive) { Color baseColor = GUI.color; GUI.color = Color.red; EditorGUILayout.HelpBox("All MMFeedbacks, including this one, are currently disabled. This is done via script, by changing the value of the MMFeedbacks.GlobalMMFeedbacksActive boolean. Right now this value has been set to false. Setting it back to true will allow MMFeedbacks to play again.", MessageType.Warning); EditorGUILayout.Space(); GUI.color = baseColor; } if (MMFeedbacksConfiguration.Instance.ShowInspectorTips) { EditorGUILayout.HelpBox("Select feedbacks from the 'add a feedback' dropdown and customize them. Remember, if you don't use auto initialization (Awake or Start), " + "you'll need to initialize them via script.", MessageType.None); } Rect helpBoxRect = GUILayoutUtility.GetLastRect(); // Settings dropdown ------------------------------------------------------------------------------------- _settingsMenuDropdown = EditorGUILayout.Foldout(_settingsMenuDropdown, "Settings", true, EditorStyles.foldout); if (_settingsMenuDropdown) { EditorGUILayout.Space(10); EditorGUILayout.LabelField("Initialization", EditorStyles.boldLabel); EditorGUILayout.PropertyField(_mmfeedbacksSafeMode); EditorGUILayout.PropertyField(_mmfeedbacksInitializationMode); EditorGUILayout.PropertyField(_mmfeedbacksAutoPlayOnStart); EditorGUILayout.PropertyField(_mmfeedbacksAutoPlayOnEnable); EditorGUILayout.Space(10); EditorGUILayout.LabelField("Direction", EditorStyles.boldLabel); EditorGUILayout.PropertyField(_mmfeedbacksDirection); EditorGUILayout.PropertyField(_mmfeedbacksAutoChangeDirectionOnEnd); EditorGUILayout.Space(10); EditorGUILayout.LabelField("Intensity", EditorStyles.boldLabel); EditorGUILayout.PropertyField(_mmfeedbacksFeedbacksIntensity); EditorGUILayout.Space(10); EditorGUILayout.LabelField("Timing", EditorStyles.boldLabel); EditorGUILayout.PropertyField(_mmfeedbacksDurationMultiplier); EditorGUILayout.PropertyField(_mmfeedbacksDisplayFullDurationDetails); EditorGUILayout.PropertyField(_mmfeedbacksCooldownDuration); EditorGUILayout.PropertyField(_mmfeedbacksInitialDelay); EditorGUILayout.Space(10); EditorGUILayout.LabelField("Events", EditorStyles.boldLabel); EditorGUILayout.PropertyField(_mmfeedbacksEvents); } // Duration ---------------------------------------------------------------------------------------------- float durationRectWidth = 70f; Rect durationRect = new Rect(helpBoxRect.xMax - durationRectWidth, helpBoxRect.yMax + 6, durationRectWidth, 17f); durationRect.xMin = helpBoxRect.xMax - durationRectWidth; durationRect.xMax = helpBoxRect.xMax; // Direction ---------------------------------------------------------------------------------------------- float directionRectWidth = 16f; Rect directionRect = new Rect(helpBoxRect.xMax - directionRectWidth, helpBoxRect.yMax + 5, directionRectWidth, 17f); directionRect.xMin = helpBoxRect.xMax - directionRectWidth; directionRect.xMax = helpBoxRect.xMax; GUI.Label(durationRect, "[" + _targetMMFeedbacks.TotalDuration.ToString("F2") + "s]"); if (_targetMMFeedbacks.Direction == MMFeedbacks.Directions.BottomToTop) { GUIContent directionIcon = EditorGUIUtility.IconContent("vcs_change", "BottomToTop"); if (GUI.Button(directionRect, directionIcon, _directionButtonStyle)) { _targetMMFeedbacks.Revert(); } } else { float rotationAngle = 180f; var pivotPoint = new Vector2(directionRect.xMin + 7, directionRect.yMax - 8); var matrixBackup = GUI.matrix; GUIUtility.RotateAroundPivot(rotationAngle, pivotPoint); GUIContent directionIcon = EditorGUIUtility.IconContent("vcs_incoming", "TopToBottom"); if (GUI.Button(directionRect, directionIcon, _directionButtonStyle)) { _targetMMFeedbacks.Revert(); } GUI.matrix = matrixBackup; } // Draw list ------------------------------------------------------------------------------------------ MMFeedbackStyling.DrawSection("Feedbacks"); for (int i = 0; i < _mmfeedbacks.arraySize; i++) { MMFeedbackStyling.DrawSplitter(); SerializedProperty property = _mmfeedbacks.GetArrayElementAtIndex(i); // Failsafe but should not happen if (property.objectReferenceValue == null) { continue; } // Retrieve feedback MMFeedback feedback = property.objectReferenceValue as MMFeedback; feedback.hideFlags = _debugView ? HideFlags.None : HideFlags.HideInInspector; Undo.RecordObject(feedback, "Modified Feedback"); // Draw header int id = i; bool isExpanded = property.isExpanded; string label = feedback.Label; bool pause = false; if (feedback.Pause != null) { pause = true; } if ((feedback.LooperPause == true) && (Application.isPlaying)) { if ((feedback as MMFeedbackLooper).InfiniteLoop) { label = label + "[Infinite Loop] "; } else { label = label + "[ " + (feedback as MMFeedbackLooper).NumberOfLoopsLeft + " loops left ] "; } } Rect headerRect = MMFeedbackStyling.DrawHeader( ref isExpanded, ref feedback.Active, label, feedback.FeedbackColor, (GenericMenu menu) => { if (Application.isPlaying) { menu.AddItem(new GUIContent("Play"), false, () => PlayFeedback(id)); } else { menu.AddDisabledItem(new GUIContent("Play")); } menu.AddSeparator(null); //menu.AddItem(new GUIContent("Reset"), false, () => ResetFeedback(id)); menu.AddItem(new GUIContent("Remove"), false, () => RemoveFeedback(id)); menu.AddSeparator(null); menu.AddItem(new GUIContent("Copy"), false, () => CopyFeedback(id)); if (FeedbackCopy.HasCopy() && FeedbackCopy.Type == feedback.GetType()) { menu.AddItem(new GUIContent("Paste"), false, () => PasteFeedback(id)); } else { menu.AddDisabledItem(new GUIContent("Paste")); } }, feedback.FeedbackStartedAt, feedback.FeedbackDuration, feedback.TotalDuration, feedback.Timing, pause, _targetMMFeedbacks ); // Check if we start dragging this feedback switch (e.type) { case EventType.MouseDown: if (headerRect.Contains(e.mousePosition)) { _draggedStartID = i; e.Use(); } break; default: break; } // Draw blue rect if feedback is being dragged if (_draggedStartID == i && headerRect != Rect.zero) { Color color = new Color(0, 1, 1, 0.2f); EditorGUI.DrawRect(headerRect, color); } // If hovering at the top of the feedback while dragging one, check where the feedback should be dropped : top or bottom if (headerRect.Contains(e.mousePosition)) { if (_draggedStartID >= 0) { _draggedEndID = i; Rect headerSplit = headerRect; headerSplit.height *= 0.5f; headerSplit.y += headerSplit.height; if (headerSplit.Contains(e.mousePosition)) { _draggedEndID = i + 1; } } } // If expanded, draw feedback editor property.isExpanded = isExpanded; if (isExpanded) { EditorGUI.BeginDisabledGroup(!feedback.Active); string helpText = FeedbackHelpAttribute.GetFeedbackHelpText(feedback.GetType()); if ((!string.IsNullOrEmpty(helpText)) && (MMFeedbacksConfiguration.Instance.ShowInspectorTips)) { GUIStyle style = new GUIStyle(EditorStyles.helpBox); style.richText = true; float newHeight = style.CalcHeight(new GUIContent(helpText), EditorGUIUtility.currentViewWidth); EditorGUILayout.LabelField(helpText, style); } EditorGUILayout.Space(); if (!_editors.ContainsKey(feedback)) { AddEditor(feedback); } Editor editor = _editors[feedback]; CreateCachedEditor(feedback, feedback.GetType(), ref editor); editor.OnInspectorGUI(); EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); EditorGUI.BeginDisabledGroup(!Application.isPlaying); EditorGUILayout.BeginHorizontal(); { if (GUILayout.Button("Play", EditorStyles.miniButtonMid)) { PlayFeedback(id); } if (GUILayout.Button("Stop", EditorStyles.miniButtonMid)) { StopFeedback(id); } } EditorGUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); EditorGUILayout.Space(); } } // Draw add new item if (_mmfeedbacks.arraySize > 0) { MMFeedbackStyling.DrawSplitter(); } EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); { // Feedback list int newItem = EditorGUILayout.Popup(0, _typeDisplays) - 1; if (newItem >= 0) { AddFeedback(_typesAndNames[newItem].FeedbackType); } // Paste feedback copy as new if (FeedbackCopy.HasCopy()) { if (GUILayout.Button("Paste as new", EditorStyles.miniButton, GUILayout.Width(EditorStyles.miniButton.CalcSize(new GUIContent("Paste as new")).x))) { PasteAsNew(); } } if (FeedbackCopy.HasMultipleCopies()) { if (GUILayout.Button("Paste all as new", EditorStyles.miniButton, GUILayout.Width(EditorStyles.miniButton.CalcSize(new GUIContent("Paste all as new")).x))) { PasteAllAsNew(); } } } if (!FeedbackCopy.HasMultipleCopies()) { if (GUILayout.Button("Copy all", EditorStyles.miniButton, GUILayout.Width(EditorStyles.miniButton.CalcSize(new GUIContent("Paste as new")).x))) { CopyAll(); } } EditorGUILayout.EndHorizontal(); // Reorder if (_draggedStartID >= 0 && _draggedEndID >= 0) { if (_draggedEndID != _draggedStartID) { if (_draggedEndID > _draggedStartID) { _draggedEndID--; } _mmfeedbacks.MoveArrayElement(_draggedStartID, _draggedEndID); _draggedStartID = _draggedEndID; } } if (_draggedStartID >= 0 || _draggedEndID >= 0) { switch (e.type) { case EventType.MouseUp: _draggedStartID = -1; _draggedEndID = -1; e.Use(); break; default: break; } } // Clean up bool wasRemoved = false; for (int i = _mmfeedbacks.arraySize - 1; i >= 0; i--) { if (_mmfeedbacks.GetArrayElementAtIndex(i).objectReferenceValue == null) { wasRemoved = true; _mmfeedbacks.DeleteArrayElementAtIndex(i); } } if (wasRemoved) { GameObject gameObject = (target as MMFeedbacks).gameObject; foreach (var c in gameObject.GetComponents <Component>()) { c.hideFlags = HideFlags.None; } } // Apply changes serializedObject.ApplyModifiedProperties(); // Draw debug MMFeedbackStyling.DrawSection("All Feedbacks Debug"); // Testing buttons EditorGUI.BeginDisabledGroup(!Application.isPlaying); EditorGUILayout.BeginHorizontal(); { // initialize button if (GUILayout.Button("Initialize", EditorStyles.miniButtonLeft)) { (target as MMFeedbacks).Initialization(); } // play button _originalBackgroundColor = GUI.backgroundColor; GUI.backgroundColor = _playButtonColor; if (GUILayout.Button("Play", EditorStyles.miniButtonMid)) { (target as MMFeedbacks).PlayFeedbacks(); } GUI.backgroundColor = _originalBackgroundColor; // pause button if ((target as MMFeedbacks).ContainsLoop) { if (GUILayout.Button("Pause", EditorStyles.miniButtonMid)) { (target as MMFeedbacks).PauseFeedbacks(); } } // stop button if (GUILayout.Button("Stop", EditorStyles.miniButtonMid)) { (target as MMFeedbacks).StopFeedbacks(); } // reset button if (GUILayout.Button("Reset", EditorStyles.miniButtonMid)) { (target as MMFeedbacks).ResetFeedbacks(); } EditorGUI.EndDisabledGroup(); // reverse button if (GUILayout.Button("Revert", EditorStyles.miniButtonMid)) { (target as MMFeedbacks).Revert(); } // debug button EditorGUI.BeginChangeCheck(); { _debugView = GUILayout.Toggle(_debugView, "Debug View", EditorStyles.miniButtonRight); if (EditorGUI.EndChangeCheck()) { foreach (var f in (target as MMFeedbacks).Feedbacks) { f.hideFlags = _debugView ? HideFlags.HideInInspector : HideFlags.None; } UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); } } } EditorGUILayout.EndHorizontal(); float pingPong = Mathf.PingPong(Time.time, 0.25f); // if in pause, we display additional controls if (_targetMMFeedbacks.InScriptDrivenPause) { // draws a warning box _scriptDrivenBoxColor = Color.Lerp(_scriptDrivenBoxColorFrom, _scriptDrivenBoxColorTo, pingPong); GUI.skin.box.normal.background = Texture2D.whiteTexture; GUI.backgroundColor = _scriptDrivenBoxColor; GUI.skin.box.normal.textColor = Color.black; GUILayout.Box("Script driven pause in progress, call Resume() to exit pause", GUILayout.ExpandWidth(true)); GUI.backgroundColor = _originalBackgroundColor; GUI.skin.box.normal.background = _scriptDrivenBoxBackgroundTexture; // draws resume button if (GUILayout.Button("Resume")) { _targetMMFeedbacks.ResumeFeedbacks(); } } // Debug draw if (_debugView) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.PropertyField(_mmfeedbacks, true); EditorGUI.EndDisabledGroup(); } }
/// <summary> /// Draws the inspector, complete with helpbox, init mode selection, list of feedbacks, feedback selection and test buttons /// </summary> public override void OnInspectorGUI() { var e = Event.current; // Update object serializedObject.Update(); Undo.RecordObject(target, "Modified Feedback Manager"); EditorGUILayout.Space(); EditorGUILayout.HelpBox("Select feedbacks from the 'add a feedback' dropdown and customize them. Remember, if you don't use auto initialization (Awake or Start), " + "you'll need to initialize them via script.", MessageType.None); // Initialisation MMFeedbackStyling.DrawSection("Settings"); EditorGUILayout.PropertyField(_mmfeedbacksInitializationMode); EditorGUILayout.PropertyField(_mmfeedbacksAutoPlayOnStart); // Draw list MMFeedbackStyling.DrawSection("Feedbacks"); for (int i = 0; i < _mmfeedbacks.arraySize; i++) { MMFeedbackStyling.DrawSplitter(); SerializedProperty property = _mmfeedbacks.GetArrayElementAtIndex(i); // Failsafe but should not happend if (property.objectReferenceValue == null) { continue; } // Retrieve feedback MMFeedback feedback = property.objectReferenceValue as MMFeedback; feedback.hideFlags = _debugView ? HideFlags.None : HideFlags.HideInInspector; Undo.RecordObject(feedback, "Modified Feedback"); // Draw header int id = i; bool isExpanded = property.isExpanded; string label = feedback.Label; bool pause = false; if (feedback.Pause != null) { pause = true; } if ((feedback.LooperPause == true) && (Application.isPlaying)) { label = label + "[ " + (feedback as MMFeedbackLooper).NumberOfLoopsLeft + " loops left ] "; } Rect headerRect = MMFeedbackStyling.DrawHeader( ref isExpanded, ref feedback.Active, label, feedback.FeedbackColor, (GenericMenu menu) => { if (Application.isPlaying) { menu.AddItem(new GUIContent("Play"), false, () => PlayFeedback(id)); } else { menu.AddDisabledItem(new GUIContent("Play")); } menu.AddSeparator(null); //menu.AddItem(new GUIContent("Reset"), false, () => ResetFeedback(id)); menu.AddItem(new GUIContent("Remove"), false, () => RemoveFeedback(id)); menu.AddSeparator(null); menu.AddItem(new GUIContent("Copy"), false, () => CopyFeedback(id)); if (FeedbackCopy.HasCopy() && FeedbackCopy.Type == feedback.GetType()) { menu.AddItem(new GUIContent("Paste"), false, () => PasteFeedback(id)); } else { menu.AddDisabledItem(new GUIContent("Paste")); } }, feedback.FeedbackStartedAt, feedback.FeedbackDuration, feedback.Timing, pause ); // Check if we start dragging this feedback switch (e.type) { case EventType.MouseDown: if (headerRect.Contains(e.mousePosition)) { _draggedStartID = i; e.Use(); } break; default: break; } // Draw blue rect if feedback is being dragged if (_draggedStartID == i && headerRect != Rect.zero) { Color color = new Color(0, 1, 1, 0.2f); EditorGUI.DrawRect(headerRect, color); } // If hovering at the top of the feedback while dragging one, check where the feedback should be dropped : top or bottom if (headerRect.Contains(e.mousePosition)) { if (_draggedStartID >= 0) { _draggedEndID = i; Rect headerSplit = headerRect; headerSplit.height *= 0.5f; headerSplit.y += headerSplit.height; if (headerSplit.Contains(e.mousePosition)) { _draggedEndID = i + 1; } } } // If expanded, draw feedback editor property.isExpanded = isExpanded; if (isExpanded) { EditorGUI.BeginDisabledGroup(!feedback.Active); string helpText = FeedbackHelpAttribute.GetFeedbackHelpText(feedback.GetType()); if (!string.IsNullOrEmpty(helpText)) { GUIStyle style = new GUIStyle(EditorStyles.helpBox); style.richText = true; float newHeight = style.CalcHeight(new GUIContent(helpText), EditorGUIUtility.currentViewWidth); EditorGUILayout.LabelField(helpText, style); } EditorGUILayout.Space(); if (!_editors.ContainsKey(feedback)) { AddEditor(feedback); } Editor editor = _editors[feedback]; CreateCachedEditor(feedback, feedback.GetType(), ref editor); editor.OnInspectorGUI(); EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); EditorGUI.BeginDisabledGroup(!Application.isPlaying); EditorGUILayout.BeginHorizontal(); { if (GUILayout.Button("Play", EditorStyles.miniButtonMid)) { PlayFeedback(id); } if (GUILayout.Button("Stop", EditorStyles.miniButtonMid)) { StopFeedback(id); } } EditorGUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); EditorGUILayout.Space(); } } // Draw add new item if (_mmfeedbacks.arraySize > 0) { MMFeedbackStyling.DrawSplitter(); } EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); { // Feedback list int newItem = EditorGUILayout.Popup(0, _typeDisplays) - 1; if (newItem >= 0) { AddFeedback(_typesAndNames[newItem].FeedbackType); } // Paste feedback copy as new if (FeedbackCopy.HasCopy()) { if (GUILayout.Button("Paste as new", EditorStyles.miniButton, GUILayout.Width(EditorStyles.miniButton.CalcSize(new GUIContent("Paste as new")).x))) { PasteAsNew(); } } if (FeedbackCopy.HasMultipleCopies()) { if (GUILayout.Button("Paste all as new", EditorStyles.miniButton, GUILayout.Width(EditorStyles.miniButton.CalcSize(new GUIContent("Paste all as new")).x))) { PasteAllAsNew(); } } } if (!FeedbackCopy.HasMultipleCopies()) { if (GUILayout.Button("Copy all", EditorStyles.miniButton, GUILayout.Width(EditorStyles.miniButton.CalcSize(new GUIContent("Paste as new")).x))) { CopyAll(); } } EditorGUILayout.EndHorizontal(); // Reorder if (_draggedStartID >= 0 && _draggedEndID >= 0) { if (_draggedEndID != _draggedStartID) { if (_draggedEndID > _draggedStartID) { _draggedEndID--; } _mmfeedbacks.MoveArrayElement(_draggedStartID, _draggedEndID); _draggedStartID = _draggedEndID; } } if (_draggedStartID >= 0 || _draggedEndID >= 0) { switch (e.type) { case EventType.MouseUp: _draggedStartID = -1; _draggedEndID = -1; e.Use(); break; default: break; } } // Clean up bool wasRemoved = false; for (int i = _mmfeedbacks.arraySize - 1; i >= 0; i--) { if (_mmfeedbacks.GetArrayElementAtIndex(i).objectReferenceValue == null) { wasRemoved = true; _mmfeedbacks.DeleteArrayElementAtIndex(i); } } if (wasRemoved) { GameObject gameObject = (target as MMFeedbacks).gameObject; foreach (var c in gameObject.GetComponents <Component>()) { c.hideFlags = HideFlags.None; } } // Apply changes serializedObject.ApplyModifiedProperties(); // Draw debug MMFeedbackStyling.DrawSection("All Feedbacks Debug"); // Testing buttons EditorGUI.BeginDisabledGroup(!Application.isPlaying); EditorGUILayout.BeginHorizontal(); { if (GUILayout.Button("Initialize", EditorStyles.miniButtonLeft)) { (target as MMFeedbacks).Initialization(); } if (GUILayout.Button("Play", EditorStyles.miniButtonMid)) { (target as MMFeedbacks).PlayFeedbacks(); } if (GUILayout.Button("Stop", EditorStyles.miniButtonMid)) { (target as MMFeedbacks).StopFeedbacks(); } if (GUILayout.Button("Reset", EditorStyles.miniButtonMid)) { (target as MMFeedbacks).ResetFeedbacks(); } EditorGUI.EndDisabledGroup(); EditorGUI.BeginChangeCheck(); { _debugView = GUILayout.Toggle(_debugView, "Debug View", EditorStyles.miniButtonRight); if (EditorGUI.EndChangeCheck()) { foreach (var f in (target as MMFeedbacks).Feedbacks) { f.hideFlags = _debugView ? HideFlags.HideInInspector : HideFlags.None; } UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); } } } EditorGUILayout.EndHorizontal(); // Debug draw if (_debugView) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.PropertyField(_mmfeedbacks, true); EditorGUI.EndDisabledGroup(); } }