/// <summary>
        /// Shows a context menu to delete or unparent a state.
        /// <param name="state">The state to delete or unparent.</param>
        /// </summary>
        void OnDeleteUnparentContextMenu(InternalStateBehaviour state)
        {
            var menu = new GenericMenu();

            menu.AddItem(new GUIContent("Unparent"), false, this.OnUnparentState, state);
            menu.AddItem(new GUIContent("Delete"), false, this.OnDeleteState, state);
            menu.ShowAsContext();
        }
 /// <summary>
 /// Refresh the window content.
 /// </summary>
 public void Refresh()
 {
     OnSelectionChange();
     if (m_ParentGUI != null)
     {
         m_ParentGUI.Refresh();
     }
     InternalStateBehaviour.ResetRefresh();
 }
        /// <summary>
        /// Adds a state to the supplied parent.
        /// Automatically handles undo.
        /// <param name="parent">The ParentBehaviour to add the new state.</param>
        /// <param name="type">The new state type.</param>
        /// <returns>The new created state.<returns>
        /// </summary>
        public static InternalStateBehaviour AddState(ParentBehaviour parent, System.Type type)
        {
            // Validate parameters
            if (type != null && parent != null)
            {
                // Create and register undo
                #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                Undo.RegisterSceneUndo("Create State (" + type.Name + ")");
                #endif

                InternalStateBehaviour newState = parent.AddState(type);


                if (newState != null)
                {
                    // Register undo
                    #if !UNITY_4_0_0 && !UNITY_4_1 && !UNITY_4_2
                    Undo.RegisterCreatedObjectUndo(newState, "Create State (" + type.Name + ")");
                    #endif

                    // The parent is a FSM?
                    var fsm = parent as InternalStateMachine;
                    if (fsm != null)
                    {
                        // The newState is an AnyState?
                        if (newState is InternalAnyState)
                        {
                            // The fsm already has an AnyState?
                            if (fsm.anyState != null)
                            {
                                // Destroy the curren anyState
                                StateUtility.Destroy(fsm.anyState);
                            }

                            // Add the new anyState
                            fsm.anyState = newState as InternalAnyState;
                        }
                        // The start state is null?
                        else if (fsm.startState == null)
                        {
                            // Set the new state as the start state
                            fsm.startState = newState;
                            EditorUtility.SetDirty(fsm);
                        }
                    }

                    // Sets dirty flag
                    EditorUtility.SetDirty(parent.gameObject);
                }

                return(newState);
            }
            return(null);
        }
        public static int GetStateMachineDepth(this InternalStateBehaviour state)
        {
            int depth = 0;
            InternalStateMachine fsm = state.fsm;

            while (fsm != null)
            {
                fsm = fsm.fsm;
                depth++;
            }
            return(depth);
        }
        /// <summary>
        /// Adds a new transition to the state.
        /// Automatically handles undo.
        /// <param name="state">The state to add a new transition.</param>
        /// <param name="eventID">The event id of the new transition.</param>
        /// </summary>
        public static void AddTransition(InternalStateBehaviour state, int eventID)
        {
            // Register undo
            #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
            Undo.RegisterUndo(state, "Create Transition");
            #else
            Undo.RecordObject(state, "Create Transition");
            #endif

            state.AddTransition(eventID);
            EditorUtility.SetDirty(state);
        }
        public static int GetBehaviourTreeDepth(this InternalStateBehaviour state)
        {
            int depth = 0;
            InternalBehaviourTree tree = state.tree;

            while (tree != null)
            {
                tree = tree.tree;
                depth++;
            }
            return(depth);
        }
示例#7
0
        /// <summary>
        /// Draw the state pop-up.
        /// </summary>
        public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent)
        {
            // InternalStateBehaviour
            if (property.propertyType == NodePropertyType.UnityObject && property.type == typeof(InternalStateBehaviour))
            {
                var rect      = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup);
                var id        = GUIUtility.GetControlID(FocusType.Passive);
                var popupRect = EditorGUI.PrefixLabel(rect, id, guiContent);
                var state     = property.value as InternalStateBehaviour;

                // Set the pop-up color
                var oldGUIColor = GUI.color;
                if (state == null)
                {
                    GUI.color = Color.red;
                }

                if (GUI.Button(popupRect, state != null ? state.stateName : "Null", EditorStyles.popup))
                {
                    // Get states
                    var states = node.tree.states;

                    // Create the pop-up menu
                    var menu = new GenericMenu();

                    // Add null
                    menu.AddItem(new GUIContent("Null"), state == null, delegate() { property.value = (InternalStateBehaviour)null; });

                    // Add states
                    for (int i = 0; i < states.Count; i++)
                    {
                        InternalStateBehaviour currentState = states[i];
                        //setField = field != null ? new SetField(this.target, target, states[i], field, m_Tree) : new SetField(this.target, arrayField, index, states[i], m_Tree);
                        menu.AddItem(new GUIContent(states[i].stateName), state == states[i], delegate() { property.value = currentState; });
                    }

                    // Show menu
                    menu.ShowAsContext();
                }

                // Restore GUI.color
                GUI.color = oldGUIColor;
            }
            else
            {
                EditorGUILayout.LabelField(guiContent, new GUIContent("Use TreeState with InternalStateBehaviour."));
            }
        }
        /// <summary>
        /// Sets a new destination state to the supplied transition.
        /// <param name="state">The state that owns the target transition.</param>
        /// <param name="transition">The transition to set the new destination.</param>
        /// <param name="destination">The new destination state.</param>
        /// </summary>
        public static void SetNewDestination(InternalStateBehaviour state, StateTransition transition, InternalStateBehaviour destination)
        {
            // Validate members
            if (state != null && transition != null)
            {
                // Register undo
                #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                Undo.RegisterUndo(state, "Transition Destination");
                #else
                Undo.RecordObject(state, "Transition Destination");
                #endif

                // Create a connection to the destination
                transition.destination = destination;

                // Set state dirty flag
                EditorUtility.SetDirty(state);
            }
        }
        /// <summary>
        /// Sets a new event id in the supplied transition.
        /// <param name="state">The state that owns the target transition.</param>
        /// <param name="transition">The transition to set the new event id.</param>
        /// <param name="eventId">The new event id.</param>
        /// </summary>
        public static void SetNewEvent(InternalStateBehaviour state, StateTransition transition, int eventId)
        {
            // Validate members
            if (state != null && transition != null)
            {
                // Register undo
                #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                Undo.RegisterUndo(state, "Transition Event");
                #else
                Undo.RecordObject(state, "Transition Event");
                #endif

                // Set transition event
                transition.eventID = eventId;

                // Set state dirty flag
                EditorUtility.SetDirty(state);
            }
        }
示例#10
0
        /// <summary>
        /// The constructor.
        /// <param name="id">A unique id for the window.</param>
        /// <param name="state">The state that this object will draw.</param>
        /// </summary>
        public StateGUI(int id, InternalStateBehaviour state)
        {
            m_State = state;
            m_Id    = id;

            // Get state data
            if (m_State != null)
            {
                m_Icon = IconUtility.GetIcon(m_State.GetType(), m_State);
                // It's the start state?
                m_IsStart = m_State.fsm != null && m_State.fsm.startState == m_State;
                // It's the concurrent state?
                m_IsConcurrent = m_State.fsm != null && m_State.fsm.concurrentState == m_State;
                // Transition visual debugging
                m_State.onTransitionPerformed += OnTransitionPerformed;
                // Build gui transitions
                CreateTransitionGUIs();
            }
        }
示例#11
0
        /// <summary>
        /// Removes the transition from the state.
        /// <param name="state">The state that owns the target transition.</param>
        /// <param name="transition">The transition to  be removed.</param>
        /// </summary>
        public static void RemoveTransition(InternalStateBehaviour state, StateTransition transition)
        {
            // Validate members
            if (state != null && transition != null)
            {
                // Register undo
                #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                Undo.RegisterUndo(state, "Delete Transition");
                #else
                Undo.RecordObject(state, "Delete Transition");
                #endif

                // Remove transition
                state.RemoveTransition(transition);

                // Set state dirty flag
                EditorUtility.SetDirty(state);
            }
        }
示例#12
0
 /// <summary>
 /// Update the hideFlags of the supplied state.
 /// <param name ="state">The target state.</param>
 /// </summary>
 static void OnStateHideFlag(InternalStateBehaviour state)
 {
     // It's a valid state?
     if (state != null)
     {
         // It is not a prefab?
         if (!UnityEditor.AssetDatabase.Contains(state.gameObject))
         {
             // The state is not a root parent and the hide flag is True?
             if (state.hideFlag && !state.isRoot)
             {
                 state.hideFlags = HideFlags.HideInInspector;
             }
             else
             {
                 state.hideFlags = (HideFlags)0;
             }
         }
     }
 }
示例#13
0
        /// <summary>
        /// Returns the destination of a transition.
        /// </summary>
        protected InternalStateBehaviour GetDestination(InternalStateMachine fsm, InternalStateBehaviour destination)
        {
            if (fsm == null || destination == null)
            {
                return(null);
            }

            InternalStateMachine currentFsm = destination.fsm;

            if (currentFsm == fsm)
            {
                return(destination);
            }

            while (currentFsm != null && fsm != currentFsm.fsm)
            {
                currentFsm = currentFsm.fsm;
            }

            return(currentFsm);
        }
        /// <summary>
        /// Context menu callback to delete a state.
        /// <param name="userData">The state to be deleted.</param>
        /// </summary>
        void OnDeleteState(object userData)
        {
            var state = userData as InternalStateBehaviour;

            if (state != null)
            {
                if (Application.isPlaying && !AssetDatabase.Contains(state.gameObject))
                {
                    InternalStateBehaviour.Destroy(state);
                }
                else
                {
                    #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                    Undo.RegisterSceneUndo("Delete");
                    Object.DestroyImmediate(state, true);
                    #else
                    Undo.DestroyObjectImmediate(state);
                    #endif
                }
            }
        }
示例#15
0
        /// <summary>
        /// Sets the state as the concurrent state of the fsm.
        /// Automatically handles undo.
        /// <param name="state">The new fsm concurrent state.</param>
        /// </summary>
        public static void SetAsConcurrent(InternalStateBehaviour state)
        {
            // Get the fsm
            var fsm = state.fsm;

            // The fsm is valid and the state is not the start state?
            if (fsm != null && fsm.concurrentState != state)
            {
                // Register undo
                #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                Undo.RegisterUndo(fsm, "Concurrent State");
                #else
                Undo.RecordObject(fsm, "Concurrent State");
                #endif

                fsm.concurrentState = state;
                EditorUtility.SetDirty(fsm);

                // EditorUtility.SetDirty(state); // Repaint state inspector
            }
        }
示例#16
0
        /// <summary>
        /// Class constructor.
        /// <param name="stateTransition">The target transition.</param>
        /// <param name="destination">The target destination.</param>
        /// <param name="index">The transition index.</param>
        /// <param name="blackboard">The state blackboard.</param>
        /// </summary>
        public TransitionGUI(StateTransition stateTransition, InternalStateBehaviour destination, int index, InternalBlackboard blackboard)
        {
            m_Transition  = stateTransition;
            m_Destination = destination;

            // It's a global event?
            if (m_Transition.eventID < 0)
            {
                if (InternalGlobalBlackboard.Instance != null)
                {
                    m_FsmEvent = InternalGlobalBlackboard.Instance.GetFsmEvent(m_Transition.eventID);
                }
            }
            // It's a local variable and the blackboard is not null?
            else if (m_Transition.eventID > 0 && blackboard != null)
            {
                m_FsmEvent = blackboard.GetFsmEvent(m_Transition.eventID);
            }

            // Get the transition arrow vertical offset
            m_VerticalOffset = StateGUI.defaultHeight + TransitionGUI.defaultHeight * (index + .35f);
        }
        /// <summary>
        /// Shows a menu to select states that are in the same parent as the supplied state.
        /// <param name="state">The target state.</param>
        /// </summary>
        void ShowStateSelectionMenu(InternalStateBehaviour state)
        {
            var menu        = new GenericMenu();
            var states      = state.GetComponents <InternalStateBehaviour>();
            var uniqueNames = new List <string>();

            // Build the menu
            for (int i = 0; i < states.Length; i++)
            {
                // Get the current state
                var currentState = states[i];

                // The current state has the same parent as the supplied state?
                if (currentState.parent == state.parent)
                {
                    string currentName = StringHelper.GetUniqueNameInList(uniqueNames, currentState.stateName);
                    uniqueNames.Add(currentName);
                    menu.AddItem(new GUIContent(currentName), state == currentState, delegate() { activeParent = currentState as ParentBehaviour ?? currentState.parent; Selection.objects = new UnityEngine.Object[] { currentState }; });
                }
            }

            menu.ShowAsContext();
        }
示例#18
0
        /// <summary>
        /// Creates the TransitionGUIs list to display the transition event name.
        /// </summary>
        protected virtual void CreateTransitionGUIs()
        {
            m_TransitionGUIs.Clear();

            if (m_State != null)
            {
                // Get the blackobard
                var blackboard = m_State.blackboard;
                // Get the transitions list
                var transitions = m_State.transitions;

                for (int i = 0; i < transitions.Length; i++)
                {
                    // Get the destination
                    InternalStateBehaviour destination = GetDestination(m_State.fsm, transitions[i].destination);
                    if (destination == null && transitions[i].destination != null && GetDestination(transitions[i].destination.fsm, m_State) != null)
                    {
                        destination = m_State.fsm;
                    }

                    m_TransitionGUIs.Add(new TransitionGUI(transitions[i], destination, i, blackboard));
                }
            }
        }
示例#19
0
        /// <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();
        }
示例#20
0
 /// <summary>
 /// Returns true if he supplied state is not null and is not a start state.
 /// <param name="state">The state to test.</param>
 /// <returns>False if the state is a start state; True otherwise.</returns>
 /// </summary>
 protected bool IsNotStart(InternalStateBehaviour state)
 {
     return(state != null && state.fsm != null && state.fsm.startState != state);
 }
示例#21
0
 public SetParent(InternalStateBehaviour state, ParentBehaviour newParent)
 {
     this.state     = state;
     this.newParent = newParent;
 }
示例#22
0
 /// <summary>
 /// Returns true if the supplied state is not null and is not a root.
 /// <param name="state">The state to test.</param>
 /// <returns>False if the state is a root; True otherwise.</returns>
 /// </summary>
 protected bool IsNotRoot(InternalStateBehaviour state)
 {
     return(state != null && !state.isRoot);
 }
示例#23
0
        /// <summary>
        /// Paste the state in StateUtility.stateToPaste in the supplied fsm.
        /// <param name="gameObject">The target gameObject.</param>
        /// <param name="originalStates">The original states.</param>
        /// <param name="parent">Optionally parent for the cloned states.</param>
        /// </summary>
        public static void CloneStates(GameObject gameObject, InternalStateBehaviour[] originalStates, ParentBehaviour parent)
        {
            if (gameObject != null && originalStates != null && originalStates.Length > 0)
            {
                var orginalClone = new Dictionary <InternalStateBehaviour, InternalStateBehaviour>();
                var originalFsm = parent != null ? originalStates[0].parent as InternalStateMachine : null;
                var newFsm = parent as InternalStateMachine;
                InternalStateBehaviour startState = null, concurrentState = null;
                InternalAnyState       anyState = null;

                // Copy blackboard data?
                var newBlackboard = gameObject.GetComponent <InternalBlackboard>();
                if (newBlackboard == null)
                {
                    // Get the original blackboard
                    InternalBlackboard originalBlackboard = originalStates[0].GetComponent <InternalBlackboard>();

                    #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                    Undo.RegisterSceneUndo("Paste State");
                    // Create the new blacbkoard
                    newBlackboard = gameObject.AddComponent(originalBlackboard.GetType()) as InternalBlackboard;
                    #else
                    // Create the new blacbkoard
                    newBlackboard = gameObject.AddComponent(originalBlackboard.GetType()) as InternalBlackboard;
                    if (newBlackboard != null)
                    {
                        Undo.RegisterCreatedObjectUndo(newBlackboard, "Paste State");
                    }
                    #endif

                    // Copy serialized values
                    EditorUtility.CopySerialized(originalBlackboard, newBlackboard);
                }

                foreach (InternalStateBehaviour state in originalStates)
                {
                    // Don't clone AnyState in StateMachines
                    if (state != null && (newFsm == null || !(state is InternalAnyState) || newFsm.anyState == null))
                    {
                        #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                        Undo.RegisterSceneUndo("Paste State");
                        // Create a new state
                        var newState = gameObject.AddComponent(state.GetType()) as InternalStateBehaviour;
                        #else
                        // Create a new state
                        var newState = gameObject.AddComponent(state.GetType()) as InternalStateBehaviour;
                        if (newState != null)
                        {
                            Undo.RegisterCreatedObjectUndo(newState, "Paste State");
                        }
                        #endif

                        if (newState != null)
                        {
                            // Store state
                            orginalClone.Add(state, newState);

                            // Copy serialized values
                            EditorUtility.CopySerialized(state, newState);

                            // Update blackboard
                            if (state.gameObject != newState.gameObject)
                            {
                                var serialObj = new SerializedObject(newState);
                                serialObj.FindProperty("m_Blackboard").objectReferenceValue = newBlackboard;
                                serialObj.ApplyModifiedProperties();
                                serialObj.Dispose();
                            }

                            // Update the AnyState, StartState and ConcurrentState
                            if (newState is InternalStateMachine)
                            {
                                var fsm = newState as InternalStateMachine;
                                fsm.startState      = null;
                                fsm.concurrentState = null;
                                fsm.anyState        = null;
                            }

                            EditorUtility.SetDirty(newState);

                            // Set new parent
                            if (parent != null)
                            {
                                newState.parent = parent;

                                // Update position
                                if (parent == state.parent)
                                {
                                    newState.position += new Vector2(20f, 20f);
                                }
                            }
                            else
                            {
                                newState.parent = null;
                            }

                            // Saves state and sets dirty flag
                            INodeOwner nodeOwner = newState as INodeOwner;
                            if (nodeOwner != null)
                            {
                                nodeOwner.LoadNodes();
                                StateUtility.SetDirty(nodeOwner);
                            }
                            else
                            {
                                EditorUtility.SetDirty(newState);
                            }

                            // Try to get the StartState, AnyState and ConcurrentState
                            if (originalFsm != null)
                            {
                                if (originalFsm.startState == state)
                                {
                                    startState = newState;
                                }
                                if (anyState == null)
                                {
                                    anyState = newState as InternalAnyState;
                                }
                                if (originalFsm.concurrentState == state)
                                {
                                    concurrentState = newState;
                                }
                            }
                        }
                    }
                }

                // Set StartState, AnyState and ConcurrentState
                if (newFsm != null)
                {
                    if (newFsm.startState == null)
                    {
                        newFsm.startState = startState;
                    }
                    if (newFsm.anyState == null)
                    {
                        newFsm.anyState = anyState;
                    }
                    if (newFsm.concurrentState == null)
                    {
                        newFsm.concurrentState = concurrentState;
                    }
                    EditorUtility.SetDirty(newFsm);
                }

                // Try to update the transitions' destination
                foreach (KeyValuePair <InternalStateBehaviour, InternalStateBehaviour> pair in orginalClone)
                {
                    InternalStateBehaviour state    = pair.Key;
                    InternalStateBehaviour newState = pair.Value;

                    // Update the newState transition
                    for (int i = 0; i < newState.transitions.Length && i < state.transitions.Length; i++)
                    {
                        // The original destination is valid?
                        if (state.transitions[i].destination != null && orginalClone.ContainsKey(state.transitions[i].destination))
                        {
                            newState.transitions[i].destination = orginalClone[state.transitions[i].destination];
                        }
                    }

                    if (newState is ParentBehaviour)
                    {
                        var stateAsParent = state as ParentBehaviour;

                        // Removes the newState from the children state to avoid an infinite loop
                        List <InternalStateBehaviour> children = stateAsParent.states;
                        if (children.Contains(newState))
                        {
                            children.Remove(newState);
                        }

                        StateUtility.CloneStates(newState.gameObject, children.ToArray(), newState as ParentBehaviour);
                    }

                    EditorUtility.SetDirty(newState);
                }

                EditorUtility.SetDirty(gameObject);
            }
        }
示例#24
0
        /// <summary>
        /// Destroys the supplied state.
        /// Automatically handles undo.
        /// <param name="state">The state to be destroyed.</param>
        /// </summary>
        public static void Destroy(InternalStateBehaviour state)
        {
            // its a valid state
            if (state != null)
            {
                var gameObject = state.gameObject;                  // stores the gameObject to set dirty flag
                var isPrefab   = FileUtility.IsPrefab(gameObject);
                var monoState  = state as InternalMonoState;        // its a mono state?

                // It is a fsm?
                if (state is ParentBehaviour)
                {
                    var parent = state as ParentBehaviour;
                    foreach (var child in parent.states)
                    {
                        StateUtility.Destroy(child);
                    }
                }

                if (Application.isPlaying && !isPrefab)
                {
                    // Its a MonoState and the user wants to destroy mono behaviour to?
                    if (monoState != null && monoState.monoBehaviour != null && EditorUtility.DisplayDialog("Destroy MonoBehaviour?", "Do you want to destroy the " + monoState.monoBehaviour.GetType().ToString() + "?", "Ok", "Cancel"))
                    {
                        var monoStateGO = monoState.gameObject;
                        Object.Destroy(monoState.monoBehaviour);
                        EditorUtility.SetDirty(monoStateGO);
                    }
                    Object.Destroy(state);
                }
                else
                {
                    // Register scene undo
                    #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                    Undo.RegisterSceneUndo("Delete");
                    #endif

                    // Its a MonoState and the user wants to destroy the MonoBehaviour to?
                    if (monoState != null && monoState.monoBehaviour != null && EditorUtility.DisplayDialog("Destroy MonoBehaviour?", "Do you want to destroy the " + monoState.monoBehaviour.GetType().ToString() + "?", "Ok", "Cancel"))
                    {
                        // Gets the  MonoState game object
                        var monoStateGO = monoState.gameObject;

                        // Destroy the mono behaviour
                        #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                        Object.DestroyImmediate(monoState.monoBehaviour, true);
                        #else
                        Undo.DestroyObjectImmediate(monoState.monoBehaviour);
                        #endif

                        // Set game object dirty flag
                        EditorUtility.SetDirty(monoStateGO);
                    }

                    // Destroys the state
                    #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                    Object.DestroyImmediate(state, true);
                    #else
                    Undo.DestroyObjectImmediate(state);
                    #endif
                }

                EditorUtility.SetDirty(gameObject);
            }
        }