private void DeleteState(int stateIndex)
        {
            Undo.RegisterCompleteObjectUndo(new UnityEngine.Object[] { stateMachine, nodesInfo, this }, "State Deleted");

            DeleteStateReferencesInTransitions(stateIndex);

            nodesInfo.StatesCount--;
            nodesInfo.Names.RemoveAt(stateIndex);
            nodesInfo.Rects.RemoveAt(stateIndex);

            transitions.RemoveAt(stateIndex);

            List <Action[]> actions = new List <Action[]>(StateMachineReflections.GetActions(stateMachine));

            actions.RemoveAt(stateIndex);
            List <bool[]> isDurationEnd = new List <bool[]>(StateMachineReflections.GetIsDurationsEnd(stateMachine));

            isDurationEnd.RemoveAt(0);
            List <Duration> durations = new List <Duration>(StateMachineReflections.GetDurations(stateMachine));

            durations.RemoveAt(0);
            List <Condition[][]> conditions = new List <Condition[][]>(StateMachineReflections.GetConditions(stateMachine));

            conditions.RemoveAt(stateIndex);

            SaveStateMachine(actions.ToArray(), isDurationEnd.ToArray(), durations.ToArray(), conditions.ToArray());

            if (startStateIndex == stateIndex)
            {
                StateMachineReflections.SetStartStateIndex(stateMachine, startStateIndex = nodesInfo.StatesCount > 0 ? 0 : -1);
            }
        }
            private void SaveDuration()
            {
                List <Duration> durations = new List <Duration>(StateMachineReflections.GetDurations(stateMachine));

                durations[stateIndex] = duration;
                StateMachineReflections.SetDurations(stateMachine, durations.ToArray());
            }
        private void CreateState(Vector2 mousePosition)
        {
            Undo.RegisterCompleteObjectUndo(new UnityEngine.Object[] { stateMachine, nodesInfo, this }, "State Created");

            nodesInfo.StatesCount++;
            nodesInfo.Names.Add("New State");
            nodesInfo.Rects.Add(new Rect(mousePosition, NODE_SIZE));

            transitions.Add(new List <int>());

            List <Action[]> actions = new List <Action[]>(StateMachineReflections.GetActions(stateMachine));

            actions.Add(new Action[0]);
            List <bool[]> isDurationEnd = new List <bool[]>(StateMachineReflections.GetIsDurationsEnd(stateMachine));

            isDurationEnd.Add(new bool[0]);
            List <Duration> durations = new List <Duration>(StateMachineReflections.GetDurations(stateMachine));

            durations.Add(new ConstantDuration());
            List <Condition[][]> conditions = new List <Condition[][]>(StateMachineReflections.GetConditions(stateMachine));

            conditions.Add(new Condition[0][]);

            SaveStateMachine(actions.ToArray(), isDurationEnd.ToArray(), durations.ToArray(), conditions.ToArray());

            if (nodesInfo.StatesCount == 1)
            {
                StateMachineReflections.SetStartStateIndex(stateMachine, startStateIndex = 0);
            }
        }
 private void SaveStateMachine(Action[][] actions, bool[][] isDurationEnd, Duration[] durations, Condition[][][] conditions)
 {
     StateMachineReflections.SetTransitions(stateMachine, transitions.Select(a => a.ToArray()).ToArray());
     StateMachineReflections.SetActions(stateMachine, actions);
     StateMachineReflections.SetIsDurationsEnd(stateMachine, isDurationEnd);
     StateMachineReflections.SetDurations(stateMachine, durations);
     StateMachineReflections.SetConditions(stateMachine, conditions);
 }
        public static void OpenWindow(StateMachineController stateMachine)
        {
            StateMachineWindow window = GetWindow <StateMachineWindow>();

            window.titleContent = new GUIContent("State Machine");
            window.minSize      = new Vector2(800, 600);
            window.stateMachine = stateMachine;

            window.serializedObject = new SerializedObject(stateMachine);

            window.nodesInfo       = (NodesInfo)AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(stateMachine), typeof(NodesInfo));
            window.transitions     = new List <List <int> >(StateMachineReflections.GetTransitions(stateMachine).Select(i => i.ToList()));
            window.startStateIndex = StateMachineReflections.GetStartStateIndex(stateMachine);
        }
            public State(StateMachineController stateMachine, NodesInfo nodesInfo, int stateIndex)
            {
                this.stateMachine = stateMachine;
                this.nodesInfo    = nodesInfo;
                this.stateIndex   = stateIndex;

                transitionsIndexes = StateMachineReflections.GetTransitions(stateMachine);
                isDurationsEnd     = StateMachineReflections.GetIsDurationsEnd(stateMachine);
                conditions         = StateMachineReflections.GetConditions(stateMachine);

                name     = nodesInfo.Names[stateIndex];
                duration = StateMachineReflections.GetDurations(stateMachine)[stateIndex];
                actions  = StateMachineReflections.GetActions(stateMachine)[stateIndex];

                transitions = new Transition[transitionsIndexes[stateIndex].Length];
                for (int i = 0; i < transitions.Length; i++)
                {
                    transitions[i] = new Transition("=> " + nodesInfo.Names[transitionsIndexes[stateIndex][i]], isDurationsEnd[stateIndex][i], conditions[stateIndex][i]);
                }
            }
        private void DeleteTransition(int stateIndex, int transitionIndex)
        {
            Undo.RegisterCompleteObjectUndo(new UnityEngine.Object[] { stateMachine, this }, "Transition Deleted");

            transitions[stateIndex].RemoveAt(transitionIndex);
            StateMachineReflections.SetTransitions(stateMachine, transitions.Select(a => a.ToArray()).ToArray());

            bool[][]    isDurationsEnd = StateMachineReflections.GetIsDurationsEnd(stateMachine);
            List <bool> isDurationEnd  = new List <bool>(isDurationsEnd[transitionIndex]);

            isDurationEnd.RemoveAt(transitionIndex);
            isDurationsEnd[transitionIndex] = isDurationEnd.ToArray();
            StateMachineReflections.SetIsDurationsEnd(stateMachine, isDurationsEnd);

            Condition[][][]    conditions      = StateMachineReflections.GetConditions(stateMachine);
            List <Condition[]> stateConditions = new List <Condition[]>(conditions[stateIndex]);

            stateConditions.RemoveAt(transitionIndex);
            conditions[stateIndex] = stateConditions.ToArray();
            StateMachineReflections.SetConditions(stateMachine, conditions);
        }
        private void DeleteStateReferencesInTransitions(int stateIndexToDelete)
        {
            Condition[][][] conditions = StateMachineReflections.GetConditions(stateMachine);

            for (int stateIndex = 0; stateIndex < nodesInfo.StatesCount; stateIndex++)
            {
                for (int transitionIndex = 0; transitionIndex < transitions[stateIndex].Count; transitionIndex++)
                {
                    if (transitions[stateIndex][transitionIndex] == stateIndexToDelete)
                    {
                        transitions[stateIndex].RemoveAt(transitionIndex);

                        List <Condition[]> stateConditions = new List <Condition[]>(conditions[transitionIndex]);
                        stateConditions.RemoveAt(transitionIndex);
                        conditions[transitionIndex] = stateConditions.ToArray();

                        transitionIndex--;
                    }
                }
            }

            StateMachineReflections.SetConditions(stateMachine, conditions);
        }
        private void CreateTransition(Vector2 mousePosition)
        {
            int stateIndex = GetStateIndex(mousePosition);

            if (stateIndex != -1 && stateIndex != creatingTransitionFromStateIndex)
            {
                Undo.RegisterCompleteObjectUndo(new UnityEngine.Object[] { stateMachine, this }, "Transition Created");

                transitions[creatingTransitionFromStateIndex].Add(stateIndex);
                StateMachineReflections.SetTransitions(stateMachine, transitions.Select(a => a.ToArray()).ToArray());

                bool[][]    isDurationsEnd = StateMachineReflections.GetIsDurationsEnd(stateMachine);
                List <bool> isDurationEnd  = new List <bool>(isDurationsEnd[creatingTransitionFromStateIndex]);
                isDurationEnd.Add(false);
                isDurationsEnd[creatingTransitionFromStateIndex] = isDurationEnd.ToArray();
                StateMachineReflections.SetIsDurationsEnd(stateMachine, isDurationsEnd);

                Condition[][][]    conditions      = StateMachineReflections.GetConditions(stateMachine);
                List <Condition[]> stateConditions = new List <Condition[]>(conditions[creatingTransitionFromStateIndex]);
                stateConditions.Add(new Condition[0]);
                conditions[creatingTransitionFromStateIndex] = stateConditions.ToArray();
                StateMachineReflections.SetConditions(stateMachine, conditions);
            }
        }
 private void SaveActions()
 {
     Action[][] actions = StateMachineReflections.GetActions(stateMachine);
     actions[stateIndex] = this.actions;
     StateMachineReflections.SetActions(stateMachine, actions);
 }
        private void ProcessContextMenu(Vector2 mousePosition)
        {
            GenericMenu genericMenu = new GenericMenu();

            int stateIndex = GetStateIndex(mousePosition);

            if (stateIndex != -1)
            {
                genericMenu.AddItem(new GUIContent("Create Transition"), false, () => creatingTransitionFromStateIndex = stateIndex);
                genericMenu.AddItem(new GUIContent("Set as Start State"), false, () => StateMachineReflections.SetStartStateIndex(stateMachine, startStateIndex = stateIndex));
                genericMenu.AddItem(new GUIContent("Delete State"), false, () => DeleteState(stateIndex));
            }
            else
            {
                Vector2Int transition = GetTransition(mousePosition);

                if (transition != new Vector2Int(-1, -1))
                {
                    genericMenu.AddItem(new GUIContent("Delete Transition"), false, () => DeleteTransition(transition.x, transition.y));
                }
                else
                {
                    genericMenu.AddItem(new GUIContent("New State"), false, () => CreateState(mousePosition));
                    genericMenu.AddItem(new GUIContent("Reset Panning"), false, ResetPanning);
                }
            }

            genericMenu.ShowAsContext();
        }
 private void SaveTransitions()
 {
     StateMachineReflections.SetTransitions(stateMachine, transitionsIndexes);
     StateMachineReflections.SetIsDurationsEnd(stateMachine, isDurationsEnd);
     StateMachineReflections.SetConditions(stateMachine, conditions);
 }