public override sealed void DrawNodeConnections(Vector2 canvasMousePos, float zoomFactor) { var e = Event.current; if (maxOutConnections == 0){ if (clickedPort != null && e.type == EventType.MouseUp){ dragDropMisses ++; if (dragDropMisses == graph.allNodes.Count){ clickedPort = null; } } return; } var portRectLeft = new Rect(0,0,20,20); var portRectRight = new Rect(0,0,20,20); var portRectBottom = new Rect(0,0,20,20); portRectLeft.center = new Vector2(nodeRect.x - 11, nodeRect.yMax - 10); portRectRight.center = new Vector2(nodeRect.xMax + 11, nodeRect.yMax - 10); portRectBottom.center = new Vector2(nodeRect.center.x, nodeRect.yMax + 11); EditorGUIUtility.AddCursorRect(portRectLeft, MouseCursor.ArrowPlus); EditorGUIUtility.AddCursorRect(portRectRight, MouseCursor.ArrowPlus); EditorGUIUtility.AddCursorRect(portRectBottom, MouseCursor.ArrowPlus); GUI.color = new Color(1,1,1,0.3f); GUI.Box(portRectLeft, "", "arrowLeft"); GUI.Box(portRectRight, "", "arrowRight"); if (maxInConnections == 0) GUI.Box(portRectBottom, "", "arrowBottom"); GUI.color = Color.white; if (e.type == EventType.MouseDown && e.button == 0){ if (portRectLeft.Contains(e.mousePosition)){ clickedPort = new GUIPort(this, portRectLeft.center); dragDropMisses = 0; e.Use(); } if (portRectRight.Contains(e.mousePosition)){ clickedPort = new GUIPort(this, portRectRight.center); dragDropMisses = 0; e.Use(); } if (maxInConnections == 0 && portRectBottom.Contains(e.mousePosition)){ clickedPort = new GUIPort(this, portRectBottom.center); dragDropMisses = 0; e.Use(); } } if (clickedPort != null && clickedPort.parent == this) Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos, e.mousePosition, new Color(0.5f,0.5f,0.8f,0.8f), null, 2); if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0){ if (nodeRect.Contains(e.mousePosition)){ foreach(FSMConnection connection in inConnections){ if (connection.sourceNode == clickedPort.parent){ Debug.LogWarning("State is already connected to target state. Consider using a 'ConditionList' on the existing transition if you want to check multiple conditions"); clickedPort = null; e.Use(); return; } } graph.ConnectNodes(clickedPort.parent, this); clickedPort = null; e.Use(); } else { dragDropMisses ++; if (dragDropMisses == graph.allNodes.Count && clickedPort != null){ var source = clickedPort.parent; var pos = Event.current.mousePosition; var menu = new GenericMenu(); clickedPort = null; menu.AddItem(new GUIContent("Add Action State"), false, ()=> { var newState = graph.AddNode<ActionState>(pos); graph.ConnectNodes(source, newState); }); //PostGUI cause of zoom factors Graph.PostGUI += ()=> { menu.ShowAsContext(); }; Event.current.Use(); e.Use(); } } } for (var i = 0; i < outConnections.Count; i++){ var connection = outConnections[i] as FSMConnection; var targetState = connection.targetNode as FSMState; if (targetState == null){ //In case of MissingNode type continue; } var targetPos = targetState.GetConnectedInPortPosition(connection); var sourcePos = Vector2.zero; if (nodeRect.center.x <= targetPos.x) sourcePos = portRectRight.center; if (nodeRect.center.x > targetPos.x) sourcePos = portRectLeft.center; if (maxInConnections == 0 && nodeRect.center.y < targetPos.y - 50 && Mathf.Abs(nodeRect.center.x - targetPos.x) < 200 ) sourcePos = portRectBottom.center; connection.DrawConnectionGUI(sourcePos, targetPos); } }
//Draw the connections line from this node, to all of its children. This is the default hierarchical style. Override in each system's base node class. virtual public void DrawNodeConnections(Vector2 canvasMousePos, float zoomFactor) { if (isHidden) { return; } var e = Event.current; //Receive connections first if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0) { if (nodeRect.Contains(e.mousePosition)) { graph.ConnectNodes(clickedPort.parent, this, clickedPort.portIndex); clickedPort = null; e.Use(); } else { dragDropMisses++; if (dragDropMisses == graph.allNodes.Count && clickedPort != null) { var source = clickedPort.parent; var index = clickedPort.portIndex; var pos = e.mousePosition; clickedPort = null; System.Action <System.Type> Selected = delegate(System.Type type){ var newNode = graph.AddNode(type, pos); graph.ConnectNodes(source, newNode, index); newNode.SortConnectionsByPositionX(); Graph.currentSelection = newNode; }; var menu = EditorUtils.GetTypeSelectionMenu(graph.baseNodeType, Selected); if (zoomFactor == 1 && NCPrefs.useBrowser) { menu.ShowAsBrowser(string.Format("Add {0} Node", graph.GetType().Name), graph.baseNodeType); } else { Graph.PostGUI += () => { menu.ShowAsContext(); }; } e.Use(); } } } if (maxOutConnections == 0) { return; } var nodeOutputBox = new Rect(nodeRect.x, nodeRect.yMax - 4, nodeRect.width, 12); GUI.Box(nodeOutputBox, "", (GUIStyle)"nodePortContainer"); //draw the ports if (outConnections.Count < maxOutConnections || maxOutConnections == -1) { for (var i = 0; i < outConnections.Count + 1; i++) { var portRect = new Rect(0, 0, 10, 10); portRect.center = new Vector2(((nodeRect.width / (outConnections.Count + 1)) * (i + 0.5f)) + nodeRect.xMin, nodeRect.yMax + 6); GUI.Box(portRect, "", (GUIStyle)"nodePortEmpty"); if (collapsed) { continue; } //start a connection by clicking a port EditorGUIUtility.AddCursorRect(portRect, MouseCursor.ArrowPlus); if (e.type == EventType.MouseDown && e.button == 0 && portRect.Contains(e.mousePosition)) { dragDropMisses = 0; clickedPort = new GUIPort(i, this, portRect.center); e.Use(); } } } //draw the new drag&drop connection line if (clickedPort != null && clickedPort.parent == this) { var yDiff = (clickedPort.pos.y - e.mousePosition.y) * 0.5f; yDiff = e.mousePosition.y > clickedPort.pos.y? -yDiff : yDiff; var tangA = new Vector2(0, yDiff); var tangB = tangA * -1; Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos + tangA, e.mousePosition + tangB, new Color(0.5f, 0.5f, 0.8f, 0.8f), null, 3); } //draw all connected lines for (var connectionIndex = 0; connectionIndex < outConnections.Count; connectionIndex++) { var connection = outConnections[connectionIndex]; if (connection != null) { var sourcePos = new Vector2(((nodeRect.width / (outConnections.Count + 1)) * (connectionIndex + 1)) + nodeRect.xMin, nodeRect.yMax + 6); var targetPos = new Vector2(connection.targetNode.nodeRect.center.x, connection.targetNode.nodeRect.y); var sourcePortRect = new Rect(0, 0, 12, 12); sourcePortRect.center = sourcePos; GUI.Box(sourcePortRect, "", (GUIStyle)"nodePortConnected"); if (collapsed || connection.targetNode.isHidden) { continue; } connection.DrawConnectionGUI(sourcePos, targetPos); //On right click disconnect connection from the source. if (e.type == EventType.ContextClick && sourcePortRect.Contains(e.mousePosition)) { graph.RemoveConnection(connection); e.Use(); return; } //On right click disconnect connection from the target. var targetPortRect = new Rect(0, 0, 15, 15); targetPortRect.center = targetPos; if (e.type == EventType.ContextClick && targetPortRect.Contains(e.mousePosition)) { graph.RemoveConnection(connection); e.Use(); return; } } } }
sealed public override void DrawNodeConnections(Vector2 canvasMousePos, float zoomFactor) { var e = Event.current; if (maxOutConnections == 0) { if (clickedPort != null && e.type == EventType.MouseUp) { dragDropMisses++; if (dragDropMisses == graph.allNodes.Count) { clickedPort = null; } } return; } var portRectLeft = new Rect(0, 0, 20, 20); var portRectRight = new Rect(0, 0, 20, 20); var portRectBottom = new Rect(0, 0, 20, 20); portRectLeft.center = new Vector2(nodeRect.x - 11, nodeRect.yMax - 10); portRectRight.center = new Vector2(nodeRect.xMax + 11, nodeRect.yMax - 10); portRectBottom.center = new Vector2(nodeRect.center.x, nodeRect.yMax + 11); EditorGUIUtility.AddCursorRect(portRectLeft, MouseCursor.ArrowPlus); EditorGUIUtility.AddCursorRect(portRectRight, MouseCursor.ArrowPlus); EditorGUIUtility.AddCursorRect(portRectBottom, MouseCursor.ArrowPlus); GUI.color = new Color(1, 1, 1, 0.3f); GUI.Box(portRectLeft, "", "arrowLeft"); GUI.Box(portRectRight, "", "arrowRight"); if (maxInConnections == 0) { GUI.Box(portRectBottom, "", "arrowBottom"); } GUI.color = Color.white; if (e.type == EventType.MouseDown && e.button == 0) { if (portRectLeft.Contains(e.mousePosition)) { clickedPort = new GUIPort(this, portRectLeft.center); dragDropMisses = 0; e.Use(); } if (portRectRight.Contains(e.mousePosition)) { clickedPort = new GUIPort(this, portRectRight.center); dragDropMisses = 0; e.Use(); } if (maxInConnections == 0 && portRectBottom.Contains(e.mousePosition)) { clickedPort = new GUIPort(this, portRectBottom.center); dragDropMisses = 0; e.Use(); } } if (clickedPort != null && clickedPort.parent == this) { Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos, e.mousePosition, new Color(0.5f, 0.5f, 0.8f, 0.8f), null, 2); } if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0) { if (nodeRect.Contains(e.mousePosition)) { foreach (FSMConnection connection in inConnections) { if (connection.sourceNode == clickedPort.parent) { Debug.LogWarning("State is already connected to target state. Consider using a 'ConditionList' on the existing transition if you want to check multiple conditions"); clickedPort = null; e.Use(); return; } } graph.ConnectNodes(clickedPort.parent, this); clickedPort = null; e.Use(); } else { dragDropMisses++; if (dragDropMisses == graph.allNodes.Count && clickedPort != null) { var source = clickedPort.parent; var pos = Event.current.mousePosition; var menu = new GenericMenu(); clickedPort = null; menu.AddItem(new GUIContent("Add Action State"), false, () => { var newState = graph.AddNode <ActionState>(pos); graph.ConnectNodes(source, newState); }); //PostGUI cause of zoom factors Graph.PostGUI += () => { menu.ShowAsContext(); }; Event.current.Use(); e.Use(); } } } for (var i = 0; i < outConnections.Count; i++) { var connection = outConnections[i] as FSMConnection; var targetState = connection.targetNode as FSMState; if (targetState == null) //In case of MissingNode type { continue; } var targetPos = targetState.GetConnectedInPortPosition(connection); var sourcePos = Vector2.zero; if (nodeRect.center.x <= targetPos.x) { sourcePos = portRectRight.center; } if (nodeRect.center.x > targetPos.x) { sourcePos = portRectLeft.center; } if (maxInConnections == 0 && nodeRect.center.y < targetPos.y - 50 && Mathf.Abs(nodeRect.center.x - targetPos.x) < 200) { sourcePos = portRectBottom.center; } connection.DrawConnectionGUI(sourcePos, targetPos); } }
///Editor. Draw the connections line from this node, to all of its children. This is the default hierarchical tree style. Override in each system's base node class. virtual protected void DrawNodeConnections(Rect drawCanvas, bool fullDrawPass, Vector2 canvasMousePos, float zoomFactor) { var e = Event.current; //Receive connections first if ( clickedPort != null && e.type == EventType.MouseUp && e.button == 0 ) { if ( rect.Contains(e.mousePosition) ) { graph.ConnectNodes(clickedPort.parent, this, clickedPort.portIndex); clickedPort = null; e.Use(); } else { dragDropMisses++; if ( dragDropMisses == graph.allNodes.Count && clickedPort != null ) { var source = clickedPort.parent; var index = clickedPort.portIndex; var pos = e.mousePosition; clickedPort = null; System.Action<System.Type> Selected = delegate (System.Type type) { var newNode = graph.AddNode(type, pos); graph.ConnectNodes(source, newNode, index); GraphEditorUtility.activeElement = newNode; }; var menu = EditorUtils.GetTypeSelectionMenu(graph.baseNodeType, Selected); if ( zoomFactor == 1 ) { menu.ShowAsBrowser(string.Format("Add {0} Node", graph.GetType().Name), graph.baseNodeType); } else { GraphEditorUtility.PostGUI += () => { menu.ShowAsContext(); }; } e.Use(); } } } if ( maxOutConnections == 0 ) { return; } if ( fullDrawPass || drawCanvas.Overlaps(rect) ) { var nodeOutputBox = new Rect(rect.x, rect.yMax - 4, rect.width, 12); GUI.Box(nodeOutputBox, string.Empty, StyleSheet.nodePortContainer); //draw the ports if ( outConnections.Count < maxOutConnections || maxOutConnections == -1 ) { for ( var i = 0; i < outConnections.Count + 1; i++ ) { var portRect = new Rect(0, 0, 10, 10); portRect.center = new Vector2(( ( rect.width / ( outConnections.Count + 1 ) ) * ( i + 0.5f ) ) + rect.xMin, rect.yMax + 6); GUI.Box(portRect, string.Empty, StyleSheet.nodePortEmpty); if ( collapsed ) { continue; } if ( GraphEditorUtility.allowClick ) { //start a connection by clicking a port EditorGUIUtility.AddCursorRect(portRect, MouseCursor.ArrowPlus); if ( e.type == EventType.MouseDown && e.button == 0 && portRect.Contains(e.mousePosition) ) { dragDropMisses = 0; clickedPort = new GUIPort(i, this, portRect.center); e.Use(); } } } } } //draw the new drag&drop connection line if ( clickedPort != null && clickedPort.parent == this ) { var tangA = default(Vector2); var tangB = default(Vector2); ParadoxNotion.CurveUtils.ResolveTangents(clickedPort.pos, e.mousePosition, 0.5f, PlanarDirection.Vertical, out tangA, out tangB); Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos + tangA, e.mousePosition + tangB, StyleSheet.GetStatusColor(Status.Resting).WithAlpha(0.8f), null, 3); } //draw all connected lines for ( var i = 0; i < outConnections.Count; i++ ) { var connection = outConnections[i]; if ( connection != null ) { var sourcePos = new Vector2(( ( rect.width / ( outConnections.Count + 1 ) ) * ( i + 1 ) ) + rect.xMin, rect.yMax + 6); var targetPos = new Vector2(connection.targetNode.rect.center.x, connection.targetNode.rect.y); var sourcePortRect = new Rect(0, 0, 12, 12); sourcePortRect.center = sourcePos; var targetPortRect = new Rect(0, 0, 15, 15); targetPortRect.center = targetPos; var boundRect = RectUtils.GetBoundRect(sourcePortRect, targetPortRect); if ( fullDrawPass || drawCanvas.Overlaps(boundRect) ) { GUI.Box(sourcePortRect, string.Empty, StyleSheet.nodePortConnected); if ( collapsed || connection.targetNode.isHidden ) { continue; } connection.DrawConnectionGUI(sourcePos, targetPos); if ( GraphEditorUtility.allowClick ) { //On right click disconnect connection from the source. if ( e.type == EventType.ContextClick && sourcePortRect.Contains(e.mousePosition) ) { graph.RemoveConnection(connection); e.Use(); return; } //On right click disconnect connection from the target. if ( e.type == EventType.ContextClick && targetPortRect.Contains(e.mousePosition) ) { graph.RemoveConnection(connection); e.Use(); return; } } } } } }
//Draw the ports and connections sealed protected override void DrawNodeConnections(Rect drawCanvas, bool fullDrawPass, Vector2 canvasMousePos, float zoomFactor) { var e = Event.current; //Receive connections first if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0) { if (rect.Contains(e.mousePosition)) { graph.ConnectNodes(clickedPort.parent, this); clickedPort = null; e.Use(); } else { dragDropMisses++; if (dragDropMisses == graph.allNodes.Count && clickedPort != null) { var source = clickedPort.parent; var pos = Event.current.mousePosition; var menu = new GenericMenu(); clickedPort = null; menu.AddItem(new GUIContent("Add Action State"), false, () => { var newState = graph.AddNode <ActionState>(pos); graph.ConnectNodes(source, newState); }); //PostGUI cause of zoom factors GraphEditorUtility.PostGUI += () => { menu.ShowAsContext(); }; Event.current.Use(); e.Use(); } } } var portRectLeft = new Rect(0, 0, 20, 20); var portRectRight = new Rect(0, 0, 20, 20); var portRectBottom = new Rect(0, 0, 20, 20); portRectLeft.center = new Vector2(rect.x - 11, rect.center.y); portRectRight.center = new Vector2(rect.xMax + 11, rect.center.y); portRectBottom.center = new Vector2(rect.center.x, rect.yMax + 11); if (maxOutConnections != 0) { if (fullDrawPass || drawCanvas.Overlaps(rect)) { EditorGUIUtility.AddCursorRect(portRectLeft, MouseCursor.ArrowPlus); EditorGUIUtility.AddCursorRect(portRectRight, MouseCursor.ArrowPlus); EditorGUIUtility.AddCursorRect(portRectBottom, MouseCursor.ArrowPlus); GUI.color = new Color(1, 1, 1, 0.3f); GUI.DrawTexture(portRectLeft, StyleSheet.arrowLeft); GUI.DrawTexture(portRectRight, StyleSheet.arrowRight); if (maxInConnections == 0) { GUI.DrawTexture(portRectBottom, StyleSheet.arrowBottom); } GUI.color = Color.white; if (GraphEditorUtility.allowClick && e.type == EventType.MouseDown && e.button == 0) { if (portRectLeft.Contains(e.mousePosition)) { clickedPort = new GUIPort(this, portRectLeft.center); dragDropMisses = 0; e.Use(); } if (portRectRight.Contains(e.mousePosition)) { clickedPort = new GUIPort(this, portRectRight.center); dragDropMisses = 0; e.Use(); } if (maxInConnections == 0 && portRectBottom.Contains(e.mousePosition)) { clickedPort = new GUIPort(this, portRectBottom.center); dragDropMisses = 0; e.Use(); } } } } //draw new linking if (clickedPort != null && clickedPort.parent == this) { Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos, e.mousePosition, new Color(0.5f, 0.5f, 0.8f, 0.8f), null, 2); } //draw out connections for (var i = 0; i < outConnections.Count; i++) { var connection = outConnections[i] as FSMConnection; var targetState = connection.targetNode as FSMState; if (targetState == null) { //In case of MissingNode type continue; } var targetPos = targetState.GetConnectedInPortPosition(connection); var sourcePos = Vector2.zero; if (rect.center.x <= targetPos.x) { sourcePos = portRectRight.center; } if (rect.center.x > targetPos.x) { sourcePos = portRectLeft.center; } if (maxInConnections == 0 && rect.center.y < targetPos.y - 50 && Mathf.Abs(rect.center.x - targetPos.x) < 200) { sourcePos = portRectBottom.center; } var boundRect = RectUtils.GetBoundRect(sourcePos, targetPos); if (fullDrawPass || drawCanvas.Overlaps(boundRect)) { connection.DrawConnectionGUI(sourcePos, targetPos); } } }
/// <summary> /// 画出连线 /// </summary> /// <param name="canvasMousePos"></param> /// <param name="zoomFactor"></param> public virtual void DrawNodeConnections(Vector2 canvasMousePos, float zoomFactor) { var e = Event.current; if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0) { if (nodeRect.Contains(e.mousePosition)) { graph.ConnectNodes(clickedPort.parent, this, clickedPort.portIndex); this.PostConnectionActiveEvent(); clickedPort = null; e.Use(); } else { dragDropMisses++; if (dragDropMisses == graph.allNodes.Count && clickedPort != null) { var source = clickedPort.parent; var index = clickedPort.portIndex; var pos = e.mousePosition; clickedPort = null; System.Action <System.Type> Selected = delegate(System.Type type) { var newNode = graph.AddNode(type, pos); graph.ConnectNodes(source, newNode, index); // newNode.SortConnectionsByPositionX(); Graph.currentSelection = newNode; }; } } } if (maxInConnections == 0) { return; } var nodeOutputBox = new Rect(nodeRect.x, nodeRect.yMax - 4, nodeRect.width, 12); GUI.Box(nodeOutputBox, "", (GUIStyle)"nodePortContainer"); if (outConnections.Count < maxOutConnections || maxOutConnections == -1) { for (var i = 0; i < outConnections.Count + 1; i++) { var portRect = new Rect(0, 0, 10, 10); portRect.center = new Vector2(((nodeRect.width / (outConnections.Count + 1)) * (i + 0.5f)) + nodeRect.xMin, nodeRect.yMax + 6); GUI.Box(portRect, "", (GUIStyle)"nodePortEmpty"); EditorGUIUtility.AddCursorRect(portRect, MouseCursor.ArrowPlus); if (e.type == EventType.MouseDown && e.button == 0 && portRect.Contains(e.mousePosition)) { dragDropMisses = 0; clickedPort = new GUIPort(i, this, portRect.center); e.Use(); } } } if (clickedPort != null && clickedPort.parent == this) { var yDiff = (clickedPort.pos.y - e.mousePosition.y) * 0.5f; yDiff = e.mousePosition.y > clickedPort.pos.y ? -yDiff : yDiff; var tangA = new Vector2(0, yDiff); var tangB = tangA * -1; Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos + tangA, e.mousePosition + tangB, new Color(0.5f, 0.5f, 0.8f, 0.8f), null, 3); } for (var connectionIndex = 0; connectionIndex < outConnections.Count; connectionIndex++) { var connection = outConnections[connectionIndex]; if (connection != null) { var sourcePos = new Vector2(((nodeRect.width / (outConnections.Count + 1)) * (connectionIndex + 1)) + nodeRect.xMin, nodeRect.yMax + 6); var targetPos = new Vector2(connection.targetNode.nodeRect.center.x, connection.targetNode.nodeRect.y); var sourcePortRect = new Rect(0, 0, 12, 12); sourcePortRect.center = sourcePos; GUI.Box(sourcePortRect, "", (GUIStyle)"nodePortConnected"); connection.DrawConnectionGUI(sourcePos, targetPos); //On right click disconnect connection from the source. if (e.type == EventType.ContextClick && sourcePortRect.Contains(e.mousePosition)) { graph.RemoveConnection(connection); e.Use(); return; } //On right click disconnect connection from the target. var targetPortRect = new Rect(0, 0, 15, 15); targetPortRect.center = targetPos; if (e.type == EventType.ContextClick && targetPortRect.Contains(e.mousePosition)) { graph.RemoveConnection(connection); e.Use(); return; } } } }