private bool deleteNode(DialogueNode dNode) { if (dialogue == null || dNode == null) { return(false); } // Mark the deleted and any deprecated/dead nodes for deletion: for (int i = 0; i < nodes.Count; ++i) { DialogueNodeEditor.Node n = nodes[i]; if (n.node == null || n.node == dNode) { n.node = null; n.rootId = -1; nodes[i] = n; } } // Remove all marked nodes from list: nodes.RemoveAll(o => o.node == null); Repaint(); // Destroy node asset in dialogue: return(DialogueEditorHelper.destroyNodeAsset(dNode)); }
private bool duplicateNode(DialogueNodeEditor.Node node) { if (dialogue == null || node.node == null) { return(false); } // Duplicate node asset: DialogueNode newDNode = DialogueEditorHelper.duplicateNode(node.node); if (newDNode == null) { Debug.LogError("[DialogueEditor] Error! Failed to duplicate node in dialogue asset!"); return(false); } // Create new node from prefab one, but using the newly cloned asset: DialogueNodeEditor.Node newNode = node; newNode.node = newDNode; newNode.rect = new Rect(node.rect.x + 30, node.rect.y + 30, node.rect.width, node.rect.height); // Add to nodes list and return success: nodes.Add(newNode); Repaint(); return(true); }
public bool createNewNode(Dialogue dialogue, ref List <Node> nodes) { // Make sure the dialogue asset is non-null: if (dialogue == null) { return(false); } // Update node list: (initialize list and load existing nodes from dialogue asset) if (nodes == null || nodes.Count == 0) { createNodeList(dialogue, ref nodes); } // Create a new node asset in dialogue: DialogueNode newDNode = DialogueEditorHelper.createNewNode(dialogue); // Create an editor node representation: Node newNode = Node.Blank; newNode.node = newDNode; // Set newly created node as root node if no root has been assigned yet: if (dialogue.rootNodes == null || dialogue.rootNodes.Length == 0) { // Create new root node in dialogue with no conditions: DialogueConditions newRootConds = DialogueConditions.None; DialogueRoot newRoot = new DialogueRoot() { node = newDNode, conditions = newRootConds }; dialogue.rootNodes = new DialogueRoot[1] { newRoot }; newNode.rootId = 0; // Save changes to asset: DialogueEditorHelper.saveDialogueAsset(dialogue); } // Center the new node on screen: newNode.rect.center = new Vector2(Screen.width, Screen.height) * 0.5f + offset; // Add the new node representation to nodes list: nodes.Add(newNode); return(true); }
void OnGUI() { // A) CONSTANTS & REFERENCES: // UI constants: const float uiHeaderHeight = 38f; Rect areaRect = new Rect(0, uiHeaderHeight + 1, Screen.width, Screen.height - uiHeaderHeight - 1); // Get the currently selected node: DialogueNodeEditor.Node selected = DialogueNodeEditor.Node.Blank; if (dialogue != null && nodes != null && selectedNodeIndex >= 0 && selectedNodeIndex < nodes.Count) { selected = nodes[selectedNodeIndex]; } // Make sure there is always a node editor instance at hand: if (nodeEditor == null) { nodeEditor = new DialogueNodeEditor(); } // B) HEADER: EditorGUI.DrawRect(new Rect(0, uiHeaderHeight, Screen.width, 1), Color.black); EditorGUI.DrawRect(areaRect, Color.gray); Dialogue newDialogue = (Dialogue)EditorGUI.ObjectField(new Rect(0, 0, 300, 16), "Dialogue asset", dialogue, typeof(Dialogue), false); if (newDialogue != dialogue) { // Assign new asset and reset selections: dialogue = newDialogue; assetChanged = true; nodeEditor.setSelection(DialogueNodeEditor.Node.Blank); // Rebuild node graph: if (dialogue != null) { DialogueNodeEditor.createNodeList(dialogue, ref nodes); nodeEditor.autoLayoutNodes(); } return; } //Buttons for layouting: GUILayout.BeginArea(new Rect(Screen.width - 303, 0, 300, 18)); { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Save changes") && dialogue != null) { DialogueEditorHelper.saveDialogueAsset(dialogue); assetChanged = false; } if (GUILayout.Button("Rebuild graph")) { DialogueNodeEditor.createNodeList(dialogue, ref nodes); nodeEditor.autoLayoutNodes(); } if (GUILayout.Button("Auto-Layout")) { nodeEditor.autoLayoutNodes(); } EditorGUILayout.EndHorizontal(); } GUILayout.EndArea(); // Buttons for creating, deleting and duplicating node assets: GUILayout.BeginArea(new Rect(Screen.width - 303, 19, 300, 18)); { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("New Node")) { // Create new node and select it right away: if (nodeEditor.createNewNode(dialogue, ref nodes)) { selectNode(nodes.Count - 1); Repaint(); } } EditorGUI.BeginDisabledGroup(nodeEditor.Selected.node == null); if (GUILayout.Button("Delete Node")) { deleteNode(nodeEditor.Selected.node); } if (GUILayout.Button("Duplicate")) { duplicateNode(nodeEditor.Selected); } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); } GUILayout.EndArea(); EditorGUI.LabelField(new Rect(0, 16, 300, 16), "Asset status: ", assetStatusLines[(int)assetStatus]); if (dialogue == null) { return; } // C) WORK AREA: GUI.BeginGroup(areaRect); GUI.BeginClip(new Rect(0, 0, areaRect.width, areaRect.height)); if (nodes == null && dialogue != null && dialogue.rootNodes != null) { DialogueNodeEditor.createNodeList(dialogue, ref nodes); } // Draw existing nodes in their relative positions here with all their dependencies. if (dialogue != null && nodes != null) { assetChanged = assetChanged || nodeEditor.drawNodes(dialogue, nodes, scrollPosition); } // Navigation elements: { Rect navRect = new Rect(10, 10, 200, 70); GUI.BeginGroup(navRect); EditorGUI.DrawRect(new Rect(0, 0, navRect.width, navRect.height), Color.black); EditorGUI.DrawRect(new Rect(1, 1, navRect.width - 2, navRect.height - 2), new Color(0.75f, 0.75f, 0.75f)); // Draw navigation buttons at the top left of the work space: if (GUI.RepeatButton(new Rect(5, 25, 20, 20), "L")) { scrollPosition.x -= 10.0f; } if (GUI.RepeatButton(new Rect(45, 25, 20, 20), "R")) { scrollPosition.x += 10.0f; } if (GUI.RepeatButton(new Rect(25, 5, 20, 20), "D")) { scrollPosition.y -= 10.0f; } if (GUI.RepeatButton(new Rect(25, 45, 20, 20), "U")) { scrollPosition.y += 10.0f; } if (GUI.RepeatButton(new Rect(25, 25, 20, 20), "O")) { scrollPosition = Vector2.zero; } findNodeTxt = EditorGUI.TextField(new Rect(70, 5, 85, 16), findNodeTxt); if (GUI.Button(new Rect(156, 5, 39, 16), "Find") && !string.IsNullOrEmpty(findNodeTxt)) { int findNodeIndex = -1; try { findNodeIndex = System.Convert.ToInt32(findNodeTxt); } catch (System.Exception) { } for (int i = 0; i < nodes.Count; ++i) { DialogueNodeEditor.Node fNode = nodes[i]; DialogueNode fdNode = fNode.node; if (fdNode == null) { continue; } if (i == findNodeIndex || fdNode.name.Contains(findNodeTxt)) { selectNode(i); centerSelected(); break; } } } findPos.x = EditorGUI.FloatField(new Rect(70, 22, 42, 16), findPos.x); findPos.y = EditorGUI.FloatField(new Rect(113, 22, 42, 16), findPos.y); if (GUI.Button(new Rect(156, 22, 39, 16), "Goto")) { scrollPosition.x = Mathf.Round(findPos.x - Screen.width * 0.5f); scrollPosition.y = Mathf.Round(findPos.y - Screen.height * 0.5f); } DialogueNodeEditor.showReturnLinks = GUI.Toggle(new Rect(70, 40, 106, 16), DialogueNodeEditor.showReturnLinks, "Show full curves"); GUI.EndGroup(); } GUI.EndClip(); GUI.EndGroup(); // D) ASSET CHANGES: // Do some post-checks if the asset was changed: if (assetChanged) { // Drop current selection if it has expired: if (selected.node == null) { selectedNodeIndex = -1; } // Remove any invalid nodes from dialogue: nodes.RemoveAll(o => o.node == null); } //Reset flags: assetChanged = false; }