Esempio n. 1
0
        public static void OnGUI(UnityEngine.Object targetObject)
        {
            EditorGUI.BeginChangeCheck();
            SerializedObject serializedObject = new SerializedObject(targetObject);

            serializedObject.Update();
            FieldInfo[] fields;
            if (!fieldsLookup.TryGetValue(targetObject.GetType(), out fields))
            {
                fields = targetObject.GetPublicFields().OrderBy(field => field.MetadataToken).ToArray();

                fieldsLookup.Add(targetObject.GetType(), fields);
            }
            if (PreferencesEditor.GetBool(Preference.ShowActionTooltips) && !string.IsNullOrEmpty(targetObject.GetTooltip()))
            {
                GUILayout.BeginVertical((GUIStyle)"hostview");

                GUILayout.Label(targetObject.GetTooltip(), FsmEditorStyles.wrappedLabelLeft);
                GUILayout.EndVertical();
            }


            for (int i = 0; i < fields.Length; i++)
            {
                FieldInfo field = fields[i];
                if (field.HasAttribute(typeof(HideInInspector)))
                {
                    continue;
                }
                PropertyDrawer     drawer   = GUIDrawer.GetDrawer(field);
                GUIContent         content  = field.GetInspectorGUIContent();
                SerializedProperty property = serializedObject.FindProperty(field.Name);
                if (PreferencesEditor.GetBool(Preference.ShowVariableTooltips) && !string.IsNullOrEmpty(field.GetTooltip()))
                {
                    GUILayout.BeginVertical("box");
                    GUILayout.Label(field.GetTooltip(), FsmEditorStyles.wrappedLabelLeft);
                    GUILayout.EndVertical();
                }

                if (drawer != null)
                {
                    drawer.fieldInfo = field;
                    drawer.OnGUI(property, content);
                }
                else
                {
                    int indentLevel = EditorGUI.indentLevel;
                    EditorGUI.indentLevel = typeof(IList).IsAssignableFrom(field.FieldType)?indentLevel + 1:indentLevel;
                    EditorGUILayout.PropertyField(property, content, true);
                    EditorGUI.indentLevel = indentLevel;
                }
            }


            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
                ErrorChecker.CheckForErrors();
            }
        }
Esempio n. 2
0
        public virtual void CreateVariable(SerializedProperty property)
        {
            FsmVariable variable = ScriptableObject.CreateInstance(fieldInfo.FieldType) as FsmVariable;

            variable.hideFlags = HideFlags.HideInHierarchy;
            DefaultValueAttribute defaultAttribute = fieldInfo.GetAttribute <DefaultValueAttribute>();

            if (defaultAttribute != null)
            {
                variable.SetValue(defaultAttribute.DefaultValue);
            }

            SharedPersistentAttribute sharedPersistantAttribute = fieldInfo.GetAttribute <SharedPersistentAttribute> ();

            if (sharedPersistantAttribute != null && variable.GetType() == typeof(FsmGameObject))
            {
                variable.Name = "Owner";
            }
            if (EditorUtility.IsPersistent(property.serializedObject.targetObject))
            {
                AssetDatabase.AddObjectToAsset(variable, property.serializedObject.targetObject);
                AssetDatabase.SaveAssets();
            }
            variable.IsShared             = fieldInfo.HasAttribute(typeof(SharedAttribute)) || EditorUtility.IsPersistent(variable) && fieldInfo.HasAttribute(typeof(SharedPersistentAttribute)) || fieldInfo.FieldType == typeof(FsmArray);
            property.objectReferenceValue = variable;
            property.serializedObject.ApplyModifiedProperties();
            ErrorChecker.CheckForErrors();
        }
Esempio n. 3
0
 public static void Update()
 {
     if (checkForErrors)
     {
         ErrorChecker.CheckForErrors(FsmEditor.Active.Root);
         FsmEditor.RepaintAll();
     }
 }
Esempio n. 4
0
 public static void Dirty()
 {
     NodeInspector[] editors = (NodeInspector[])Resources.FindObjectsOfTypeAll(typeof(NodeInspector));
     foreach (NodeInspector inspector in editors)
     {
         inspector.MarkDirty();
     }
     ErrorChecker.CheckForErrors();
 }
 public static void DeleteNode(Node node)
 {
     FsmEditorUtility.DestroyImmediate(node);
     node.Parent.Nodes = ArrayUtility.Remove <Node> (node.Parent.Nodes, node);
     foreach (Transition transition in node.InTransitions)
     {
         FsmEditorUtility.DestroyImmediate(transition);
         transition.FromNode.Transitions = ArrayUtility.Remove(transition.FromNode.Transitions, transition);
     }
     ErrorChecker.CheckForErrors();
 }
Esempio n. 6
0
		public static void SelectStateMachine(StateMachine stateMachine){
			if (FsmEditor.instance == null || FsmEditor.Active== stateMachine) {
				FsmEditor.instance.CenterView ();	
				return;			
			}
			FsmEditor.instance.active = stateMachine;
			FsmEditor.instance.selection.Clear ();
			FsmEditor.instance.UpdateUnitySelection ();
			FsmEditor.instance.CenterView ();	
			ErrorChecker.CheckForErrors ();
		}
Esempio n. 7
0
 public static void Update()
 {
     if (checkForErrors)
     {
         StateMachine[] fsms = Resources.FindObjectsOfTypeAll <StateMachine>();
         for (int i = 0; i < fsms.Length; i++)
         {
             ErrorChecker.CheckForErrors(fsms[i]);
         }
         FsmEditor.RepaintAll();
     }
 }
Esempio n. 8
0
		private void Update(){
			if (FsmEditor.Active != null) {
				ErrorChecker.Update ();	
				if (EditorApplication.isPlaying) {
					debugProgress += Time.deltaTime * 30;
					if (debugProgress > 142) {
						debugProgress = 0;
					}
					FsmEditor.RepaintAll ();
				}
			}
		}
		private void DoNode (Node node)
		{
			GUIStyle style = FsmEditorStyles.GetNodeStyle (node.color, selection.Contains (node), node.GetType () == typeof(StateMachine));
			string state = string.Empty;
			if (FsmEditor.Active.Owner != null && FsmEditor.Active.Owner.ActiveNode && (node == FsmEditor.Active.Owner.ActiveNode || node == FsmEditor.Active.Owner.AnyState || node == FsmEditor.Active.Owner.ActiveNode.Parent) && EditorApplication.isPlaying) {
				if (!FsmEditor.Active.Owner.IsPaused && !FsmEditor.Active.Owner.IsDisabled) {
					state = "[Active]";
				} else if (FsmEditor.Active.Owner.IsPaused) {
					state = "[Paused]";
				} else if (FsmEditor.Active.Owner.IsDisabled) {
					state = "[Disabled]";
				}

			}

			GUI.Box (node.position, node.Name + state, style);

			if (ErrorChecker.HasErrors (node) && Event.current.type != EventType.Layout) {
				Rect rect = node.position;
				if (node is StateMachine) {
					rect.x += 10;
					rect.y += 6;
				}
				GUI.Label (rect, "", "CN EntryError");
			}

			if (node is State && (node as State).IsSequence) {
				Rect rect = node.position;
				rect.x += 25;
				rect.y += 3;
				GUI.Label (rect, EditorGUIUtility.FindTexture ("d_PlayButtonProfile"));			
			} 

			if (PreferencesEditor.GetBool (Preference.ShowStateDescription)) {
				GUILayout.BeginArea (new Rect (node.position.x, node.position.y + node.position.height, node.position.width, 500));
				GUILayout.Label (node.comment, FsmEditorStyles.wrappedLabel);
				GUILayout.EndArea ();
			}

			if (DisplayProgress (node)) {
				Rect rect = new Rect (node.position.x + 5, node.position.y + 20, debugProgress, 5);

				if (node == FsmEditor.Active.Owner.ActiveNode.Parent) {
					rect.y += 5;
					rect.x += 15;
					rect.width *= 0.8f;
				}
				GUI.Box (rect, "", "MeLivePlayBar");
			}	

		}
Esempio n. 10
0
        protected override void OnGUI()
        {
            mainToolbar.OnGUI();
            EventType eventType = FsmEditorUtility.ReserveEvent(variableEditorRect, fsmSelectionRect, preferencesRect);

            ZoomableArea.Begin(new Rect(0f, 0f, scaledCanvasSize.width, scaledCanvasSize.height + 21), scale, IsDocked);
            Begin();

            shortcutEditor.HandleKeyEvents();
            if (FsmEditor.Active != null)
            {
                DoNodes();
            }
            else
            {
                ZoomableArea.End();
            }
            AcceptDragAndDrop();
            End();

            FsmEditorUtility.ReleaseEvent(eventType);
            PreferencesEditor.DoGUI(preferencesRect);
            shortcutEditor.DoGUI(shortcutRect);
            DoFsmSelection(fsmSelectionRect);
            variableEditor.DoGUI(variableEditorRect);
            if (centerView)
            {
                CenterView();
                centerView = false;
            }
            if (FsmEditor.Active != null)
            {
                GUI.Label(new Rect(5, 20, 300, 200), FsmEditor.Active.comment, FsmEditorStyles.instructionLabel);
            }
            else
            {
                GUI.Label(new Rect(5, 20, 300, 200), "Right click to create a state machine.", FsmEditorStyles.instructionLabel);
            }
            Event ev = Event.current;

            if (SelectedNodes.Count == 1 && ev.rawType == EventType.KeyDown && ev.keyCode == KeyCode.Delete && FsmEditor.SelectedTransition != null && EditorUtility.DisplayDialog("Delete selected transition?", FsmEditor.SelectedTransition.FromNode.Name + " -> " + FsmEditor.SelectedTransition.ToNode.Name + "\r\n\r\nYou cannot undo this action.", "Delete", "Cancel"))
            {
                Node node = SelectedTransition.FromNode;
                node.Transitions = ArrayUtility.Remove(node.Transitions, FsmEditor.SelectedTransition);
                FsmEditorUtility.DestroyImmediate(FsmEditor.SelectedTransition);
                ErrorChecker.CheckForErrors();
                EditorUtility.SetDirty(node);
            }
        }
Esempio n. 11
0
        static void HierarchyWindowItemCallback(int pID, Rect pRect)
        {
            GameObject go = EditorUtility.InstanceIDToObject(pID) as GameObject;

            if (go != null && go.GetComponent <ICodeBehaviour>() != null)
            {
                Rect rect = new Rect(pRect.x + pRect.width - 25, pRect.y - 3, 25, 25);
                GUI.DrawTexture(rect, FsmEditorStyles.iCodeLogo);
                ICodeBehaviour[] behaviours = go.GetComponents <ICodeBehaviour>();
                for (int i = 0; i < behaviours.Length; i++)
                {
                    ICodeBehaviour behaviour = behaviours[i];
                    ErrorChecker.CheckForErrors(behaviour.stateMachine);
                    if (ErrorChecker.HasErrors(behaviour.stateMachine) || behaviour.stateMachine == null)
                    {
                        Rect rect1 = new Rect(pRect.x + pRect.width - 25 - rect.width, pRect.y - 3, 25, 25);
                        GUI.DrawTexture(rect1, EditorGUIUtility.FindTexture("d_console.erroricon"));
                    }
                }
            }

            Event ev = Event.current;

            if (ev.type == EventType.DragPerform)
            {
                DragAndDrop.AcceptDrag();
                var selectedObjects = new List <GameObject>();
                foreach (var objectRef in DragAndDrop.objectReferences)
                {
                    if (objectRef is StateMachine)
                    {
                        if (pRect.Contains(ev.mousePosition))
                        {
                            var gameObject = (GameObject)EditorUtility.InstanceIDToObject(pID);
                            var componentX = gameObject.AddComponent <ICodeBehaviour>();
                            componentX.stateMachine = objectRef as StateMachine;
                            selectedObjects.Add(gameObject);
                        }
                    }
                }

                if (selectedObjects.Count == 0)
                {
                    return;
                }
                Selection.objects = selectedObjects.ToArray();
                ev.Use();
            }
        }
Esempio n. 12
0
 private void ComponentHint(SerializedProperty component, SerializedProperty property)
 {
     if (GUILayout.Button(GUIContent.none, "MiniPullDown", GUILayout.Width(15f)))
     {
         GUI.FocusControl(null);
         FsmGUIUtility.SubclassMenu <Component> (delegate(Type type) {
             component.serializedObject.Update();
             component.stringValue = type.Name;
             property.stringValue  = string.Empty;
             component.serializedObject.ApplyModifiedProperties();
             ErrorChecker.CheckForErrors();
         });
         EditorGUIUtility.ExitGUI();
     }
 }
Esempio n. 13
0
        public override void OnGUI(SerializedProperty property, GUIContent label)
        {
            if (property.objectReferenceValue == null)
            {
                CreateVariable(property);
            }
            if (property.objectReferenceValue == null)
            {
                return;
            }
            SerializedObject serializedObject = new SerializedObject(property.objectReferenceValue);

            serializedObject.Update();
            GUILayout.BeginHorizontal();

            SerializedProperty nameProperty   = serializedObject.FindProperty("name");
            SerializedProperty valueProperty  = serializedObject.FindProperty("value");
            SerializedProperty sharedProperty = serializedObject.FindProperty("isShared");

            if (EditorUtility.IsPersistent(property.objectReferenceValue) && fieldInfo.HasAttribute(typeof(SharedPersistentAttribute)) || fieldInfo.FieldType == typeof(FsmArray))
            {
                sharedProperty.boolValue = true;
            }

            Color color = GUI.backgroundColor;

            if (ErrorChecker.HasErrors(property.objectReferenceValue))
            {
                GUI.backgroundColor = Color.red;
            }

            if (sharedProperty.boolValue)
            {
                DrawSharedVariable(label, nameProperty);
            }
            else
            {
                OnPropertyField(valueProperty, label);
            }
            GUI.backgroundColor = color;

            if (DoSharedToggle(property))
            {
                DrawSharedToggle(sharedProperty);
            }
            GUILayout.EndHorizontal();
            serializedObject.ApplyModifiedProperties();
        }
Esempio n. 14
0
 public override void OnPropertyField(SerializedProperty property, GUIContent label)
 {
     base.OnPropertyField(property, label);
     if (GUILayout.Button(GUIContent.none, "MiniPullDown", GUILayout.Width(18f)))
     {
         GUI.FocusControl(null);
         Type mType = fieldInfo.GetAttribute <ComponentAttribute>().Type ?? typeof(Component);
         FsmGUIUtility.SubclassMenu(mType, delegate(Type type){
             property.serializedObject.Update();
             property.stringValue = type.Name;
             property.serializedObject.ApplyModifiedProperties();
             ErrorChecker.CheckForErrors();
         });
         EditorGUIUtility.ExitGUI();
     }
 }
Esempio n. 15
0
		protected override void OnEnable ()
		{
			base.OnEnable ();
			FsmEditor.instance = this;
			variableEditor = new VariableEditor ();
			if (mainToolbar == null) {
				mainToolbar= new MainToolbar();			
			}
			if (shortcutEditor == null) {
				shortcutEditor=new ShortcutEditor();

			}
			centerView = true;
			EditorApplication.playmodeStateChanged += OnPlayModeStateChanged;
			ErrorChecker.CheckForErrors ();
		}
        public void OnInspectorGUI()
        {
            int index = node.Transitions.ToList().FindIndex(x => x == FsmEditor.SelectedTransition);

            if (index != transitionList.index && index != -1)
            {
                transitionList.index = index;
            }
            transitionList.DoLayoutList();
            GUILayout.Space(10f);

            conditionList.DoLayoutList();
            Event ev = Event.current;

            if (ev.rawType == EventType.KeyDown && ev.keyCode == KeyCode.Delete && FsmEditor.SelectedTransition != null && EditorUtility.DisplayDialog("Delete selected transition?", FsmEditor.SelectedTransition.FromNode.Name + " -> " + FsmEditor.SelectedTransition.ToNode.Name + "\r\n\r\nYou cannot undo this action.", "Delete", "Cancel"))
            {
                node.Transitions = ArrayUtility.Remove(node.Transitions, FsmEditor.SelectedTransition);
                FsmEditorUtility.DestroyImmediate(FsmEditor.SelectedTransition);
                ErrorChecker.CheckForErrors();
                EditorUtility.SetDirty(node);
            }
        }
Esempio n. 17
0
        private void OnGUI()
        {
            List <FsmError> errors = ErrorChecker.GetErrors();

            GUILayout.BeginHorizontal("box");
            GUILayout.Label("State Machine");
            GUILayout.Label("State");
            GUILayout.Label("Node");
            GUILayout.Label("Type");
            GUILayout.Label("Field");
            GUILayout.EndHorizontal();
            foreach (FsmError error in errors)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label(error.StateMachine.Name, GUILayout.Width(Screen.width / 5 + 40));            //+" "+error.State.Name+" "+error.ExecutableNode.GetType().Name+" "+ error.Type+" "+error.FieldInfo.Name);
                GUILayout.Label(error.State.Name, GUILayout.Width(Screen.width / 5 - 15));
                GUILayout.Label(error.ExecutableNode.GetType().Name, GUILayout.Width(Screen.width / 5 - 15));
                GUILayout.Label(error.Type.ToString(), GUILayout.Width(Screen.width / 5 - 17));
                GUILayout.Label(error.FieldInfo.Name, GUILayout.Width(Screen.width / 5));
                GUILayout.EndHorizontal();
            }
        }
        public override void CreateVariable(SerializedProperty property)
        {
            FsmVariable variable = property.objectReferenceValue as FsmVariable;

            if (parameterTypeNames == null)
            {
                parameterTypeNames = TypeUtility.GetSubTypeNames(typeof(FsmVariable));
                parameterTypeNames = ArrayUtility.Insert <string> (parameterTypeNames, "None", 0);
            }
            int index = parameterTypeNames.ToList().FindIndex(x => x == (variable != null?variable.GetType().ToString().Split('.').Last():""));

            index = Mathf.Clamp(index, 0, int.MaxValue);

            index = EditorGUILayout.Popup("Parameter Type", index, parameterTypeNames);

            string typeName         = parameterTypeNames [index];
            string variableTypeName = (variable == null ? "None" : variable.GetType().Name);

            if (typeName != variableTypeName)
            {
                FsmEditorUtility.DestroyImmediate(property.objectReferenceValue as FsmVariable);
                if (typeName != "None")
                {
                    variable           = ScriptableObject.CreateInstance(TypeUtility.GetTypeByName(typeName)[0]) as FsmVariable;
                    variable.hideFlags = HideFlags.HideInHierarchy;
                    if (EditorUtility.IsPersistent(property.serializedObject.targetObject))
                    {
                        AssetDatabase.AddObjectToAsset(variable, property.serializedObject.targetObject);
                        AssetDatabase.SaveAssets();
                    }

                    variable.IsShared = fieldInfo.HasAttribute(typeof(SharedAttribute)) || EditorUtility.IsPersistent(variable) && fieldInfo.HasAttribute(typeof(SharedPersistentAttribute)) || variable is FsmArray || !variable.GetType().GetProperty("Value").PropertyType.IsSerializable;
                    property.serializedObject.Update();
                    property.objectReferenceValue = variable;
                    property.serializedObject.ApplyModifiedProperties();
                }
                ErrorChecker.CheckForErrors();
            }
        }
Esempio n. 19
0
        private void PropertyHint(SerializedProperty property, Type componentType)
        {
            if (GUILayout.Button(GUIContent.none, "MiniPullDown", GUILayout.Width(15)))
            {
                GUI.FocusControl(null);
                GenericMenu toolsMenu = new GenericMenu();
                string[]    names     = componentType.GetPropertyAndFieldNames(true);

                foreach (string s in names)
                {
                    string name        = s;
                    string displayName = s.Split('.').Last();
                    toolsMenu.AddItem(new GUIContent(displayName), false, delegate() {
                        property.serializedObject.Update();
                        property.stringValue = name;
                        property.serializedObject.ApplyModifiedProperties();
                        ErrorChecker.CheckForErrors();
                    });
                }
                toolsMenu.ShowAsContext();
                EditorGUIUtility.ExitGUI();
            }
        }
        private void ResetActionList()
        {
            SerializedObject   obj      = new SerializedObject(state);
            SerializedProperty elements = obj.FindProperty("actions");

            actionList = new ReorderableObjectList(obj, elements);

            actionList.drawHeaderCallback = delegate(Rect rect) {
                EditorGUI.LabelField(rect, "Actions");
            };

            actionList.onAddCallback = delegate(ReorderableObjectList list) {
                FsmGUIUtility.SubclassMenu <StateAction> (delegate(Type type){
                    StateAction action = (StateAction)ScriptableObject.CreateInstance(type);
                    action.name        = type.GetCategory() + "." + type.Name;
                    action.hideFlags   = HideFlags.HideInHierarchy;
                    state.Actions      = ArrayUtility.Add <StateAction> (state.Actions, action);

                    if (EditorUtility.IsPersistent(state))
                    {
                        AssetDatabase.AddObjectToAsset(action, state);
                        AssetDatabase.SaveAssets();
                    }
                    list.index = list.count;
                    EditorUtility.SetDirty(state);
                });
            };

            actionList.drawElementCallback = delegate(int index, bool selected) {
                StateAction action  = state.Actions [index];
                bool        enabled = action.IsEnabled;
                if (selected)
                {
                    GUIStyle selectBackground = new GUIStyle("MeTransitionSelectHead")
                    {
                        stretchHeight = false,
                    };
                    selectBackground.overflow = new RectOffset(-1, -2, -2, 2);
                    GUILayout.BeginVertical(selectBackground);
                }
                action.IsOpen = GUIDrawer.ObjectTitlebar(action, action.IsOpen, ref enabled, FsmGUIUtility.ExecutableContextMenu(action, state));
                if (selected)
                {
                    GUILayout.EndVertical();
                }
                action.IsEnabled = enabled;
                if (action.IsOpen)
                {
                    GUIDrawer.OnGUI(action);
                }
            };

            actionList.onRemoveCallback = delegate(ReorderableObjectList list) {
                StateAction action = state.Actions[list.index];
                state.Actions = ArrayUtility.Remove <StateAction> (state.Actions, action);
                FsmEditorUtility.DestroyImmediate(action);
                list.index = list.index - 1;
                ErrorChecker.CheckForErrors();
                EditorUtility.SetDirty(state);
            };

            actionList.onContextClick = delegate(int index) {
                FsmGUIUtility.ExecutableContextMenu(state.Actions [index], state).ShowAsContext();
            };

            actionList.onHeaderContextClick = delegate() {
                GenericMenu menu = new GenericMenu();

                if (state.Actions.Length > 0)
                {
                    menu.AddItem(new GUIContent("Copy"), false, delegate {
                        copy      = new List <StateAction>(state.Actions);
                        copyState = state;
                    });
                }
                else
                {
                    menu.AddDisabledItem(new GUIContent("Copy"));
                }

                if (copy == null)
                {
                    copy = new List <StateAction>();
                }

                copy.RemoveAll(x => x == null);
                if (copy.Count > 0)
                {
                    menu.AddItem(new GUIContent("Paste After"), false, delegate() {
                        for (int i = 0; i < copy.Count; i++)
                        {
                            ExecutableNode dest = FsmUtility.Copy(copy[i]);
                            state.Actions       = ArrayUtility.Add <StateAction>(state.Actions, (StateAction)dest);
                            FsmEditorUtility.ParentChilds(state);
                            EditorUtility.SetDirty(state);
                            //	NodeInspector.Dirty();
                            ErrorChecker.CheckForErrors();
                        }
                    });
                    menu.AddItem(new GUIContent("Paste Before"), false, delegate() {
                        for (int i = 0; i < copy.Count; i++)
                        {
                            ExecutableNode dest = FsmUtility.Copy(copy[i]);
                            state.Actions       = ArrayUtility.Insert <StateAction>(state.Actions, (StateAction)dest, 0);
                            FsmEditorUtility.ParentChilds(state);
                            EditorUtility.SetDirty(state);
                            //	NodeInspector.Dirty();
                            ErrorChecker.CheckForErrors();
                        }
                    });
                    if (copyState != state)
                    {
                        menu.AddItem(new GUIContent("Replace"), false, delegate() {
                            for (int i = 0; i < state.Actions.Length; i++)
                            {
                                FsmEditorUtility.DestroyImmediate(state.Actions[i]);
                            }
                            state.Actions = new StateAction[0];
                            ResetActionList();

                            for (int i = 0; i < copy.Count; i++)
                            {
                                ExecutableNode dest = FsmUtility.Copy(copy[i]);
                                state.Actions       = ArrayUtility.Add <StateAction>(state.Actions, (StateAction)dest);
                                FsmEditorUtility.ParentChilds(state);
                                EditorUtility.SetDirty(state);
                                //	NodeInspector.Dirty();
                                ErrorChecker.CheckForErrors();
                            }
                        });
                    }
                    else
                    {
                        menu.AddDisabledItem(new GUIContent("Replace"));
                    }
                }
                else
                {
                    menu.AddDisabledItem(new GUIContent("Paste After"));
                    menu.AddDisabledItem(new GUIContent("Paste Before"));
                    menu.AddDisabledItem(new GUIContent("Replace"));
                }
                menu.ShowAsContext();
            };

            this.host.Repaint();
            if (FsmEditor.instance != null)
            {
                FsmEditor.instance.Repaint();
            }
        }
Esempio n. 21
0
 private void OnUndoRedo()
 {
     ErrorChecker.CheckForErrors();
 }
        public void ResetTransitionList()
        {
            SerializedObject   obj      = new SerializedObject(node);
            SerializedProperty elements = obj.FindProperty("transitions");

            transitionList = new ReorderableObjectList(obj, elements);
            transitionList.drawHeaderCallback = delegate(Rect rect) {
                EditorGUI.LabelField(rect, "Transitions");
                EditorGUI.LabelField(new Rect(rect.width - 25, rect.y, 50, 20), "Mute");
            };

            transitionList.onSelectCallback = delegate(int index) {
                if (node.Transitions.Length > 0)
                {
                    FsmEditor.SelectTransition(this.node.Transitions[index]);
                    this.ResetConditionList();
                }
            };

            transitionList.onRemoveCallback = delegate(ReorderableObjectList list) {
                Transition transition = node.Transitions[list.index];
                node.Transitions = ArrayUtility.Remove(node.Transitions, transition);
                FsmEditorUtility.DestroyImmediate(transition);
                list.index = Mathf.Clamp(list.index - 1, 0, list.count - 1);
                ErrorChecker.CheckForErrors();
                EditorUtility.SetDirty(node);
            };
            transitionList.drawElementCallback = delegate(int index, bool selected) {
                Transition transition = node.Transitions [index];
                if (selected)
                {
                    GUIStyle selectBackground = new GUIStyle("MeTransitionSelectHead")
                    {
                        stretchHeight = false,
                    };
                    selectBackground.overflow = new RectOffset(-1, -2, -2, 2);
                    GUILayout.BeginVertical(selectBackground);
                }
                GUILayout.BeginHorizontal();
                for (int i = 0; i < transition.Conditions.Length; i++)
                {
                    Condition condition = transition.Conditions[i];
                    if (ErrorChecker.HasErrors(condition))
                    {
                        GUILayout.Label(FsmEditorStyles.errorIcon);
                        break;
                    }
                }
                GUILayout.Label(transition.FromNode.Name + " -> " + transition.ToNode.Name, selected?EditorStyles.whiteLabel:EditorStyles.label);
                GUILayout.FlexibleSpace();
                transition.Mute = GUILayout.Toggle(transition.Mute, GUIContent.none, GUILayout.Width(15));
                GUILayout.Space(22f);
                GUILayout.EndHorizontal();
                if (selected)
                {
                    GUILayout.EndVertical();
                }
            };

            transitionList.onReorderCallback = delegate(ReorderableObjectList list) {
                FsmEditor.SelectTransition(this.node.Transitions[list.index]);
                this.ResetConditionList();
            };
            transitionList.onContextClick = delegate(int index) {
                GenericMenu menu = new GenericMenu();
                menu.AddItem(new GUIContent("Remove"), false, delegate() {
                    Transition transition = node.Transitions[index];
                    node.Transitions      = ArrayUtility.Remove(node.Transitions, transition);
                    FsmEditorUtility.DestroyImmediate(transition);

                    transitionList.index = Mathf.Clamp((index == transitionList.index?index - 1:(index < transitionList.index?transitionList.index - 1:transitionList.index)), 0, node.Transitions.Length - 1);
                    ErrorChecker.CheckForErrors();
                    EditorUtility.SetDirty(node);
                });
                menu.ShowAsContext();
            };

            this.ResetConditionList();
            this.host.Repaint();
            if (FsmEditor.instance != null)
            {
                FsmEditor.instance.Repaint();
            }
        }
        public static void Paste(Vector2 position, StateMachine stateMachine)
        {
            List <Node> copiedNodes = new List <Node> ();
            Vector2     center      = GetCenter(nodes);

            for (int i = 0; i < nodes.Count; i++)
            {
                Node origNode = nodes[i];
                List <FsmVariable> sharedVariables = new List <FsmVariable>();
                GetSharedVariables(origNode, ref sharedVariables);
                if (sharedVariables.Count > 0)
                {
                    string variableNames = string.Empty;
                    sharedVariables.Select(x => x.Name).ToList().ForEach(y => variableNames = (variableNames + (string.IsNullOrEmpty(variableNames)?"":",") + y));
                    if (EditorUtility.DisplayDialog("Paste Variables", "Copied states have reference to shared variables, do you want to paste those variables? (" + variableNames + ")", "Yes", "No"))
                    {
                        for (int j = 0; j < sharedVariables.Count; j++)
                        {
                            FsmVariable variable = sharedVariables[j];
                            stateMachine.SetVariable(variable.Name, variable.GetValue());
                        }
                    }
                }

                Node mNode = (Node)FsmUtility.Copy(origNode);
                mNode.Parent    = stateMachine;
                mNode.hideFlags = HideFlags.HideInHierarchy;
                if (mNode.IsStartNode && stateMachine.GetStartNode() != null)
                {
                    mNode.IsStartNode = false;
                }
                //mNode.Name = FsmEditorUtility.GenerateUniqueNodeName(mNode.GetType(),stateMachine);
                stateMachine.Nodes = ArrayUtility.Add <Node> (stateMachine.Nodes, mNode);

                mNode.position = new Rect(-(center.x - origNode.position.x) + position.x, -(center.y - origNode.position.y) + position.y, FsmEditorStyles.StateWidth, FsmEditorStyles.StateHeight);

                if (mNode.GetType() == typeof(StateMachine))
                {
                    mNode.position.width  = FsmEditorStyles.StateMachineWidth;
                    mNode.position.height = FsmEditorStyles.StateMachineHeight;
                }
                FsmEditorUtility.UpdateNodeColor(mNode);
                copiedNodes.Add(mNode);
            }

            for (int i = 0; i < copiedNodes.Count; i++)
            {
                Node mNode = copiedNodes [i];
                if (mNode is AnyState)
                {
                    bool     mOverride = EditorUtility.DisplayDialog("Override AnyState", "AnyState can only exist once per state machine. Do you want to override it?", "Yes", "No");
                    AnyState anyState  = stateMachine.Nodes.ToList().Find(x => x.GetType() == typeof(AnyState) && (mOverride && x != mNode || !mOverride && x == mNode)) as AnyState;
                    stateMachine.Nodes = ArrayUtility.Remove(stateMachine.Nodes, anyState);
                    FsmEditorUtility.DestroyImmediate(anyState);
                    FsmEditor.SelectedNodes.Clear();
                }
            }

            for (int i = 0; i < copiedNodes.Count; i++)
            {
                Node mNode = copiedNodes[i];

                foreach (Transition transition in mNode.Transitions)
                {
                    Node toNode = copiedNodes.Find(x => x.Name == transition.ToNode.Name) ?? stateMachine.Nodes.ToList().Find(x => x.Name == transition.ToNode.Name);
                    if (toNode != null)
                    {
                        transition.ToNode = toNode;
                    }
                    else
                    {
                        FsmEditorUtility.DestroyImmediate(transition);
                        mNode.Transitions = ArrayUtility.Remove(mNode.Transitions, transition);
                    }
                }
            }

            for (int i = 0; i < copiedNodes.Count; i++)
            {
                Node mNode = stateMachine.Nodes.ToList().Find(x => x.Name == copiedNodes[i].Name && x != copiedNodes[i]);
                if (mNode != null)
                {
                    copiedNodes[i].Name = FsmEditorUtility.GenerateUniqueNodeName(copiedNodes[i].GetType(), stateMachine);
                }
            }

            FsmEditorUtility.ParentChilds(stateMachine);
            nodes.Clear();
            EditorUtility.SetDirty(stateMachine);
            ErrorChecker.CheckForErrors();
        }
Esempio n. 24
0
        public override void OnGUI(SerializedProperty property, GUIContent label)
        {
            if (property.objectReferenceValue == null)
            {
                CreateVariable(property);
            }
            if (property.objectReferenceValue == null)
            {
                return;
            }
            SerializedObject serializedObject = new SerializedObject(property.objectReferenceValue);

            serializedObject.Update();
            GUILayout.BeginHorizontal();

            SerializedProperty nameProperty   = serializedObject.FindProperty("name");
            SerializedProperty valueProperty  = serializedObject.FindProperty("value");
            SerializedProperty sharedProperty = serializedObject.FindProperty("isShared");

            if (EditorUtility.IsPersistent(property.objectReferenceValue) && fieldInfo.HasAttribute(typeof(SharedPersistentAttribute)) || fieldInfo.FieldType == typeof(FsmArray))
            {
                sharedProperty.boolValue = true;
            }

            Color    color = GUI.backgroundColor;
            FsmError error = ErrorChecker.GetError(property.objectReferenceValue);

            if (error != null)
            {
                GUI.backgroundColor = Color.red;
            }

            int variableIndex = -1;

            if (sharedProperty.boolValue)
            {
                variableIndex = DrawSharedVariable(label, nameProperty);
            }
            else
            {
                OnPropertyField(valueProperty, label);
            }
            GUI.backgroundColor = color;

            if (DoSharedToggle(property))
            {
                DrawSharedToggle(sharedProperty);
            }
            GUILayout.EndHorizontal();
            if (variableIndex == 0)
            {
                nameProperty.stringValue = "None";
                Color color1 = GUI.backgroundColor;
                GUI.backgroundColor = (EditorGUIUtility.isProSkin?new Color(0f, 0f, 0f, 0.6f):new Color(0f, 0f, 0f, 0.2f));
                GUIStyle style = new GUIStyle("box");
                style.normal.textColor = new Color(0f, 0f, 0f, 0.7f);
                if (GUILayout.Button("Click to create a new variable [" + fieldInfo.FieldType.Name + "]", style, GUILayout.ExpandWidth(true)))
                {
                    CreateVariable(property.objectReferenceValue.GetType(), fieldInfo.Name);
                    nameProperty.stringValue = fieldInfo.Name;
                }
                GUI.backgroundColor = color1;
            }
            serializedObject.ApplyModifiedProperties();
        }
        public static GenericMenu ExecutableContextMenu(ExecutableNode executable, Node node)
        {
            GenericMenu menu = new GenericMenu();

            if (executable == null)
            {
                return(menu);
            }
            menu.AddItem(new GUIContent("Enable"), executable.IsEnabled, delegate() {
                executable.IsEnabled = !executable.IsEnabled;
            });

            menu.AddSeparator("");

            menu.AddItem(new GUIContent("Find Script"), false, delegate() {
                MonoScript[] monoScriptArray = (MonoScript[])Resources.FindObjectsOfTypeAll(typeof(MonoScript));
                Selection.activeObject       = monoScriptArray.ToList().Find(x => x.GetClass() == executable.GetType());
            });

            menu.AddItem(new GUIContent("Edit Script"), false, delegate() {
                MonoScript[] monoScriptArray = (MonoScript[])Resources.FindObjectsOfTypeAll(typeof(MonoScript));
                Selection.activeObject       = monoScriptArray.ToList().Find(x => x.GetClass() == executable.GetType());
                AssetDatabase.OpenAsset(Selection.activeObject);
            });

            menu.AddSeparator("");

            bool moveDown     = false;
            int  currentIndex = -1;

            if (executable.GetType().IsSubclassOf(typeof(StateAction)))
            {
                State state = node as State;
                currentIndex = Array.IndexOf(state.Actions, executable);
                moveDown     = currentIndex + 1 < state.Actions.Length;
            }
            else
            {
                currentIndex = Array.IndexOf(FsmEditor.SelectedTransition.Conditions, executable);
                moveDown     = currentIndex + 1 < FsmEditor.SelectedTransition.Conditions.Length;
            }

            if (currentIndex - 1 >= 0)
            {
                menu.AddItem(new GUIContent("Move Up"), false, delegate() {
                    if (executable.GetType().IsSubclassOf(typeof(StateAction)))
                    {
                        State state   = node as State;
                        state.Actions = ArrayUtility.MoveItem(state.Actions, currentIndex, currentIndex - 1);
                    }
                    else
                    {
                        FsmEditor.SelectedTransition.Conditions = ArrayUtility.MoveItem(FsmEditor.SelectedTransition.Conditions, currentIndex, currentIndex - 1);
                    }
                    NodeInspector.Dirty();
                });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Move Up"));
            }

            if (moveDown)
            {
                menu.AddItem(new GUIContent("Move Down"), false, delegate() {
                    if (executable.GetType().IsSubclassOf(typeof(StateAction)))
                    {
                        State state   = node as State;
                        state.Actions = ArrayUtility.MoveItem(state.Actions, currentIndex, currentIndex + 1);
                    }
                    else
                    {
                        FsmEditor.SelectedTransition.Conditions = ArrayUtility.MoveItem(FsmEditor.SelectedTransition.Conditions, currentIndex, currentIndex + 1);
                    }
                    NodeInspector.Dirty();
                });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Move Down"));
            }

            menu.AddSeparator("");

            menu.AddItem(new GUIContent("Copy"), false, delegate() {
                executableCopy = executable;
            });

            if (executableCopy != null)
            {
                menu.AddItem(new GUIContent("Paste After"), false, delegate() {
                    ExecutableNode dest = FsmUtility.Copy(executableCopy);
                    if (dest.GetType().IsSubclassOf(typeof(StateAction)))
                    {
                        State state   = node as State;
                        state.Actions = ArrayUtility.Insert <StateAction>(state.Actions, (StateAction)dest, currentIndex + 1);
                    }
                    else
                    {
                        FsmEditor.SelectedTransition.Conditions = ArrayUtility.Insert <Condition>(FsmEditor.SelectedTransition.Conditions, (Condition)dest, currentIndex + 1);
                    }
                    FsmEditorUtility.ParentChilds(node);
                    NodeInspector.Dirty();
                });

                menu.AddItem(new GUIContent("Paste Before"), false, delegate() {
                    ExecutableNode dest = FsmUtility.Copy(executableCopy);
                    if (dest.GetType().IsSubclassOf(typeof(StateAction)))
                    {
                        State state   = node as State;
                        state.Actions = ArrayUtility.Insert <StateAction>(state.Actions, (StateAction)dest, currentIndex);
                    }
                    else
                    {
                        FsmEditor.SelectedTransition.Conditions = ArrayUtility.Insert <Condition>(FsmEditor.SelectedTransition.Conditions, (Condition)dest, currentIndex);
                    }
                    FsmEditorUtility.ParentChilds(node);
                    NodeInspector.Dirty();
                });


                menu.AddItem(new GUIContent("Replace"), false, delegate() {
                    ExecutableNode dest = FsmUtility.Copy(executableCopy);
                    if (dest.GetType().IsSubclassOf(typeof(StateAction)))
                    {
                        State state = node as State;
                        FsmEditorUtility.DestroyImmediate(state.Actions[currentIndex]);
                        state.Actions = ArrayUtility.RemoveAt <StateAction>(state.Actions, currentIndex);
                        state.Actions = ArrayUtility.Insert <StateAction>(state.Actions, (StateAction)dest, currentIndex);
                    }
                    else
                    {
                        FsmEditorUtility.DestroyImmediate(FsmEditor.SelectedTransition.Conditions[currentIndex]);
                        FsmEditor.SelectedTransition.Conditions = ArrayUtility.RemoveAt <Condition>(FsmEditor.SelectedTransition.Conditions, currentIndex);
                        FsmEditor.SelectedTransition.Conditions = ArrayUtility.Insert <Condition>(FsmEditor.SelectedTransition.Conditions, (Condition)dest, currentIndex);
                    }

                    FsmEditorUtility.ParentChilds(node);
                    NodeInspector.Dirty();
                });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Paste After"));
                menu.AddDisabledItem(new GUIContent("Paste Before"));
                menu.AddDisabledItem(new GUIContent("Replace"));
            }
            menu.AddSeparator("");

            menu.AddItem(new GUIContent("Remove"), false, delegate() {
                if (executable.GetType().IsSubclassOf(typeof(StateAction)))
                {
                    State state   = node as State;
                    state.Actions = ArrayUtility.Remove <StateAction> (state.Actions, (StateAction)executable);
                }
                else
                {
                    FsmEditor.SelectedTransition.Conditions = ArrayUtility.Remove <Condition>(FsmEditor.SelectedTransition.Conditions, (Condition)executable);
                }

                FsmEditorUtility.DestroyImmediate(executable);
                //NodeInspector.Dirty();
                ErrorChecker.CheckForErrors();
            });

            return(menu);
        }
Esempio n. 26
0
 private void OnEnable()
 {
     ErrorChecker.CheckForErrors();
 }
Esempio n. 27
0
        public static bool NodeTitlebar(ExecutableNode executable, Node node)
        {
            int        controlID = EditorGUIUtility.GetControlID(FocusType.Passive);
            GUIContent content   = new GUIContent(executable.name.Replace("/", "."), executable.GetType().GetTooltip());

            Rect position = GUILayoutUtility.GetRect(GUIContent.none, FsmEditorStyles.inspectorTitle);
            Rect rect     = new Rect(position.x + (float)FsmEditorStyles.inspectorTitle.padding.left, position.y + (float)FsmEditorStyles.inspectorTitle.padding.top, 16f, 16f);
            Rect rect1    = new Rect(position.xMax - (float)FsmEditorStyles.inspectorTitle.padding.right - 2f - 16f, rect.y, 16f, 16f);
            Rect rect4    = rect1;

            rect4.x = rect4.x - 18f;

            Rect rect2 = new Rect(position.x + 2f + 2f + 16f * 2, rect.y, 100f, rect.height)
            {
                xMax = rect4.xMin - 2f
            };
            Rect rect3 = new Rect(position.x + 16f, rect.y, 16f, 16f);

            executable.IsEnabled = GUI.Toggle(rect3, executable.IsEnabled, GUIContent.none);
            string url = executable.GetType().GetHelpUrl();

            if (ErrorChecker.HasErrors(executable))
            {
                Rect rect5 = rect4;
                rect5.y += 1.0f;
                if (!string.IsNullOrEmpty(url))
                {
                    rect5.x    = rect5.x - 18f;
                    rect2.xMax = rect5.x;
                }

                GUI.Label(rect5, FsmEditorStyles.errorIcon, FsmEditorStyles.inspectorTitleText);
            }

            if (GUI.Button(rect1, FsmEditorStyles.popupIcon, FsmEditorStyles.inspectorTitleText))
            {
                ExecutableContextMenu(executable, node).ShowAsContext();
            }

            if (!string.IsNullOrEmpty(url) && GUI.Button(rect4, FsmEditorStyles.helpIcon, FsmEditorStyles.inspectorTitleText))
            {
                Application.OpenURL(url);
            }

            EventType eventType = Event.current.type;

            if (eventType != EventType.MouseDown)
            {
                if (eventType == EventType.Repaint)
                {
                    FsmEditorStyles.inspectorTitle.Draw(position, GUIContent.none, controlID, executable.IsOpen);
                    FsmEditorStyles.inspectorTitleText.Draw(rect2, content, controlID, executable.IsOpen);
                }
            }
            position.width = 15;
            bool flag = DoToggleForward(position, controlID, executable.IsOpen, GUIContent.none, GUIStyle.none);

            if (flag != executable.IsOpen)
            {
                executable.IsOpen = flag;
            }
            return(flag);
        }
Esempio n. 28
0
        public static bool ObjectTitlebar(UnityEngine.Object targetObject, bool foldout, ref bool enabled, GenericMenu settings)
        {
            int        controlID = EditorGUIUtility.GetControlID(FocusType.Passive);
            GUIContent content   = new GUIContent(targetObject.name.Replace("/", "."), targetObject.GetTooltip());

            Debug.Log(FsmEditorStyles.inspectorTitle.fixedWidth);
            Rect position = GUILayoutUtility.GetRect(GUIContent.none, FsmEditorStyles.inspectorTitle);

            position.x     += 1f;
            position.width -= 3f;
            Rect rect  = new Rect(position.x + (float)FsmEditorStyles.inspectorTitle.padding.left, position.y + (float)FsmEditorStyles.inspectorTitle.padding.top, 16f, 16f);
            Rect rect1 = new Rect(position.xMax - (float)FsmEditorStyles.inspectorTitle.padding.right - 2f - 16f, rect.y, 16f, 16f);
            Rect rect4 = rect1;

            rect4.x = rect4.x - 18f;

            Rect rect2 = new Rect(position.x + 2f + 2f + 16f * 2, rect.y, 100f, rect.height)
            {
                xMax = rect4.xMin - 2f
            };
            Rect rect3 = new Rect(position.x + 16f, rect.y, 16f, 16f);

            enabled = GUI.Toggle(rect3, enabled, GUIContent.none);
            string url = targetObject.GetHelpUrl();

            if (ErrorChecker.HasErrors(targetObject))
            {
                Rect rect5 = rect4;
                rect5.y += 1.0f;
                if (!string.IsNullOrEmpty(url))
                {
                    rect5.x    = rect5.x - 18f;
                    rect2.xMax = rect5.x;
                }

                GUI.Label(rect5, FsmEditorStyles.errorIcon, FsmEditorStyles.inspectorTitleText);
            }

            if (GUI.Button(rect1, FsmEditorStyles.popupIcon, FsmEditorStyles.inspectorTitleText))
            {
                settings.ShowAsContext();
            }

            if (!string.IsNullOrEmpty(url) && GUI.Button(rect4, FsmEditorStyles.helpIcon, FsmEditorStyles.inspectorTitleText))
            {
                Application.OpenURL(url);
            }

            EventType eventType = Event.current.type;

            if (eventType != EventType.MouseDown)
            {
                if (eventType == EventType.Repaint)
                {
                    FsmEditorStyles.inspectorTitle.Draw(position, GUIContent.none, controlID, foldout);
                    Color color = GUI.contentColor;
                    if (FsmEditor.Active != null && FsmEditor.Active.Owner != null)
                    {
                        ICodeBehaviour behaviour = FsmEditor.Active.Owner;
                        if (behaviour.ActiveNode is State && (behaviour.ActiveNode as State).ActiveAction == targetObject)
                        {
                            GUI.contentColor = Color.green;
                        }
                    }
                    FsmEditorStyles.inspectorTitleText.Draw(rect2, content, controlID, foldout);
                    GUI.contentColor = color;
                }
            }
            position.width = 15;

            bool flag = FsmGUIUtility.DoToggleForward(position, controlID, foldout, GUIContent.none, GUIStyle.none);

            return(flag);
        }
Esempio n. 29
0
        private void OnGUI()
        {
            List <FsmError> errors = ErrorChecker.GetErrors();

            if (selectedFsmErrors)
            {
                if (FsmEditor.instance != null)
                {
                    errors = errors.FindAll(x => x.State.Parent == FsmEditor.Active).ToList();
                }
                else
                {
                    errors.Clear();
                }
            }
            //Toolbar
            GUILayout.BeginHorizontal(EditorStyles.toolbar);
            if (GUILayout.Button("Refresh", EditorStyles.toolbarButton))
            {
                ErrorChecker.CheckForErrors();
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Selected FSM Only", (selectedFsmErrors?(GUIStyle)"TE toolbarbutton" : EditorStyles.toolbarButton)))
            {
                selectedFsmErrors = !selectedFsmErrors;
                ErrorChecker.CheckForErrors();
                EditorPrefs.SetBool("SelectedFSMOnly", selectedFsmErrors);
            }
            GUILayout.EndHorizontal();

            scroll = EditorGUILayout.BeginScrollView(scroll);
            for (int i = 0; i < errors.Count; i++)
            {
                FsmError error = errors[i];
                GUIStyle style = FsmEditorStyles.elementBackground;
                if (i == index)
                {
                    style = new GUIStyle("MeTransitionSelectHead")
                    {
                        stretchHeight = false,
                    };
                    style.overflow = new RectOffset(-1, -2, -2, 2);
                }
                GUILayout.BeginVertical(style);
                GUILayout.Label(error.Type.ToString());
                GUILayout.Label(error.State.Parent.Name + " : " + error.State.Name + " : " + error.ExecutableNode.name + (error.FieldInfo != null? " : " + error.FieldInfo.Name:""));
                GUILayout.EndVertical();
                Rect  elementRect = new Rect(0, i * 19f * 2f, Screen.width, 19f * 2f);
                Event ev          = Event.current;
                switch (ev.rawType)
                {
                case EventType.MouseDown:
                    if (elementRect.Contains(Event.current.mousePosition))
                    {
                        if (Event.current.button == 0)
                        {
                            index = i;
                            if (FsmEditor.instance == null)
                            {
                                FsmEditor.ShowWindow();
                            }
                            FsmEditor.SelectNode(error.State);
                            Event.current.Use();
                        }
                    }
                    break;
                }
            }
            EditorGUILayout.EndScrollView();
        }