//MIKEHACK public void AddCommandHack(Block bl, Type type, int index) { if (bl == null) { return; } Flowchart flowchart = bl.GetFlowchart(); flowchart.ClearSelectedCommands(); Command newCommand = Undo.AddComponent(bl.gameObject, type) as Command; bl.GetFlowchart().AddSelectedCommand(newCommand); newCommand.parentBlock = bl; newCommand.itemId = flowchart.NextItemId(); // Let command know it has just been added to the block newCommand.OnCommandAdded(bl); Undo.RecordObject(bl, "Set command type"); if (index < bl.commandList.Count - 1) { bl.commandList.Insert(index, newCommand); } else { bl.commandList.Add(newCommand); } // Because this is an async call, we need to force prefab instances to record changes PrefabUtility.RecordPrefabInstancePropertyModifications(bl); }
protected static void AddCommandCallback(object obj) { AddCommandOperation commandOperation = obj as AddCommandOperation; Block block = commandOperation.block; if (block == null) { return; } Flowchart flowchart = block.GetFlowchart(); flowchart.ClearSelectedCommands(); Command newCommand = Undo.AddComponent(block.gameObject, commandOperation.commandType) as Command; block.GetFlowchart().AddSelectedCommand(newCommand); newCommand.parentBlock = block; newCommand.itemId = flowchart.NextItemId(); // Let command know it has just been added to the block newCommand.OnCommandAdded(block); Undo.RecordObject(block, "Set command type"); if (commandOperation.index < block.commandList.Count - 1) { block.commandList.Insert(commandOperation.index, newCommand); } else { block.commandList.Add(newCommand); } }
protected void Copy() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null || flowchart.selectedBlock == null) { return; } CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); commandCopyBuffer.Clear(); // Scan through all commands in execution order to see if each needs to be copied foreach (Command command in flowchart.selectedBlock.commandList) { if (flowchart.selectedCommands.Contains(command)) { System.Type type = command.GetType(); Command newCommand = Undo.AddComponent(commandCopyBuffer.gameObject, type) as Command; System.Reflection.FieldInfo[] fields = type.GetFields(); foreach (System.Reflection.FieldInfo field in fields) { field.SetValue(newCommand, field.GetValue(command)); } } } }
protected void SelectNext() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); int lastSelectedIndex = -1; if (flowchart.selectedCommands.Count > 0) { for (int i = 0; i < flowchart.selectedBlock.commandList.Count; i++) { Command commandInBlock = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (commandInBlock == selectedCommand) { lastSelectedIndex = i; } } } } if (lastSelectedIndex < flowchart.selectedBlock.commandList.Count - 1) { flowchart.ClearSelectedCommands(); flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[lastSelectedIndex + 1]); } Repaint(); }
protected void Paste() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null || flowchart.selectedBlock == null) { return; } CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); // Find where to paste commands in block (either at end or after last selected command) int pasteIndex = flowchart.selectedBlock.commandList.Count; if (flowchart.selectedCommands.Count > 0) { for (int i = 0; i < flowchart.selectedBlock.commandList.Count; ++i) { Command command = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (command == selectedCommand) { pasteIndex = i + 1; } } } } foreach (Command command in commandCopyBuffer.GetCommands()) { // Using the Editor copy / paste functionality instead instead of reflection // because this does a deep copy of the command properties. if (ComponentUtility.CopyComponent(command)) { if (ComponentUtility.PasteComponentAsNew(flowchart.gameObject)) { Command[] commands = flowchart.GetComponents <Command>(); Command pastedCommand = commands.Last <Command>(); if (pastedCommand != null) { pastedCommand.itemId = flowchart.NextItemId(); flowchart.selectedBlock.commandList.Insert(pasteIndex++, pastedCommand); } } // This stops the user pasting the command manually into another game object. ComponentUtility.CopyComponent(flowchart.transform); } } // Because this is an async call, we need to force prefab instances to record changes PrefabUtility.RecordPrefabInstancePropertyModifications(block); Repaint(); }
public override void OnInspectorGUI() { BlockInspector blockInspector = target as BlockInspector; Block block = blockInspector.block; if (block == null) { return; } Flowchart flowchart = block.GetFlowchart(); if (activeBlockEditor == null || block != activeBlockEditor.target) { DestroyImmediate(activeBlockEditor); activeBlockEditor = Editor.CreateEditor(block) as BlockEditor; } activeBlockEditor.DrawBlockName(flowchart); UpdateWindowHeight(); float width = EditorGUIUtility.currentViewWidth; float height = windowHeight; // Using a custom rect area to get the correct 5px indent for the scroll views Rect blockRect = new Rect(5, topPanelHeight, width - 5, height + 10); GUILayout.BeginArea(blockRect); blockScrollPos = GUILayout.BeginScrollView(blockScrollPos, GUILayout.Height(flowchart.blockViewHeight)); activeBlockEditor.DrawBlockGUI(flowchart); GUILayout.EndScrollView(); Command inspectCommand = null; if (flowchart.selectedCommands.Count == 1) { inspectCommand = flowchart.selectedCommands[0]; } if (Application.isPlaying && inspectCommand != null && inspectCommand.parentBlock != block) { GUILayout.EndArea(); Repaint(); return; } // Only change the activeCommand at the start of the GUI call sequence if (Event.current.type == EventType.Layout) { activeCommand = inspectCommand; } DrawCommandUI(flowchart, inspectCommand); }
protected virtual void ShowCommandMenu() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); // Use index of last selected command in list, or end of list if nothing selected. int index = -1; foreach (Command command in flowchart.selectedCommands) { if (command.commandIndex + 1 > index) { index = command.commandIndex + 1; } } if (index == -1) { index = block.commandList.Count; } GenericMenu commandMenu = new GenericMenu(); // Build menu list List <System.Type> menuTypes = EditorExtensions.FindDerivedTypes(typeof(Command)).ToList(); List <KeyValuePair <System.Type, CommandInfoAttribute> > filteredAttributes = GetFilteredCommandInfoAttribute(menuTypes); filteredAttributes.Sort(CompareCommandAttributes); foreach (var keyPair in filteredAttributes) { // Skip command type if the Flowchart doesn't support it if (!flowchart.IsCommandSupported(keyPair.Value)) { continue; } AddCommandOperation commandOperation = new AddCommandOperation(); commandOperation.block = block; commandOperation.commandType = keyPair.Key; commandOperation.index = index; GUIContent menuItem; if (keyPair.Value.Category == "") { menuItem = new GUIContent(keyPair.Value.CommandName); } else { menuItem = new GUIContent(keyPair.Value.Category + "/" + keyPair.Value.CommandName); } commandMenu.AddItem(menuItem, false, AddCommandCallback, commandOperation); } commandMenu.ShowAsContext(); }
protected void Delete() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null || flowchart.selectedBlock == null) { return; } int lastSelectedIndex = 0; for (int i = flowchart.selectedBlock.commandList.Count - 1; i >= 0; --i) { Command command = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (command == selectedCommand) { command.OnCommandRemoved(block); // Order of destruction is important here for undo to work Undo.DestroyObjectImmediate(command); Undo.RecordObject(flowchart.selectedBlock, "Delete"); flowchart.selectedBlock.commandList.RemoveAt(i); lastSelectedIndex = i; break; } } } Undo.RecordObject(flowchart, "Delete"); flowchart.ClearSelectedCommands(); if (lastSelectedIndex < flowchart.selectedBlock.commandList.Count) { Command nextCommand = flowchart.selectedBlock.commandList[lastSelectedIndex]; block.GetFlowchart().AddSelectedCommand(nextCommand); } Repaint(); }
protected void StopAllPlayCommand() { Block targetBlock = target as Block; Flowchart flowchart = targetBlock.GetFlowchart(); Command command = flowchart.selectedCommands[0]; // Stop all active blocks then run the selected block. flowchart.StopAllBlocks(); flowchart.StartCoroutine(RunBlock(flowchart, targetBlock, command.commandIndex, 0.2f)); }
public virtual bool AddOption(string text, bool interactable, Block targetBlock) { bool addedOption = false; foreach (Button button in cachedButtons) { if (!button.gameObject.activeSelf) { button.gameObject.SetActive(true); button.interactable = interactable; if (interactable && autoSelectFirstButton && !cachedButtons.Select((x) => x.gameObject).Contains(EventSystem.current.currentSelectedGameObject)) { EventSystem.current.SetSelectedGameObject(button.gameObject); } Text textComponent = button.GetComponentInChildren <Text>(); if (textComponent != null) { textComponent.text = text; } Block block = targetBlock; button.onClick.AddListener(delegate { EventSystem.current.SetSelectedGameObject(null); StopAllCoroutines(); // Stop timeout Clear(); HideSayDialog(); if (block != null) { #if UNITY_EDITOR // Select the new target block in the Flowchart window Flowchart flowchart = block.GetFlowchart(); flowchart.selectedBlock = block; #endif gameObject.SetActive(false); block.StartExecution(); } }); addedOption = true; break; } } return(addedOption); }
protected static void AddCommandCallback(object obj) { AddCommandOperation commandOperation = obj as AddCommandOperation; Block block = commandOperation.block; if (block == null) { return; } Flowchart flowchart = block.GetFlowchart(); flowchart.ClearSelectedCommands(); Command newCommand = Undo.AddComponent(block.gameObject, commandOperation.commandType) as Command; block.GetFlowchart().AddSelectedCommand(newCommand); newCommand.parentBlock = block; newCommand.itemId = flowchart.NextItemId(); // Let command know it has just been added to the block newCommand.OnCommandAdded(block); Undo.RecordObject(block, "Set command type"); if (commandOperation.index < block.commandList.Count - 1) { block.commandList.Insert(commandOperation.index, newCommand); } else { block.commandList.Add(newCommand); } // Because this is an async call, we need to force prefab instances to record changes PrefabUtility.RecordPrefabInstancePropertyModifications(block); }
protected void SelectNone() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null || flowchart.selectedBlock == null) { return; } Undo.RecordObject(flowchart, "Select None"); flowchart.ClearSelectedCommands(); Repaint(); }
public virtual bool AddOption(string text, Block targetBlock) { bool addedOption = false; foreach (Button button in cachedButtons) { if (!button.gameObject.activeSelf) { button.gameObject.SetActive(true); Text textComponent = button.GetComponentInChildren <Text>(); if (textComponent != null) { textComponent.text = text; } Block block = targetBlock; button.onClick.AddListener(delegate { StopAllCoroutines(); // Stop timeout Clear(); HideSayDialog(); if (block != null) { #if UNITY_EDITOR // Select the new target block in the Flowchart window Flowchart flowchart = block.GetFlowchart(); flowchart.selectedBlock = block; #endif gameObject.SetActive(false); block.Execute(); } }); addedOption = true; break; } } return(addedOption); }
protected void SelectAll() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null || flowchart.selectedBlock == null) { return; } flowchart.ClearSelectedCommands(); Undo.RecordObject(flowchart, "Select All"); foreach (Command command in flowchart.selectedBlock.commandList) { flowchart.AddSelectedCommand(command); } Repaint(); }
protected void PlayCommand() { Block targetBlock = target as Block; Flowchart flowchart = targetBlock.GetFlowchart(); Command command = flowchart.selectedCommands[0]; if (targetBlock.IsExecuting()) { // The Block is already executing. // Tell the Block to stop, wait a little while so the executing command has a // chance to stop, and then start execution again from the new command. targetBlock.Stop(); flowchart.StartCoroutine(RunBlock(flowchart, targetBlock, command.commandIndex, 0.2f)); } else { // Block isn't executing yet so can start it now. flowchart.ExecuteBlock(targetBlock, command.commandIndex); } }
protected void SelectPrevious() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); int firstSelectedIndex = flowchart.selectedBlock.commandList.Count; bool firstSelectedCommandFound = false; if (flowchart.selectedCommands.Count > 0) { for (int i = 0; i < flowchart.selectedBlock.commandList.Count; i++) { Command commandInBlock = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (commandInBlock == selectedCommand) { if (!firstSelectedCommandFound) { firstSelectedIndex = i; firstSelectedCommandFound = true; break; } } } if (firstSelectedCommandFound) { break; } } } if (firstSelectedIndex > 0) { flowchart.ClearSelectedCommands(); flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[firstSelectedIndex - 1]); } Repaint(); }
/** * The Event Handler should call this method when the event is detected. */ public virtual bool ExecuteBlock() { if (parentBlock == null) { return(false); } if (parentBlock.eventHandler != this) { return(false); } Flowchart flowchart = parentBlock.GetFlowchart(); // Auto-follow the executing block if none is currently selected if (flowchart.selectedBlock == null) { flowchart.selectedBlock = parentBlock; } return(flowchart.ExecuteBlock(parentBlock)); }
public override void OnInspectorGUI() { BlockInspector blockInspector = target as BlockInspector; Block block = blockInspector.block; if (block == null) { return; } Flowchart flowchart = block.GetFlowchart(); BlockEditor blockEditor = Editor.CreateEditor(block) as BlockEditor; blockEditor.DrawBlockName(flowchart); // Using a custom rect area to get the correct 5px indent for the scroll views Rect blockRect = new Rect(5, topPanelHeight, Screen.width - 6, Screen.height - 70); GUILayout.BeginArea(blockRect); blockScrollPos = GUILayout.BeginScrollView(blockScrollPos, GUILayout.Height(flowchart.blockViewHeight)); blockEditor.DrawBlockGUI(flowchart); GUILayout.EndScrollView(); Command inspectCommand = null; if (flowchart.selectedCommands.Count == 1) { inspectCommand = flowchart.selectedCommands[0]; } if (Application.isPlaying && inspectCommand != null && inspectCommand.parentBlock != block) { GUILayout.EndArea(); Repaint(); DestroyImmediate(blockEditor); return; } ResizeScrollView(flowchart); GUILayout.Space(7); blockEditor.DrawButtonToolbar(); commandScrollPos = GUILayout.BeginScrollView(commandScrollPos); if (inspectCommand != null) { CommandEditor commandEditor = Editor.CreateEditor(inspectCommand) as CommandEditor; commandEditor.DrawCommandInspectorGUI(); DestroyImmediate(commandEditor); } GUILayout.EndScrollView(); GUILayout.EndArea(); // Draw the resize bar after everything else has finished drawing // This is mainly to avoid incorrect indenting. Rect resizeRect = new Rect(0, topPanelHeight + flowchart.blockViewHeight + 1, Screen.width, 4f); GUI.color = new Color(0.64f, 0.64f, 0.64f); GUI.DrawTexture(resizeRect, EditorGUIUtility.whiteTexture); resizeRect.height = 1; GUI.color = new Color32(132, 132, 132, 255); GUI.DrawTexture(resizeRect, EditorGUIUtility.whiteTexture); resizeRect.y += 3; GUI.DrawTexture(resizeRect, EditorGUIUtility.whiteTexture); GUI.color = Color.white; Repaint(); DestroyImmediate(blockEditor); }
protected virtual void DrawWindow(int windowId) { Block block = windowBlockMap[windowId]; Flowchart flowchart = block.GetFlowchart(); // Select block when node is clicked if (Event.current.button == 0 && Event.current.type == EventType.MouseDown && !mouseOverVariables) { // Check if might be start of a window drag if (Event.current.button == 0 && Event.current.alt == false) { dragWindowId = windowId; startDragPosition.x = block.nodeRect.x; startDragPosition.y = block.nodeRect.y; } if (windowId < windowBlockMap.Count) { Undo.RecordObject(flowchart, "Select"); SelectBlock(flowchart, block); GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) } } bool selected = (flowchart.selectedBlock == block); GUIStyle nodeStyleCopy = new GUIStyle(nodeStyle); if (block.eventHandler != null) { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texEventNodeOn : FungusEditorResources.texEventNodeOff; } else { // Count the number of unique connections (excluding self references) List <Block> uniqueList = new List <Block>(); List <Block> connectedBlocks = block.GetConnectedBlocks(); foreach (Block connectedBlock in connectedBlocks) { if (connectedBlock == block || uniqueList.Contains(connectedBlock)) { continue; } uniqueList.Add(connectedBlock); } if (uniqueList.Count > 1) { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texChoiceNodeOn : FungusEditorResources.texChoiceNodeOff; } else { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texProcessNodeOn : FungusEditorResources.texProcessNodeOff; } } nodeStyleCopy.normal.textColor = Color.black; // Make sure node is wide enough to fit the node name text float width = nodeStyleCopy.CalcSize(new GUIContent(block.blockName)).x; block.nodeRect.width = Mathf.Max(block.nodeRect.width, width); GUI.backgroundColor = Color.white; GUILayout.Box(block.blockName, nodeStyleCopy, GUILayout.Width(block.nodeRect.width), GUILayout.Height(block.nodeRect.height)); if (block.eventHandler != null) { string handlerLabel = ""; EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(block.eventHandler.GetType()); if (info != null) { handlerLabel = "<" + info.EventHandlerName + "> "; } string handlerSummary = block.eventHandler.GetSummary(); if (handlerSummary.Length > 0) { handlerLabel += handlerSummary; } GUIStyle handlerStyle = new GUIStyle(EditorStyles.helpBox); handlerStyle.wordWrap = true; handlerStyle.margin.top = 0; handlerStyle.margin.bottom = 0; GUILayout.Label(handlerLabel, handlerStyle); // Move connection marker down below handler description float height = 44 + handlerStyle.CalcHeight(new GUIContent(handlerLabel), block.nodeRect.width); block.nodeRect.height = height; } if (block.description.Length > 0) { GUIStyle descriptionStyle = new GUIStyle(EditorStyles.whiteLabel); descriptionStyle.wordWrap = true; GUILayout.Label(block.description, descriptionStyle); } if (Event.current.type == EventType.ContextClick) { GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Duplicate"), false, DuplicateBlock, block); menu.AddItem(new GUIContent("Delete"), false, DeleteBlock, block); menu.ShowAsContext(); } }
public virtual void ShowContextMenu() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null) { return; } bool showCut = false; bool showCopy = false; bool showDelete = false; bool showPaste = false; if (flowchart.selectedCommands.Count > 0) { showCut = true; showCopy = true; showDelete = true; } CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); if (commandCopyBuffer.HasCommands()) { showPaste = true; } GenericMenu commandMenu = new GenericMenu(); if (showCut) { commandMenu.AddItem(new GUIContent("Cut"), false, Cut); } else { commandMenu.AddDisabledItem(new GUIContent("Cut")); } if (showCopy) { commandMenu.AddItem(new GUIContent("Copy"), false, Copy); } else { commandMenu.AddDisabledItem(new GUIContent("Copy")); } if (showPaste) { commandMenu.AddItem(new GUIContent("Paste"), false, Paste); } else { commandMenu.AddDisabledItem(new GUIContent("Paste")); } if (showDelete) { commandMenu.AddItem(new GUIContent("Delete"), false, Delete); } else { commandMenu.AddDisabledItem(new GUIContent("Delete")); } commandMenu.AddSeparator(""); commandMenu.AddItem(new GUIContent("Select All"), false, SelectAll); commandMenu.AddItem(new GUIContent("Select None"), false, SelectNone); commandMenu.ShowAsContext(); }