public override void OnInspectorGUI() { base.OnInspectorGUI(); SerializedProperty property = serializedObject.FindProperty("stateMachine"); if (property.objectReferenceValue != null) { StateMachine fsm = property.objectReferenceValue as StateMachine; showInfo = EditorGUILayout.Foldout(showInfo, "Info"); if (showInfo) { int indent = EditorGUI.indentLevel; EditorGUI.indentLevel++; GUILayout.Label("StateMachines (" + (fsm.StateMachinesRecursive.Length + 1) + ")"); GUILayout.Label("States (" + fsm.StatesRecursive.Length + ")"); GUILayout.Label("Actions (" + fsm.ActionsRecursive.Length + ")"); GUILayout.Label("Variables (" + fsm.VisibleVariables.Length + ")"); EditorGUI.indentLevel = indent; } showVariables = EditorGUILayout.Foldout(showVariables, "Variables"); if (showVariables) { FsmVariable[] variables = fsm.VisibleVariables; for (int i = 0; i < variables.Length; i++) { SerializedObject obj = new SerializedObject(variables[i]); obj.Update(); EditorGUILayout.PropertyField(obj.FindProperty("value"), new GUIContent(obj.FindProperty("name").stringValue)); obj.ApplyModifiedProperties(); } } } bool flag = GUI.enabled; GUI.enabled = !(property.objectReferenceValue == null || !EditorUtility.IsPersistent(property.objectReferenceValue)); if (GUILayout.Button("Bind to GameObject")) { serializedObject.Update(); StateMachine stateMachine = (StateMachine)FsmUtility.Copy((StateMachine)property.objectReferenceValue); property.objectReferenceValue = stateMachine; serializedObject.ApplyModifiedProperties(); if (FsmEditor.instance != null) { FsmEditor.SelectStateMachine(stateMachine); } } GUI.enabled = flag; if (GUILayout.Button("Open in Editor")) { FsmEditor.ShowWindow(); if (FsmEditor.instance != null) { FsmEditor.SelectStateMachine((StateMachine)property.objectReferenceValue); } } }
protected override void CanvasContextMenu () { if (currentEvent.type != EventType.MouseDown || currentEvent.button != 1 || currentEvent.clickCount != 1 || FsmEditor.Active == null){ return; } GenericMenu canvasMenu = new GenericMenu (); canvasMenu.AddItem (FsmContent.createState, false, delegate() { State state= FsmEditorUtility.AddNode<State>(mousePosition,FsmEditor.Active); state.IsStartNode=FsmEditor.Active.GetStartNode() == null; FsmEditorUtility.UpdateNodeColor(state); }); canvasMenu.AddItem (FsmContent.createSubFsm, false, delegate() { StateMachine stateMachine=FsmEditorUtility.AddNode<StateMachine>(mousePosition,FsmEditor.Active); stateMachine.IsStartNode=FsmEditor.Active.GetStartNode() == null; FsmEditorUtility.UpdateNodeColor(stateMachine); }); canvasMenu.AddItem (FsmContent.copy, false, delegate() { Pasteboard.Copy(new List<Node>(){FsmEditor.Active}); }); if (Pasteboard.CanPaste ()) { canvasMenu.AddItem (FsmContent.paste, false, delegate() { Pasteboard.Paste(mousePosition,FsmEditor.Active); }); } canvasMenu.AddSeparator (""); if (Selection.activeGameObject != null) { canvasMenu.AddItem (FsmContent.addToSelection, false, delegate() { foreach(GameObject go in Selection.gameObjects){ ICodeBehaviour behaviour = go.AddComponent<ICodeBehaviour>(); behaviour.stateMachine = FsmEditor.Active.Root; EditorUtility.SetDirty(behaviour); } SelectGameObject(Selection.activeGameObject); }); canvasMenu.AddItem (FsmContent.bindToGameObject, false, delegate() { foreach(GameObject go in Selection.gameObjects){ ICodeBehaviour behaviour = go.AddComponent<ICodeBehaviour>(); behaviour.stateMachine = (StateMachine)FsmUtility.Copy(FsmEditor.Active.Root);//FsmEditor.Active.Root; EditorUtility.SetDirty(behaviour); } SelectGameObject(Selection.activeGameObject); }); } else { canvasMenu.AddDisabledItem(FsmContent.addToSelection); canvasMenu.AddDisabledItem(FsmContent.bindToGameObject); } if (FsmEditor.Active.Root != null && !EditorUtility.IsPersistent(FsmEditor.Active.Root)) { canvasMenu.AddItem (FsmContent.saveAsAsset, false, delegate() { string mPath = EditorUtility.SaveFilePanelInProject ( "Save StateMachine as Asset", "New StateMachine.asset", "asset", ""); if(mPath != null){ StateMachine stateMachine=(StateMachine)FsmUtility.Copy(FsmEditor.Active.Root); AssetDatabase.CreateAsset(stateMachine,mPath); AssetDatabase.SaveAssets(); FsmEditorUtility.ParentChilds(stateMachine); } }); } else { canvasMenu.AddDisabledItem(FsmContent.saveAsAsset); } canvasMenu.ShowAsContext (); }
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(); }
private void ResetConditionList() { if (transition == null) { return; } this.conditions = this.transition.Conditions; this.conditionList = new ReorderableList(this.conditions, "Condition", true, true) { drawElementCallback = new ReorderableList.ElementCallbackDelegate(this.OnConditionElement), onReorderCallback = new ReorderableList.ReorderCallbackDelegate(this.OnReorderConditionList), onAddCallback = new ReorderableList.AddCallbackDelegate(delegate(){ FsmGUIUtility.SubclassMenu <Condition> (CreateCondition); }), onContextClick = new ReorderableList.ContextCallbackDelegate(delegate(int index){ FsmGUIUtility.ExecutableContextMenu(conditions[index], node).ShowAsContext(); }), onHeaderClick = new ReorderableList.OnHeaderClick(delegate(){ GenericMenu menu = new GenericMenu(); if (conditions.Length > 0) { menu.AddItem(new GUIContent("Copy"), false, delegate { copy = transition; }); } else { menu.AddDisabledItem(new GUIContent("Copy")); } if (copy != null && copy.Conditions.Length > 0) { menu.AddItem(new GUIContent("Paste After"), false, delegate() { for (int i = 0; i < copy.Conditions.Length; i++) { ExecutableNode dest = FsmUtility.Copy(copy.Conditions[i]); transition.Conditions = ArrayUtility.Add <Condition>(transition.Conditions, (Condition)dest); FsmEditorUtility.ParentChilds(transition); NodeInspector.Dirty(); } }); menu.AddItem(new GUIContent("Paste Before"), false, delegate() { for (int i = 0; i < copy.Conditions.Length; i++) { ExecutableNode dest = FsmUtility.Copy(copy.Conditions[i]); transition.Conditions = ArrayUtility.Insert <Condition>(transition.Conditions, (Condition)dest, 0); FsmEditorUtility.ParentChilds(transition); NodeInspector.Dirty(); } }); if (copy != transition) { menu.AddItem(new GUIContent("Replace"), false, delegate() { for (int i = 0; i < transition.Conditions.Length; i++) { FsmEditorUtility.DestroyImmediate(transition.Conditions[i]); } transition.Conditions = new Condition[0]; ResetConditionList(); for (int i = 0; i < copy.Conditions.Length; i++) { ExecutableNode dest = FsmUtility.Copy(copy.Conditions[i]); transition.Conditions = ArrayUtility.Add <Condition>(transition.Conditions, (Condition)dest); FsmEditorUtility.ParentChilds(transition); NodeInspector.Dirty(); } }); } 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(); } }
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(); }); return(menu); }
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(); } }
private void ResetActionList() { this.actions = this.state.Actions; this.actionList = new ReorderableList(this.actions, "Action", true, true) { drawElementCallback = new ReorderableList.ElementCallbackDelegate(this.OnActionElement), onReorderCallback = new ReorderableList.ReorderCallbackDelegate(this.OnReorderList), onAddCallback = new ReorderableList.AddCallbackDelegate(delegate(){ FsmGUIUtility.SubclassMenu <StateAction> (CreateAction); }), onContextClick = new ReorderableList.ContextCallbackDelegate(delegate(int index){ FsmGUIUtility.ExecutableContextMenu(actions[index], state).ShowAsContext(); }), onHeaderClick = new ReorderableList.OnHeaderClick(delegate(){ GenericMenu menu = new GenericMenu(); if (actions.Length > 0) { menu.AddItem(new GUIContent("Copy"), false, delegate { copy = new List <StateAction>(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); NodeInspector.Dirty(); } }); 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); NodeInspector.Dirty(); } }); 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); NodeInspector.Dirty(); } }); } 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(); } }