示例#1
0
        public static string GetStateInitializer(StateMachineDefinition.State state, int index)
        {
            string variable = "state" + state.name;

            string str = "        State " + variable + " = new State();\n";

            str += "        " + variable + ".id = StateID." + state.name + ";\n";

            if (state.hasEnter)
            {
                str += "        " + variable + ".enter = StateEnter_" + state.name + ";\n";
            }

            if (state.hasDuring)
            {
                str += "        " + variable + ".during = State_" + state.name + ";\n";
            }

            if (state.hasExit)
            {
                str += "        " + variable + ".exit = StateExit_" + state.name + ";\n";
            }
            str += "        " + variable + ".transitions = new Transition[" + state.transitions.Count + "];\n";
            str += "        states[" + index + "] = " + variable + ";\n";

            str += "\n";
            return(str);
        }
示例#2
0
        public static string GetTransitionInitializer(StateMachineDefinition.State from, StateMachineDefinition.Transition to, int index)
        {
            string variable = "transition" + from.name + to.to;

            string str = "        Transition " + variable + " = new Transition();\n";

            str += "        " + variable + ".from = state" + from.name + ";\n";
            str += "        " + variable + ".to = state" + to.to + ";\n";
            str += "        " + variable + ".cond = TransitionCond_" + from.name + "_" + to.to + ";\n";

            if (to.hasNotify)
            {
                str += "        " + variable + ".notify = TransitionNotify_" + from.name + "_" + to.to + ";\n";
            }

            str += "        state" + from.name + ".transitions[" + index + "] = " + variable + ";\n";

            str += "\n";
            return(str);
        }
示例#3
0
 public Operation(StateMachineDefinition definition, StateMachineDefinition.State state)
 {
     this.definition = definition;
     this.state      = state;
 }
 public RenameStateOperation(StateMachineDefinition def, StateMachineDefinition.State state) : base(def, state)
 {
     name        = state.name;
     showBaseGUI = false;
 }
 public MakeTransitionOperation(StateMachineDefinition def, StateMachineDefinition.State state) : base(def, state)
 {
     showBaseGUI = true;
 }
示例#6
0
 public MoveStateOperation(StateMachineDefinition def, StateMachineDefinition.State state) : base(def, state)
 {
     showBaseGUI = true;
     start       = state.position;
     move        = Vector2.zero;
 }
        void OnGUI()
        {
            ResizeScrollView();
            Rect viewportRect = new Rect(0, 0, position.width - sidePanelWidth, position.height);

            EditorGUI.DrawRect(viewportRect, bgColor);
            bool repaint = false;

            foreach (var obj in Selection.objects)
            {
                if (obj is StateMachineDefinition)
                {
                    def = (StateMachineDefinition)obj;
                    break;
                }
            }

            if (def != null)
            {
                bool showSide = true;

                Event cur = Event.current;

                if (op != null)
                {
                    if (def != op.definition)
                    {
                        op.Cancel();
                        op = null;
                    }
                    else
                    {
                        op.Update();

                        if (op.done)
                        {
                            op      = null;
                            repaint = true;
                            EditorUtility.SetDirty(def);
                            dirty = true;
                        }
                    }
                }
                else
                {
                    var selected   = def.SelectState(cur.mousePosition + scrollPos);
                    var selectedTr = def.SelectTransition(cur.mousePosition + scrollPos);

                    if (selected == null)
                    {
                        if (selectedTr.t2 != lastSelectedTr)
                        {
                            repaint        = true;
                            lastSelectedTr = selectedTr.t2;
                        }

                        if (lastSelectedState != null)
                        {
                            lastSelectedState = null;
                            repaint           = true;
                        }
                    }
                    else
                    {
                        if (selected != lastSelectedState)
                        {
                            repaint           = true;
                            lastSelectedState = selected;
                        }

                        if (lastSelectedTr != null)
                        {
                            lastSelectedTr = null;
                            repaint        = true;
                        }
                    }

                    if (viewportRect.Contains(cur.mousePosition))
                    {
                        if (cur.type == EventType.MouseDown)
                        {
                            if (cur.button == 0)
                            {
                                if (selected != null)
                                {
                                    editingState         = selected;
                                    editingTransition.t1 = null;
                                    editingTransition.t2 = null;
                                    repaint  = true;
                                    showSide = false;


                                    if (cur.clickCount == 1)
                                    {
                                        op = new MoveStateOperation(def, selected);
                                    }
                                    else if (cur.clickCount == 2)
                                    {
                                        op = new RenameStateOperation(def, selected);
                                    }
                                }
                                else if (selectedTr.t1 != null)
                                {
                                    editingTransition = selectedTr;
                                    editingState      = null;
                                    repaint           = true;
                                    showSide          = false;
                                }
                                else
                                {
                                    editingState         = null;
                                    editingTransition.t1 = null;
                                    editingTransition.t2 = null;
                                    repaint  = true;
                                    showSide = false;
                                }
                            }
                            else if (cur.button == 1)
                            {
                                if (selected == null && lastSelectedTr == null)
                                {
                                    GenericMenu menu = new GenericMenu();

                                    menu.AddItem(new GUIContent("Create State"), false, () => {
                                        var s      = def.AddState();
                                        s.position = cur.mousePosition;
                                        op         = new RenameStateOperation(def, s);
                                        EditorUtility.SetDirty(def);
                                        dirty = true;
                                    });

                                    menu.ShowAsContext();
                                }
                                else if (selected != null)
                                {
                                    GenericMenu menu = new GenericMenu();

                                    menu.AddItem(new GUIContent("Delete State"), false, () => {
                                        def.RemoveState(selected);
                                        EditorUtility.SetDirty(def);
                                        dirty   = true;
                                        repaint = true;
                                    });

                                    menu.AddItem(new GUIContent("Add Transition"), false, () => {
                                        op = new MakeTransitionOperation(def, selected);
                                    });

                                    if (selected.name != def.defaultState)
                                    {
                                        menu.AddItem(new GUIContent("Make Default State"), false, () => {
                                            def.defaultState = selected.name;
                                            dirty            = true;
                                            repaint          = true;
                                        });
                                    }

                                    menu.ShowAsContext();
                                }
                                else if (selectedTr.t1 != null)
                                {
                                    GenericMenu menu = new GenericMenu();

                                    menu.AddItem(new GUIContent("Remove Transition"), false, () => {
                                        selectedTr.t1.RemoveTransition(selectedTr.t2);
                                        EditorUtility.SetDirty(def);
                                        dirty   = true;
                                        repaint = true;
                                    });

                                    menu.ShowAsContext();
                                }
                            }
                        }
                        else if (cur.type == EventType.MouseDrag && cur.button == 2)
                        {
                            scrollPos -= cur.delta;
                            repaint    = true;
                        }
                        else if (cur.type == EventType.KeyDown && cur.keyCode == KeyCode.F)
                        {
                            var state = def.GetState(def.defaultState);
                            if (state == null && def.states.Count > 0)
                            {
                                state = def.states[0];
                            }

                            if (state != null)
                            {
                                scrollPos = state.position - viewportRect.size / 2;
                                repaint   = true;
                            }
                        }
                    }
                }

                if (Event.current.type != EventType.Repaint && (repaint || (op != null && op.repaint)))
                {
                    Repaint();
                }

                Handles.BeginGUI();

                Handles.color = lineColor;
                for (float x = -scrollPos.x % MoveStateOperation.snap; x < viewportRect.width; x += MoveStateOperation.snap)
                {
                    Handles.DrawLine(new Vector3(x, 0), new Vector3(x, viewportRect.height));
                }

                for (float y = -scrollPos.y % MoveStateOperation.snap; y < viewportRect.height; y += MoveStateOperation.snap)
                {
                    Handles.DrawLine(new Vector3(0, y), new Vector3(viewportRect.width, y));
                }

                foreach (var from in def.states)
                {
                    if (from.transitions != null)
                    {
                        foreach (var tr in from.transitions)
                        {
                            if (tr != lastSelectedTr && tr != editingTransition.t2)
                            {
                                Handles.color = Color.black;
                            }
                            else
                            {
                                Handles.color = Color.blue;
                            }

                            if (def.GetState(tr.to) != null)
                            {
                                var     line = def.GetTransitionPoints(from, tr);
                                Vector2 src  = line.t1 - scrollPos;
                                Vector2 dest = line.t2 - scrollPos;

                                Vector2 v     = (dest - src).normalized;
                                Vector2 ortho = new Vector2(v.y, -v.x);

                                Vector2 arrow = ortho - v;
                                Vector2 mid   = (src + dest) / 2;

                                Handles.DrawAAPolyLine(3, src, dest);
                                Handles.DrawAAPolyLine(3, mid + v * 5, mid + arrow * 10);
                            }
                        }
                    }
                }

                Handles.EndGUI();

                foreach (var state in def.states)
                {
                    if (op == null || op.state != state || op.showBaseGUI)
                    {
                        string s = state.name;
                        if (def.defaultState == s)
                        {
                            s += "\n<default state>";
                        }

                        Rect rect = state.rect;
                        rect.position -= scrollPos;

                        if (state != lastSelectedState && state != editingState)
                        {
                            GUI.Button(rect, s);
                        }
                        else
                        {
                            GUI.Button(rect, "");

                            var centeredStyle = new GUIStyle(GUI.skin.label);
                            centeredStyle.alignment        = TextAnchor.MiddleCenter;
                            centeredStyle.normal.textColor = Color.blue;
                            centeredStyle.fontStyle        = FontStyle.Bold;

                            GUI.Label(rect, s, centeredStyle);
                        }
                    }

                    if (op != null && op.state == state)
                    {
                        op.OnGUI();
                    }
                }

                if (showSide)
                {
                    EditorGUI.DrawRect(new Rect(position.width - sidePanelWidth, 0, sidePanelWidth, position.height), panelColor);


                    float padding = 20;
                    GUILayout.BeginArea(new Rect(position.width - sidePanelWidth + padding, padding, sidePanelWidth - padding * 2, position.height - padding * 2));
                    EditorGUILayout.BeginVertical();
                    float w = EditorGUIUtility.labelWidth;
                    EditorGUIUtility.labelWidth = 1;

                    if (GUILayout.Button(dirty ? "Save *" : "Save"))
                    {
                        AssetDatabase.SaveAssets();
                        dirty = false;
                        StateMachineClassGenerator.GenerateAbstractClass(def);
                    }

                    if (GUILayout.Button("New Impl Class..."))
                    {
                        var path = EditorUtility.SaveFilePanelInProject("Save new class", def.name + "Impl.cs", "cs", "Enter a name for the new impl class");
                        if (path.Length > 0)
                        {
                            StateMachineClassGenerator.GenerateImplClass(def, path);
                        }
                    }

                    if (types == null)
                    {
                        types = typeof(StateMachine).Assembly.GetTypes()
                                .Where(p => !p.IsGenericType && typeof(StateMachine).IsAssignableFrom(p))
                                .Select(t => t.FullName).ToArray();
                    }

                    int index = Array.IndexOf(types, def.baseClass);
                    if (index < 0)
                    {
                        index = Array.IndexOf(types, typeof(StateMachine).FullName);
                    }
                    int prev = index;

                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Base Class");
                    index = EditorGUILayout.Popup(index, types);

                    if (prev != index)
                    {
                        dirty = true;
                    }

                    EditorGUILayout.EndHorizontal();
                    def.baseClass = types[index];

                    if (editingState != null)
                    {
                        EditorGUILayout.LabelField("State " + editingState.name);
                        EditorGUILayout.LabelField("State Events", EditorStyles.boldLabel);

                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField("Enter: ");
                        bool enter = EditorGUILayout.Toggle(editingState.hasEnter);
                        EditorGUILayout.EndHorizontal();

                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField("During: ");
                        bool during = EditorGUILayout.Toggle(editingState.hasDuring);
                        EditorGUILayout.EndHorizontal();

                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField("Exit: ");
                        bool exit = EditorGUILayout.Toggle(editingState.hasExit);
                        EditorGUILayout.EndHorizontal();


                        if (enter != editingState.hasEnter || during != editingState.hasDuring || exit != editingState.hasExit)
                        {
                            editingState.hasEnter  = enter;
                            editingState.hasDuring = during;
                            editingState.hasExit   = exit;

                            dirty = true;
                            EditorUtility.SetDirty(def);
                        }
                    }
                    else if (editingTransition.t1 != null)
                    {
                        EditorGUILayout.LabelField("Transition From " + editingTransition.t1.name + " To " + editingTransition.t2.to);
                        EditorGUILayout.LabelField("Transition Events", EditorStyles.boldLabel);

                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField("Notify: ");
                        bool notify = EditorGUILayout.Toggle(editingTransition.t2.hasNotify);
                        EditorGUILayout.EndHorizontal();

                        if (notify != editingTransition.t2.hasNotify)
                        {
                            editingTransition.t2.hasNotify = notify;

                            dirty = true;
                            EditorUtility.SetDirty(def);
                        }
                    }

                    EditorGUILayout.EndVertical();
                    EditorGUIUtility.labelWidth = w;

                    GUILayout.EndArea();
                }
            }
            else if (op != null)
            {
                op.Cancel();
                op = null;
            }
        }
 public StateMachineEditorWindow()
 {
     wantsMouseMove    = true;
     editingState      = null;
     editingTransition = new Pair <StateMachineDefinition.State, StateMachineDefinition.Transition>(null, null);
 }