Esempio n. 1
0
        private void InsertDuplicateNodes(xNode.Node[] nodes, Vector2 topLeft)
        {
            if (nodes == null || nodes.Length == 0)
            {
                return;
            }

            // Get top-left node
            Vector2 topLeftNode = nodes.Select(x => x.position)
                                  .Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y)));
            Vector2 offset = topLeft - topLeftNode;

            UnityEngine.Object[] newNodes = new UnityEngine.Object[nodes.Length];
            Dictionary <xNode.Node, xNode.Node> substitutes = new Dictionary <xNode.Node, xNode.Node>();

            for (int i = 0; i < nodes.Length; i++)
            {
                xNode.Node srcNode = nodes[i];
                if (srcNode == null)
                {
                    continue;
                }

                // Check if user is allowed to add more of given node type
                xNode.Node.DisallowMultipleNodesAttribute disallowAttrib;
                Type nodeType = srcNode.GetType();
                if (NodeEditorUtilities.GetAttrib(nodeType, out disallowAttrib))
                {
                    int typeCount = this.graph.nodes.Count(x => x.GetType() == nodeType);
                    if (typeCount >= disallowAttrib.max)
                    {
                        continue;
                    }
                }

                xNode.Node newNode = this.graphEditor.CopyNode(srcNode);
                substitutes.Add(srcNode, newNode);
                newNode.position = srcNode.position + offset;
                newNodes[i]      = newNode;
            }

            // Walk through the selected nodes again, recreate connections, using the new nodes
            for (int i = 0; i < nodes.Length; i++)
            {
                xNode.Node srcNode = nodes[i];
                if (srcNode == null)
                {
                    continue;
                }
                foreach (xNode.NodePort port in srcNode.Ports)
                {
                    for (int c = 0; c < port.ConnectionCount; c++)
                    {
                        xNode.NodePort inputPort =
                            port.Direction == xNode.NodePort.IO.Input ? port : port.GetConnection(c);
                        xNode.NodePort outputPort =
                            port.Direction == xNode.NodePort.IO.Output ? port : port.GetConnection(c);

                        xNode.Node newNodeIn, newNodeOut;
                        if (substitutes.TryGetValue(inputPort.node, out newNodeIn) &&
                            substitutes.TryGetValue(outputPort.node, out newNodeOut))
                        {
                            newNodeIn.UpdatePorts();
                            newNodeOut.UpdatePorts();
                            inputPort  = newNodeIn.GetInputPort(inputPort.fieldName);
                            outputPort = newNodeOut.GetOutputPort(outputPort.fieldName);
                        }

                        if (!inputPort.IsConnectedTo(outputPort))
                        {
                            inputPort.Connect(outputPort);
                        }
                    }
                }
            }

            EditorUtility.SetDirty(this.graph);
            // Select the new nodes
            Selection.objects = newNodes;
        }
Esempio n. 2
0
        /// <summary> Draws all connections </summary>
        public void DrawConnections()
        {
            Vector2 mousePos = Event.current.mousePosition;
            List <RerouteReference> selection = this.preBoxSelectionReroute != null
                ? new List <RerouteReference>(this.preBoxSelectionReroute)
                : new List <RerouteReference>();

            this.hoveredReroute = new RerouteReference();

            List <Vector2> gridPoints = new List <Vector2>(2);

            Color col = GUI.color;

            foreach (xNode.Node node in this.graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                // Draw full connections and output > reroute
                foreach (xNode.NodePort output in node.Outputs)
                {
                    //Needs cleanup. Null checks are ugly
                    if (!this._portConnectionPoints.TryGetValue(output, out var fromRect))
                    {
                        continue;
                    }

                    Color portColor = this.graphEditor.GetPortColor(output);
                    for (int k = 0; k < output.ConnectionCount; k++)
                    {
                        xNode.NodePort input = output.GetConnection(k);

                        Gradient     noodleGradient  = this.graphEditor.GetNoodleGradient(output, input);
                        float        noodleThickness = this.graphEditor.GetNoodleThickness(output, input);
                        NoodlePath   noodlePath      = this.graphEditor.GetNoodlePath(output, input);
                        NoodleStroke noodleStroke    = this.graphEditor.GetNoodleStroke(output, input);

                        // Error handling
                        if (input == null)
                        {
                            continue; //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
                        }
                        if (!input.IsConnectedTo(output))
                        {
                            input.Connect(output);
                        }
                        if (!this._portConnectionPoints.TryGetValue(input, out var toRect))
                        {
                            continue;
                        }

                        List <Vector2> reroutePoints = output.GetReroutePoints(k);

                        gridPoints.Clear();
                        gridPoints.Add(fromRect.center);
                        gridPoints.AddRange(reroutePoints);
                        gridPoints.Add(toRect.center);
                        this.DrawNoodle(noodleGradient, noodlePath, noodleStroke, noodleThickness, gridPoints);

                        // Loop through reroute points again and draw the points
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            RerouteReference rerouteRef = new RerouteReference(output, k, i);
                            // Draw reroute point at position
                            Rect rect = new Rect(reroutePoints[i], new Vector2(12, 12));
                            rect.position = new Vector2(rect.position.x - 6, rect.position.y - 6);
                            rect          = this.GridToWindowRect(rect);

                            // Draw selected reroute points with an outline
                            if (this.selectedReroutes.Contains(rerouteRef))
                            {
                                GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                                GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
                            }

                            GUI.color = portColor;
                            GUI.DrawTexture(rect, NodeEditorResources.dot);
                            if (rect.Overlaps(this.selectionBox))
                            {
                                selection.Add(rerouteRef);
                            }
                            if (rect.Contains(mousePos))
                            {
                                this.hoveredReroute = rerouteRef;
                            }
                        }
                    }
                }
            }

            GUI.color = col;
            if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
            {
                this.selectedReroutes = selection;
            }
        }