/// <summary> /// Shows a context menu callback to add a new state. /// </summary> void OnAddContextMenu() { var menu = new GenericMenu(); var stateScripts = FileUtility.GetScripts <InternalStateBehaviour>(); for (int i = 0; i < stateScripts.Length; i++) { System.Type childStateType = stateScripts[i].GetClass(); // Get the component path string componentPath; AddComponentMenu componentMenu = AttributeUtility.GetAttribute <AddComponentMenu>(childStateType, true); if (componentMenu != null && componentMenu.componentMenu != string.Empty) { componentPath = componentMenu.componentMenu; } else { componentPath = childStateType.ToString().Replace('.', '/'); } menu.AddItem(new GUIContent(componentPath), false, delegate() { StateUtility.AddState(m_Parent, childStateType); }); } // Shows the context menu menu.ShowAsContext(); }
/// <summary> /// Draw the transition arrows. /// </summary> public override void OnGUIAfterWindows() { if (m_StatesGUI != null) { // Trying to create connections? if (TransitionDragAndDrop.dragging != null) { switch (Event.current.type) { // Mouse Up? Let's try to connect a transition destination... case EventType.MouseUp: // Mouse button left? if (Event.current.button == 0) { var mousePos = Event.current.mousePosition; // The mouse is over a StateGUI? foreach (var guiState in m_StatesGUI) { if (guiState.rect.Contains(mousePos)) { StateUtility.SetNewDestination(TransitionDragAndDrop.state, TransitionDragAndDrop.dragging, guiState.state); Refresh(); Event.current.Use(); break; } } // Ignores the Transition drag'n & drop operation TransitionDragAndDrop.AcceptDrag(); Repaint(); } break; // Cancel drag case EventType.Used: goto case EventType.Ignore; case EventType.Ignore: TransitionDragAndDrop.AcceptDrag(); Event.current.Use(); Repaint(); break; // Draws the transition destination when dragging. case EventType.Repaint: // Is dragging? if (TransitionDragAndDrop.isDragging) { // Validate dragging members var guiState = TransitionDragAndDrop.guiState; if (guiState != null && guiState.state != null) { // Gets the mouse position and creates a Rect var mousePos = Event.current.mousePosition; var destRect = new Rect(mousePos.x, mousePos.y, 0, 0); var destYOffset = 0f; // The mouse is over a StateGUI? foreach (var _guiState in m_StatesGUI) { if (_guiState.rect.Contains(mousePos)) { // Updates the destRect and destYOffset. destRect = _guiState.rect; destYOffset = StateGUI.defaultHeight * .5f; break; } } // Draws the bezier line TransitionDragAndDrop.transitionGUI.DrawArrow(guiState.rect, destRect, destYOffset); } } break; case EventType.MouseDrag: if (TransitionDragAndDrop.isDragging) { Repaint(); } break; } } } // Get the current event Event current = Event.current; var activeFsm = BehaviourWindow.activeFsm; // cached activeFsm switch (current.type) { // Show context menu? case EventType.ContextClick: OnContextMenu(); Event.current.Use(); break; case EventType.MouseDown: // If the left mouse button is down then unselect the state and start the dragging rect if (current.button == 0) { BehaviourWindow.activeState = null; EditorGUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; if (!current.alt && !current.shift) { m_SelectionStartPoint = current.mousePosition; m_SelectionRect = true; } current.Use(); } break; // Event ignored? case EventType.Ignore: // Cancel selection rect? if (m_SelectionRect) { goto case EventType.MouseUp; } break; // Cancel selection rect? case EventType.MouseUp: if (m_SelectionRect) { m_SelectionRect = false; GUIUtility.hotControl = 0; SelectNodesInRect(GetRectFromPoints(m_SelectionStartPoint, current.mousePosition)); current.Use(); } break; // Selection rect? case EventType.MouseDrag: if (m_SelectionRect) { current.Use(); } else if (current.button == 2) { m_ScrollView -= current.delta; current.Use(); } break; // Delete selected states? case EventType.ValidateCommand: // Use event to call event ExecuteCommand if (current.commandName == "Paste" && activeFsm != null && StateUtility.statesToPaste != null && StateUtility.statesToPaste.Length > 0) { current.Use(); } else if (current.commandName == "Copy" && activeFsm != null && Selection.objects.Length > 0) { current.Use(); } else if (current.commandName == "Duplicate" && activeFsm != null) { // Is there a selected state? foreach (var obj in Selection.objects) { if (obj is InternalStateBehaviour) { current.Use(); break; } } } else if ((current.commandName == "Delete" || current.commandName == "SoftDelete") && BehaviourWindow.activeState != null) { current.Use(); } break; case EventType.ExecuteCommand: if (current.commandName == "Paste") { StateUtility.PasteStates(activeFsm); } else if (current.commandName == "Copy") { StateUtility.CopySelectedStates(); } else if (current.commandName == "Duplicate") { StateUtility.CopySelectedStates(); StateUtility.PasteStates(activeFsm); } else if (current.commandName == "Delete" || current.commandName == "SoftDelete") { foreach (InternalStateBehaviour state in Selection.objects) { StateUtility.Destroy(state); } Refresh(); current.Use(); } break; // Dragging? case EventType.DragUpdated: if (DragAndDrop.objectReferences.Length > 0 && DragAndDrop.objectReferences[0] is MonoScript && BehaviourWindow.activeFsm != null) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } break; // Drag perform? case EventType.DragPerform: if (DragAndDrop.objectReferences.Length > 0 && DragAndDrop.objectReferences[0] is MonoScript && BehaviourWindow.activeFsm != null) { var index = 0; // index of added states var mousePosition = current.mousePosition - new Vector2(StateGUI.defaultWidth, StateGUI.defaultHeight) * .5f; // Register undo #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterSceneUndo("Add States"); #endif // Get all GetScripts var scripts = new List <MonoScript>(); foreach (var obj in DragAndDrop.objectReferences) { var script = obj as MonoScript; if (script != null) { scripts.Add(script); } } // Go trough all monoscripts foreach (MonoScript monoScript in scripts) { var type = monoScript.GetClass(); // The type is a valid InternalStateBehaviour instance? if (type != null && !type.IsAbstract) { // Add state behaviour if (type.IsSubclassOf(typeof(InternalStateBehaviour))) { var newState = StateUtility.AddState(activeFsm, type); // The state is valid? if (newState != null) { // Set the newState position newState.position = mousePosition + new Vector2(StateGUI.defaultWidth * index * .5f, 20f * index); index++; } } // Add mono state else if (type.IsSubclassOf(typeof(MonoBehaviour))) { var newMonoState = StateUtility.AddState(activeFsm, typeof(InternalMonoState)) as InternalMonoState; // Set the newMonoState position if (newMonoState != null) { // Set mono state position newMonoState.position = mousePosition + new Vector2(StateGUI.defaultWidth * index * .5f, 20f * index); index++; newMonoState.monoBehaviour = newMonoState.gameObject.AddComponent(type) as MonoBehaviour; // Register undo #if !UNITY_4_0_0 && !UNITY_4_1 && !UNITY_4_2 if (newMonoState.monoBehaviour != null) { Undo.RegisterCreatedObjectUndo(newMonoState.monoBehaviour, "Add Component"); } #endif } } } } // Sets dirty flag if (activeFsm.gameObject != null) { EditorUtility.SetDirty(activeFsm.gameObject); } // Accept drag DragAndDrop.AcceptDrag(); current.Use(); Refresh(); } break; // Draw the selection rect? case EventType.Repaint: if (m_SelectionRect) { s_Styles.selectionRect.Draw(GetRectFromPoints(m_SelectionStartPoint, current.mousePosition), false, false, false, false); } break; } GUI.EndScrollView(); // Close scroolView. GUI.EndGroup(); // Close group }
/// <summary> /// Shows a context menu to add a new parent. /// </summary> void OnContextMenu() { var menu = new UnityEditor.GenericMenu(); // Get the active game object var gameObject = Selection.activeGameObject; // The selected game object is not null? if (gameObject != null) { // Gets all scripts that inherits from ParentBehaviour class MonoScript[] scripts = FileUtility.GetScripts <ParentBehaviour>(); for (int i = 0; i < scripts.Length; i++) { var type = scripts[i].GetClass(); // Get the component path string componentPath = "Add Parent/"; AddComponentMenu componentMenu = AttributeUtility.GetAttribute <AddComponentMenu>(type, false); if (componentMenu == null || componentMenu.componentMenu != string.Empty) { componentMenu = AttributeUtility.GetAttribute <AddComponentMenu>(type, true); if (componentMenu != null && componentMenu.componentMenu != string.Empty) { componentPath += componentMenu.componentMenu; } else { componentPath += type.ToString().Replace('.', '/'); } // Add to menu menu.AddItem(new GUIContent(componentPath), false, delegate() { BehaviourWindow.activeParent = StateUtility.AddState(gameObject, type) as ParentBehaviour; }); } } } else { menu.AddDisabledItem(new GUIContent("Add Parent/")); ShowNotification(new GUIContent("Select a Game Object and right click in this window!")); } // Add option to paste states if (Selection.activeGameObject != null && StateUtility.statesToPaste != null && StateUtility.statesToPaste.Length > 0) { menu.AddItem(new GUIContent("Paste State"), false, delegate() { StateUtility.CloneStates(Selection.activeGameObject, StateUtility.statesToPaste, null); }); } else { menu.AddDisabledItem(new GUIContent("Paste State")); } // Refresh window? // menu.AddSeparator(""); // menu.AddItem(new GUIContent("Refresh"), false ,Refresh); // Shows the controller menu menu.ShowAsContext(); }
/// <summary> /// Shows the context menu. /// </summary> void OnContextMenu() { var menu = new GenericMenu(); var activeFsm = BehaviourWindow.activeFsm; if (activeFsm != null) { m_LastMousePos = Event.current.mousePosition; // Get the states scripts MonoScript[] stateScripts = FileUtility.GetScripts <InternalStateBehaviour>(); for (int i = 0; i < stateScripts.Length; i++) { System.Type type = stateScripts[i].GetClass(); // Get the component path string componentPath = "Add State/"; AddComponentMenu componentMenu = AttributeUtility.GetAttribute <AddComponentMenu>(type, false); if (componentMenu == null || componentMenu.componentMenu != string.Empty) { componentMenu = AttributeUtility.GetAttribute <AddComponentMenu>(type, true); if (componentMenu != null && componentMenu.componentMenu != string.Empty) { componentPath += componentMenu.componentMenu; } else { componentPath += type.ToString().Replace('.', '/'); } menu.AddItem(new GUIContent(componentPath), false, delegate() { InternalStateBehaviour newState = StateUtility.AddState(activeFsm, type); // Sets the newState position and dirty flag if (newState != null) { newState.position = m_LastMousePos - new Vector2(StateGUI.defaultWidth, StateGUI.defaultHeight) * .5f; EditorUtility.SetDirty(newState); } }); } } } else { menu.AddDisabledItem(new GUIContent("Add State")); } // Separator menu.AddSeparator(""); menu.AddItem(new GUIContent("Copy FSM"), false, delegate() { StateUtility.statesToPaste = new InternalStateBehaviour[] { activeFsm }; }); if (StateUtility.statesToPaste != null && StateUtility.statesToPaste.Length > 0 && activeFsm != null) { menu.AddItem(new GUIContent("Paste State"), false, delegate() { StateUtility.PasteStates(activeFsm); }); } else { menu.AddDisabledItem(new GUIContent("Paste State")); } // Separator menu.AddSeparator(""); menu.AddItem(new GUIContent("Delete FSM"), false, delegate() { StateUtility.Destroy(activeFsm); }); // menu.AddSeparator(""); // Separator // if (BehaviourWindow.Instance != null) // menu.AddItem(new GUIContent("Refresh"), false, BehaviourWindow.Instance.Refresh); // else // menu.AddDisabledItem(new GUIContent("Refresh")); // Shows the context menu menu.ShowAsContext(); }