Example #1
0
        /// <summary>
        /// Creates a node of the specified ID at pos on the specified canvas, optionally auto-connecting the specified output to a matching input
        /// silent disables any events, init specifies whether OnCreate should be called
        /// </summary>
        public static Node Create(string nodeID, Vector2 pos, NodeCanvas hostCanvas, ConnectionPort connectingPort = null, bool silent = false, bool init = true)
        {
            if (string.IsNullOrEmpty(nodeID) || hostCanvas == null)
            {
                throw new ArgumentException();
            }
            if (!NodeCanvasManager.CheckCanvasCompability(nodeID, hostCanvas.GetType()))
            {
                throw new UnityException("Cannot create Node with ID '" + nodeID + "' as it is not compatible with the current canavs type (" + hostCanvas.GetType().ToString() + ")!");
            }
            if (!hostCanvas.CanAddNode(nodeID))
            {
                throw new UnityException("Cannot create Node with ID '" + nodeID + "' on the current canvas of type (" + hostCanvas.GetType().ToString() + ")!");
            }

            // Create node from data
            NodeTypeData data = NodeTypes.getNodeData(nodeID);
            Node         node = (Node)CreateInstance(data.type);

            if (node == null)
            {
                return(null);
            }

            // Init node state
            node.name     = node.Title;
            node.autoSize = node.DefaultSize;
            node.position = pos;
            node.Canvas   = hostCanvas;
            ConnectionPortManager.UpdateConnectionPorts(node);
            if (init)
            {
                node.OnCreate();
            }

            if (connectingPort != null)
            {             // Handle auto-connection and link the output to the first compatible input
                for (int i = 0; i < node.connectionPorts.Count; i++)
                {
                    if (node.connectionPorts[i].TryApplyConnection(connectingPort, silent))
                    {
                        break;
                    }
                }
            }

            // Add node to host canvas
            hostCanvas.nodes.Add(node);
            if (!silent)
            {             // Callbacks
                hostCanvas.OnNodeChange(connectingPort != null ? connectingPort.body : node);
                NodeEditorCallbacks.IssueOnAddNode(node);
                hostCanvas.Validate();
                NodeEditor.RepaintClients();
            }

            return(node);
        }
Example #2
0
        private static void FillAddNodes(NodeEditorInputInfo inputInfo, GenericMenu canvasContextMenu)
        {         // Fill context menu with nodes to add to the canvas
            NodeEditorState state = inputInfo.editorState;
            List <string>   nodes = NodeTypes.getCompatibleNodes(state.connectKnob);

            foreach (string node in nodes)
            {             // Only add nodes to the context menu that are compatible
                if (NodeCanvasManager.CheckCanvasCompability(node, inputInfo.editorState.canvas.GetType()) && inputInfo.editorState.canvas.CanAddNode(node))
                {
                    canvasContextMenu.AddItem(new GUIContent("Add " + NodeTypes.getNodeData(node).adress), false, CreateNodeCallback, new NodeEditorInputInfo(node, state));
                }
            }
        }
Example #3
0
        public static Transition Create(Node from, Node to)
        {
            if (NodeTypes.getNodeData(from).transitions == false || NodeTypes.getNodeData(to).transitions == false)
            {
                return(null);
            }
            Transition transition = CreateInstance <Transition> ();

            transition.name       = "Transition " + from.name + "-" + to.name;
            transition.startNode  = from;
            transition.endNode    = to;
            transition.conditions = new List <Func <Transition, bool> > ();
            return(transition);
        }
Example #4
0
        public static Node MoveNext(Node node)
        {
            if (NodeTypes.getNodeData(node).transitions == false)
            {
                Debug.LogError("Node " + node.ToString() + " does not accept Transitions!");
                return(null);
            }

            for (int transCnt = 0; transCnt < node.transitions.Count; transCnt++)
            {
                if (node.transitions[transCnt].conditionsMet())
                {
                    return(node.transitions[transCnt].endNode);
                }
            }

            return(node);
        }
Example #5
0
        /// <summary>
        /// Checks whether the süecified nodeID is compatible with the given canvas type
        /// </summary>
        public static bool CheckCanvasCompability(string nodeID, Type canvasType)
        {
            NodeTypeData data = NodeTypes.getNodeData(nodeID);

            return(data.limitToCanvasTypes == null || data.limitToCanvasTypes.Length == 0 || data.limitToCanvasTypes.Contains(canvasType));
        }
Example #6
0
        /// <summary>
        /// Processes input events
        /// </summary>
        public static void InputEvents(List <Rect> ignoreInput)
        {
            Event e = Event.current;

            mousePos = e.mousePosition;

            if (OverlayGUI.HasPopupControl())
            {
                return;
            }

            bool insideCanvas = curEditorState.canvasRect.Contains(e.mousePosition);

            for (int ignoreCnt = 0; ignoreCnt < ignoreInput.Count; ignoreCnt++)
            {
                if (ignoreInput [ignoreCnt].Contains(e.mousePosition))
                {
                    insideCanvas = false;
                    break;
                }
            }

            if (!insideCanvas)
            {
                return;
            }

            curEditorState.focusedNode = null;
            if (insideCanvas && (e.type == EventType.MouseDown || e.type == EventType.MouseUp))
            {
                curEditorState.focusedNode = NodeEditor.NodeAtPosition(e.mousePosition);
                if (e.button == 0)
                {
                    curEditorState.activeNode = curEditorState.focusedNode;
                    if (Repaint != null)
                    {
                        Repaint();
                    }
                }
            }

        #if UNITY_EDITOR
            if (curEditorState.focusedNode != null)
            {
                UnityEditor.Selection.activeObject = curEditorState.focusedNode;
            }
        #endif

            switch (e.type)
            {
            case EventType.MouseDown:

                curEditorState.dragNode  = false;
                curEditorState.panWindow = false;

                if (curEditorState.focusedNode != null)
                {                 // A click on a node
                    if (e.button == 1)
                    {             // Right click -> Node Context Click
                        // TODO: Node Editor: Editor-Independancy - GenericMenu conversion
//	#if UNITY_EDITOR
//						UnityEditor.GenericMenu menu = new UnityEditor.GenericMenu ();
//	#else
                        GenericMenu menu = new GenericMenu();
//	#endif
                        menu.AddItem(new GUIContent("Delete Node"), false, ContextCallback, new callbackObject("deleteNode", curNodeCanvas, curEditorState));
                        menu.AddItem(new GUIContent("Duplicate Node"), false, ContextCallback, new callbackObject("duplicateNode", curNodeCanvas, curEditorState));
                        if (NodeTypes.getNodeData(curEditorState.focusedNode).transitions)
                        {
                            menu.AddSeparator("Seperator");
                            menu.AddItem(new GUIContent("Make Transition"), false, ContextCallback, new callbackObject("startTransition", curNodeCanvas, curEditorState));
                        }

                        menu.ShowAsContext();

                        e.Use();
                    }
                    else if (e.button == 0)
                    {
                        if (!GUIToScreenRect(curEditorState.focusedNode.rect).Contains(e.mousePosition))
                        {                         // Left click at node edges -> Check for clicked connections to edit
                            NodeOutput nodeOutput = curEditorState.focusedNode.GetOutputAtPos(e.mousePosition);
                            if (nodeOutput != null)
                            {                             // Output Node -> New Connection drawn from this
                                curEditorState.connectOutput = nodeOutput;
                                e.Use();
                            }
                            else
                            {                             // no output clicked, check input
                                NodeInput nodeInput = curEditorState.focusedNode.GetInputAtPos(e.mousePosition);
                                if (nodeInput != null && nodeInput.connection != null)
                                {                                 // Input node -> Loose and edit Connection
                                    curEditorState.connectOutput = nodeInput.connection;
                                    Node.RemoveConnection(nodeInput);
                                    e.Use();
                                }
                            }
                        }
                    }
                }
                else
                {                 // A click on the empty canvas
                    if (e.button == 2 || e.button == 0)
                    {             // Left/Middle Click -> Start scrolling
                        curEditorState.panWindow = true;
                        e.delta = Vector2.zero;
                    }
                    else if (e.button == 1)
                    {                     // Right click -> Editor Context Click
                        // TODO: Node Editor: Editor-Independancy - GenericMenu conversion
                        if (curEditorState.connectOutput != null || curEditorState.makeTransition != null)
                        {
//							#if UNITY_EDITOR
//							UnityEditor.GenericMenu menu = new UnityEditor.GenericMenu ();
//							#else
                            GenericMenu menu = new GenericMenu();
//							#endif

                            // Iterate through all compatible nodes
                            foreach (Node node in NodeTypes.nodes.Keys)
                            {
                                if (curEditorState.connectOutput != null)
                                {
                                    foreach (var input in node.Inputs)
                                    {
                                        if (input.type == curEditorState.connectOutput.type)
                                        {
                                            menu.AddItem(new GUIContent("Add " + NodeTypes.nodes[node].adress), false, ContextCallback, new callbackObject(node.GetID, curNodeCanvas, curEditorState));
                                            break;
                                        }
                                    }
                                }
                                else if (curEditorState.makeTransition != null && NodeTypes.nodes [node].transitions)
                                {
                                    menu.AddItem(new GUIContent("Add " + NodeTypes.nodes[node].adress), false, ContextCallback, new callbackObject(node.GetID, curNodeCanvas, curEditorState));
                                }
                            }

                            menu.ShowAsContext();
                        }
                        else
                        {
//							#if UNITY_EDITOR
//							UnityEditor.GenericMenu menu = new UnityEditor.GenericMenu ();
//							#else
                            GenericMenu menu = new GenericMenu();
//							#endif

                            foreach (Node node in NodeTypes.nodes.Keys)
                            {
                                menu.AddItem(new GUIContent("Add " + NodeTypes.nodes [node].adress), false, ContextCallback, new callbackObject(node.GetID, curNodeCanvas, curEditorState));
                            }

                            menu.ShowAsContext();
                        }
                        e.Use();
                    }
                }

                break;

            case EventType.MouseUp:

                if (curEditorState.focusedNode != null)
                {
                    if (curEditorState.makeTransition != null)
                    {
                        Node.CreateTransition(curEditorState.makeTransition, curEditorState.focusedNode);
                    }
                    else if (curEditorState.connectOutput != null)
                    {                     // Apply a connection if theres a clicked input
                        if (!curEditorState.focusedNode.Outputs.Contains(curEditorState.connectOutput))
                        {                 // If an input was clicked, it'll will now be connected
                            NodeInput clickedInput = curEditorState.focusedNode.GetInputAtPos(e.mousePosition);
                            if (Node.CanApplyConnection(curEditorState.connectOutput, clickedInput))
                            {                             // If it can connect (type is equals, it does not cause recursion, ...)
                                Node.ApplyConnection(curEditorState.connectOutput, clickedInput);
                            }
                        }
                        e.Use();
                    }
                }

                curEditorState.makeTransition = null;
                curEditorState.connectOutput  = null;
                curEditorState.dragNode       = false;
                curEditorState.panWindow      = false;

                break;

            case EventType.ScrollWheel:

                curEditorState.zoom = (float)Math.Round(Math.Min(2.0f, Math.Max(0.6f, curEditorState.zoom + e.delta.y / 15)), 2);
                if (Repaint != null)
                {
                    Repaint();
                }

                break;

            case EventType.KeyDown:

                // TODO: Node Editor: Shortcuts
                if (e.keyCode == KeyCode.N)                 // Start Navigating (curve to origin / active Node)
                {
                    curEditorState.navigate = true;
                }

                if (e.keyCode == KeyCode.LeftControl && curEditorState.activeNode != null)                 // Snap
                {
                    curEditorState.activeNode.rect.position = new Vector2(Mathf.RoundToInt((curEditorState.activeNode.rect.position.x - curEditorState.panOffset.x) / 10) * 10 + curEditorState.panOffset.x,
                                                                          Mathf.RoundToInt((curEditorState.activeNode.rect.position.y - curEditorState.panOffset.y) / 10) * 10 + curEditorState.panOffset.y);
                }
                if (Repaint != null)
                {
                    Repaint();
                }

                break;

            case EventType.KeyUp:

                if (e.keyCode == KeyCode.N)                 // Stop Navigating
                {
                    curEditorState.navigate = false;
                }

                if (Repaint != null)
                {
                    Repaint();
                }

                break;

            case EventType.MouseDrag:

                if (curEditorState.panWindow)
                {                 // Scroll everything with the current mouse delta
                    curEditorState.panOffset += e.delta * curEditorState.zoom;
                    for (int nodeCnt = 0; nodeCnt < curNodeCanvas.nodes.Count; nodeCnt++)
                    {
                        curNodeCanvas.nodes [nodeCnt].rect.position += e.delta * curEditorState.zoom;
                    }
                    e.delta = Vector2.zero;
                    if (Repaint != null)
                    {
                        Repaint();
                    }
                }
                else
                {
                    curEditorState.panWindow = false;
                }

                if (curEditorState.dragNode && curEditorState.activeNode != null && GUIUtility.hotControl == 0)
                {                 // Drag the active node with the current mouse delta
                    curEditorState.activeNode.rect.position += e.delta * curEditorState.zoom;
                    NodeEditorCallbacks.IssueOnMoveNode(curEditorState.activeNode);
                    e.delta = Vector2.zero;
                    if (Repaint != null)
                    {
                        Repaint();
                    }
                }
                else
                {
                    curEditorState.dragNode = false;
                }

                break;
            }
        }
Example #7
0
        /// <summary>
        /// Creates a node of the specified ID at pos on the specified canvas, optionally auto-connecting the specified output to a matching input
        /// silent disables any events, init specifies whether OnCreate should be called
        /// </summary>
        public static Node Create(string nodeID, Vector2 pos, NodeCanvas hostCanvas, ConnectionPort connectingPort = null, bool silent = false, bool init = true)
        {
            if (string.IsNullOrEmpty(nodeID) || hostCanvas == null)
            {
                throw new ArgumentException();
            }
            if (!NodeCanvasManager.CheckCanvasCompability(nodeID, hostCanvas.GetType()))
            {
                throw new UnityException("Cannot create Node with ID '" + nodeID + "' as it is not compatible with the current canavs type (" + hostCanvas.GetType().ToString() + ")!");
            }
            if (!hostCanvas.CanAddNode(nodeID))
            {
                throw new UnityException("Cannot create Node with ID '" + nodeID + "' on the current canvas of type (" + hostCanvas.GetType().ToString() + ")!");
            }

            // Create node from data
            NodeTypeData data = NodeTypes.getNodeData(nodeID);
            Node         node = (Node)CreateInstance(data.type);

            if (node == null)
            {
                return(null);
            }

            // Init node state
            node.canvas   = hostCanvas;
            node.name     = node.Title;
            node.autoSize = node.DefaultSize;
            node.position = pos;
            ConnectionPortManager.UpdateConnectionPorts(node);
            if (init)
            {
                node.OnCreate();
            }

            if (connectingPort != null)
            {             // Handle auto-connection and link the output to the first compatible input
                for (int i = 0; i < node.connectionPorts.Count; i++)
                {
                    if (node.connectionPorts[i].TryApplyConnection(connectingPort, true))
                    {
                        break;
                    }
                }
            }

            // Add node to host canvas
            hostCanvas.nodes.Add(node);
            if (!silent)
            {             // Callbacks
                hostCanvas.OnNodeChange(connectingPort != null ? connectingPort.body : node);
                NodeEditorCallbacks.IssueOnAddNode(node);
                hostCanvas.Validate();
                NodeEditor.RepaintClients();
            }

#if UNITY_EDITOR
            if (!silent)
            {
                List <ConnectionPort> connectedPorts = new List <ConnectionPort>();
                foreach (ConnectionPort port in node.connectionPorts)
                {                 // 'Encode' connected ports in one list (double level cannot be serialized)
                    foreach (ConnectionPort conn in port.connections)
                    {
                        connectedPorts.Add(conn);
                    }
                    connectedPorts.Add(null);
                }
                Node createdNode = node;
                UndoPro.UndoProManager.RecordOperation(
                    () => NodeEditorUndoActions.ReinstateNode(createdNode, connectedPorts),
                    () => NodeEditorUndoActions.RemoveNode(createdNode),
                    "Create Node");
                // Make sure the new node is in the memory dump
                NodeEditorUndoActions.CompleteSOMemoryDump(hostCanvas);
            }
#endif

            return(node);
        }