/// <summary> /// Get the Dialogue data for active node (normally from Dialogue type node). Null means there was error or Graph is done /// Pass start=true to have the graph determine what to send by walking the nodes from the Start node again /// </summary> public DiaQConversation GetData(bool start) { if (start) currNode = GetNode(0); // go to first node WalkGraph(); HasSeenPlayer = true; return GetData(); }
private void DrawNode_QuestCheck(DiaQNode node) { GUI.DrawTexture(new Rect(node.position.width - 14, 2, 12, 12), DiaQEdGUI.Icon_Decision); Vector2 v = node.OutputPosition(0); GUI.Label(new Rect(0, v.y - 9, node.position.width - 20, 16), "NotTaken", DiaQEdGUI.RightAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowRed), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = 0; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } v = node.OutputPosition(1); GUI.Label(new Rect(0, v.y - 9, node.position.width - 20, 16), "Accepted", DiaQEdGUI.RightAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowYellow), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = 1; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } v = node.OutputPosition(2); GUI.Label(new Rect(0, v.y - 9, node.position.width - 20, 16), "Completed", DiaQEdGUI.RightAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowGreen), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = 2; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } v = node.OutputPosition(3); GUI.Label(new Rect(0, v.y - 9, node.position.width - 20, 16), "HandedIn", DiaQEdGUI.RightAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowBlue), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = 3; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } v = node.OutputPosition(4); GUI.DrawTexture(new Rect(2, v.y - 8, 16, 16), DiaQEdGUI.Icon_Quest); if (node.i_data[0] == 0) GUI.Label(new Rect(20, v.y - 9, node.position.width - 40, 16), node.CachedString, DiaQEdGUI.LeftAlignTextStyle); else GUI.Label(new Rect(20, v.y - 9, node.position.width - 40, 16), "from: " + node.data[0], DiaQEdGUI.LeftAlignTextStyle); }
private void DrawNode_Random(DiaQNode node) { Vector2 v = node.OutputPosition(0); GUI.DrawTexture(new Rect(2, v.y - 8, 16, 16), DiaQEdGUI.Icon_Dice); for (int i = 0; i < node.i_data[0]; i++) { v = node.OutputPosition(i); GUI.Label(new Rect(0, v.y - 9, node.position.width - 20, 16), i.ToString(), DiaQEdGUI.RightAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowBlue), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = i; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } } }
private void DrawNode_Decision(DiaQNode node) { GUI.DrawTexture(new Rect(node.position.width - 14, 2, 12, 12), DiaQEdGUI.Icon_Decision); Vector2 v = node.OutputPosition(0); GUI.Label(new Rect(0, v.y - 9, node.position.width - 20, 16), "TRUE", DiaQEdGUI.RightAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowGreen), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = 0; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } v = node.OutputPosition(1); GUI.Label(new Rect(0, v.y - 9, node.position.width - 20, 16), "FALSE", DiaQEdGUI.RightAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowRed), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = 1; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } }
private void DrawNode_Dialogue(DiaQNode node) { GUI.DrawTexture(new Rect(node.position.width - 14, 2, 12, 12), DiaQEdGUI.Icon_Dialogue); for (int i = 0; i < node.choices.Count; i++) { Vector2 v = node.OutputPosition(i); GUI.Label(new Rect(0, v.y - 9, node.position.width - 20, 16), node.choices[i] + " :" + (i + 1).ToString(), DiaQEdGUI.RightAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowBlue), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = i; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } } }
private void DrawNode_End(DiaQNode node) { GUI.DrawTexture(new Rect(node.position.width * 0.5f - 8, 20, 16, 16), DiaQEdGUI.Icon_Stop); }
private void DrawNode_Start(DiaQNode node) { GUI.DrawTexture(new Rect(19, 19, 16, 16), DiaQEdGUI.Icon_Play); Vector2 v = node.OutputPosition(0); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowBlue), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = 0; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } }
// ------------------------------------------------------------------------------------------------------------ public static Rect GetNodeDefaultRect(DiaQNode node, Vector2 pos) { Rect r = new Rect(pos.x, pos.y, 60f, 40f); switch (node.type) { case Type.Dialogue: { r.width = 200; if (node.choices.Count > 0) r.height += (node.choices.Count-1) * 20f; } break; case Type.GiveQuest: r.width = 150f; break; case Type.Decision: r.width = 100f; r.height = 60f; break; case Type.DebugLog: r.width = 150f; break; case Type.SendMessage: r.width = 150f; break; case Type.SetVariable: r.width = 150f; break; case Type.Random: r.width = 85f; r.height = 80f; break; case Type.UpdateCondition: r.width = 150f; break; case Type.QuestCheck: r.width = 120f; r.height = 120f; break; case Type.GiveReward: r.width = 150; break; case Type.UniRPGEvent: r.width = 150; break; } r.x -= r.width * 0.5f; r.y -= r.height * 0.5f; return r; }
private void DrawGraphToolbar() { GUILayout.Space(15); GUILayout.BeginHorizontal(); { GUILayout.Space(15); if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_ResetView, "Reset view"), DiaQEdGUI.ButtonLeftStyle, GUILayout.Width(30))) { currGraph.DrawOffset = Vector2.zero; linkNode = null; } showComments = GUILayout.Toggle(showComments, new GUIContent(DiaQEdGUI.Icon_Tag, "Toggle Comments"), DiaQEdGUI.ButtonRightStyle, GUILayout.Width(30)); GUILayout.Space(10); if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Dialogue, "Add Dialogue Node"), DiaQEdGUI.ButtonLeftStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.Dialogue, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Quest, "Add GiveQuest Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.GiveQuest, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Check, "Add UpdateCondition Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.UpdateCondition, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Reward, "Add GiveReward Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.GiveReward, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Event, "Add UniRPGEvent Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.UniRPGEvent, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_QuestCheck, "Add QuestCheck Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.QuestCheck, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Decision, "Add Decision Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.Decision, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Dice, "Add RandomPath Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.Random, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Variable, "Add SetVariable Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.SetVariable, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Script, "Add SendMessage Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.SendMessage, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Bug, "Add DebugLog Node"), DiaQEdGUI.ButtonMidStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.DebugLog, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } if (GUILayout.Button(new GUIContent(DiaQEdGUI.Icon_Stop, "Add End Node"), DiaQEdGUI.ButtonRightStyle, GUILayout.Width(30))) { currGraph.CreateNode(DiaQNode.Type.End, new Vector2(splitterPos[0] * 0.5f, this.position.height * 0.5f)); linkNode = null; } } GUILayout.EndHorizontal(); }
private Color GetLinkColour(DiaQNode n, int slot) { if (n.type == DiaQNode.Type.Decision) { if (slot == 0) return DiaQEdGUI.Col_LinkGreen; else return DiaQEdGUI.Col_LinkRed; } else if (n.type == DiaQNode.Type.QuestCheck) { if (slot == 0) return DiaQEdGUI.Col_LinkRed; else if (slot == 1) return DiaQEdGUI.Col_LinkYellow; else if (slot == 2) return DiaQEdGUI.Col_LinkGreen; else if (slot == 3) return DiaQEdGUI.Col_LinkBlue; } return DiaQEdGUI.Col_LinkBlue; }
private void HandleEvents() { if (Event.current != null) { switch (Event.current.type) { case EventType.MouseDown: { if (linkNode != null) { linkNode = null; Event.current.Use(); Repaint(); } else { if (Event.current.button == 0) { if (currGraph != null) { // Start dragging Graph if (mainRect.Contains(Event.current.mousePosition)) { draggingGraph = true; Event.current.Use(); } } if (Event.current.type != EventType.Used) { if (splitterRect[0].Contains(Event.current.mousePosition)) { // Start dragging vertical splitter draggingSplitter[0] = true; Event.current.Use(); } else if (splitterRect[1].Contains(Event.current.mousePosition)) { // Start dragging horizontal splitter draggingSplitter[1] = true; Event.current.Use(); } } } if (Event.current.button == 1) { // unselect node on right-click if (mainRect.Contains(Event.current.mousePosition)) { ShowGraphAreaPopMenu(); Event.current.Use(); Repaint(); } } } } break; case EventType.MouseDrag: { if (draggingGraph && currGraph!=null) { currGraph.DrawOffset += Event.current.delta; Event.current.Use(); } if (draggingSplitter[0]) { splitterPos[0] += Event.current.delta.x; if (splitterPos[0] > (this.position.width - inspectorMinWidth)) splitterPos[0] = this.position.width - inspectorMinWidth; if (splitterPos[0] < 50) splitterPos[0] = 50; inspectorWidthPercentage = splitterPos[0] / this.position.width; questRect.x = splitterPos[0] * 0.5f - questRect.width * 0.5f; Event.current.Use(); } if (draggingSplitter[1]) { splitterPos[1] += Event.current.delta.y; if (splitterPos[1] < inspectorMinHeight) splitterPos[1] = inspectorMinHeight; if (splitterPos[1] > this.position.height - inspectorMinHeight) splitterPos[1] = this.position.height - inspectorMinHeight; Event.current.Use(); } } break; case EventType.MouseUp: { if (draggingGraph) { draggingGraph = false; Event.current.Use(); Repaint(); } if (draggingSplitter[0]) { draggingSplitter[0] = false; Event.current.Use(); Repaint(); } if (draggingSplitter[1]) { draggingSplitter[1] = false; Event.current.Use(); Repaint(); } } break; case EventType.KeyDown: { if (linkNode != null) { linkNode = null; Event.current.Use(); Repaint(); } else { if (!GUI.changed && currNode != null) { //if (Event.current.keyCode == KeyCode.Delete || Event.current.keyCode == KeyCode.Backspace) if (Event.current.keyCode == KeyCode.Delete) { DeleteCurrentNode(); } if (Event.current.keyCode == KeyCode.Escape) { // Unselect Node currNode = null; Event.current.Use(); Repaint(); } } } } break; } // check if window was resized if (this.position.width != prevScreenSize.x) { splitterPos[0] = this.position.width * inspectorWidthPercentage; prevScreenSize.x = this.position.width; if (splitterPos[0] > (this.position.width - inspectorMinWidth) || splitterPos[0] < 50f) splitterPos[0] = this.position.width - inspectorMinWidth; questRect.x = splitterPos[0] * 0.5f - questRect.width * 0.5f; questRect.height = this.position.height - 50; } if (this.position.height != prevScreenSize.y) { prevScreenSize.y = this.position.height; questRect.height = this.position.height - 50; } } }
/// <summary> /// Get the Dialogue data for active node (normally from Dialogue type node). Null means there was error or Graph is done /// This expects that the Graph was waiting at a Dialogue type and will nto look at what choice was given to continue /// walking the graph nodes to the next result. If the current node has node choices the graph will just continue now /// </summary> public DiaQConversation GetData(int choise) { if (currNode == null) return null; currNode = currNode.GetLinkedNode(this, choise); WalkGraph(); HasSeenPlayer = true; return GetData(); }
// ============================================================================================================ #region Editor helpers - do not access these at runtime #if UNITY_EDITOR public void CreateNode(DiaQNode.Type type, Vector2 pos) { DiaQNode n = new DiaQNode(); n.Init(_nextNodeId++, type); n.SetRectInGraph(this, DiaQNode.GetNodeDefaultRect(n, pos)); nodes.Add(n); }
private bool WalkGraph() { // recursively walks the nodes of the graph up to where player interaction is // needed or the graph exits (return true when must stop walking) // no currNode? exit. if (currNode == null) return true; // check what to do next. switch (currNode.type) { case DiaQNode.Type.Dialogue: { return true; // stop walking now } case DiaQNode.Type.Decision: { currNode = currNode.ExecuteDecision(this); } break; case DiaQNode.Type.GiveQuest: { HandleGiveQuest(); currNode = currNode.GetLinkedNode(this, 0); } break; case DiaQNode.Type.UpdateCondition: { HandleUpdateCondition(); currNode = currNode.GetLinkedNode(this, 0); } break; case DiaQNode.Type.QuestCheck: { currNode = HandleQuestCheck(); } break; case DiaQNode.Type.SendMessage: { HandleSendMessage(); currNode = currNode.GetLinkedNode(this, 0); } break; case DiaQNode.Type.SetVariable: { HandleSetVar(); currNode = currNode.GetLinkedNode(this, 0); } break; case DiaQNode.Type.Random: { if (currNode.i_data[0] <= 1) currNode = currNode.GetLinkedNode(this, 0); else currNode = currNode.GetLinkedNode(this, Random.Range(0, currNode.i_data[0])); } break; case DiaQNode.Type.DebugLog: { HandleDebugLog(); currNode = currNode.GetLinkedNode(this, 0); } break; case DiaQNode.Type.End: { currNode = null; return true; // stop walking now } case DiaQNode.Type.Start: { currNode = currNode.GetLinkedNode(this, 0); } break; case DiaQNode.Type.GiveReward: { HandleGiveReward(); currNode = currNode.GetLinkedNode(this, 0); } break; case DiaQNode.Type.UniRPGEvent: { HandleUniRPGEventCall(); currNode = currNode.GetLinkedNode(this, 0); } break; default: { Debug.LogError("Encountered unhandled Node Type: " + currNode.type); return true; } } // nothing more to do? stop walking now. if (currNode == null) return true; // see if should walk further. return WalkGraph(); }
private void DrawNode_UniRPGEvent(DiaQNode node) { Vector2 v = node.OutputPosition(0); GUI.DrawTexture(new Rect(2, v.y - 8, 16, 16), DiaQEdGUI.Icon_Event); GUI.Label(new Rect(20, v.y - 9, node.position.width - 40, 16), node.CachedString, DiaQEdGUI.LeftAlignTextStyle); if (GUI.Button(new Rect(v.x - 16, v.y - 8, 16, 16), new GUIContent(DiaQEdGUI.Icon_ArrowBlue), DiaQEdGUI.IconButtonStyle)) { linkNode = node; linkOutSlot = 0; linkOutPos1 = node.GetPositionInGraph(currGraph) + v; } }
// ============================================================================================================ #region node window private void NodeWindow(int id) { DiaQNode node = currGraph.GetNode(id); switch (node.type) { case DiaQNode.Type.Start: DrawNode_Start(node); break; case DiaQNode.Type.End: DrawNode_End(node); break; case DiaQNode.Type.Dialogue: DrawNode_Dialogue(node); break; case DiaQNode.Type.Decision: DrawNode_Decision(node); break; case DiaQNode.Type.GiveQuest: DrawNode_Quest(node); break; case DiaQNode.Type.DebugLog: DrawNode_DebugLog(node); break; case DiaQNode.Type.SendMessage: DrawNode_SendMessage(node); break; case DiaQNode.Type.SetVariable: DrawNode_SetVariable(node); break; case DiaQNode.Type.Random: DrawNode_Random(node); break; case DiaQNode.Type.QuestCheck: DrawNode_QuestCheck(node); break; case DiaQNode.Type.UpdateCondition: DrawNode_UpdateCondition(node); break; case DiaQNode.Type.GiveReward: DrawNode_Reward(node); break; case DiaQNode.Type.UniRPGEvent: DrawNode_UniRPGEvent(node); break; } if (node.type != DiaQNode.Type.Start) { if (GUI.Button(new Rect(0, 0, 16, 16), new GUIContent(DiaQEdGUI.Icon_ConnectionIn), DiaQEdGUI.IconButtonStyle)) { if (linkNode != null) { linkNode.LinkWith(node, linkOutSlot, true); linkNode = null; EditorUtility.SetDirty(asset); } } } if ((Event.current.button == 0) && (Event.current.type == EventType.MouseDown)) { currNode = node; GUI.FocusControl(""); GUI.FocusWindow(id); } GUI.DragWindow(); }
public void OnLostFocus() { wantsMouseMove = false; linkNode = null; }
public void LinkWith(DiaQNode targetNode, int onOutputSlot, bool removePrevLink) { // don't allow linking self if (targetNode == this) return; if (!removePrevLink) { // already a link on the slot? Only one per out slot allowed if (outputs.Any(link => link.outSlot == onOutputSlot)) return; } else { // remove any existing link on the out slot outputs.RemoveAll(link => link.outSlot == onOutputSlot); } // create new link outputs.Add(new NodeLink() { outSlot = onOutputSlot, targetNodeId = targetNode.id }); }