예제 #1
0
        /// <summary>
        /// Removes the connection of this port to the specified port if existant
        /// </summary>
        public void RemoveConnection(ConnectionPort port, bool silent = false)
        {
#if UNITY_EDITOR
            if (silent == false && port != null)
            {             // Undo record
                // Important: Copy variables used within anonymous functions within same level (this if block) for correct serialization!
                ConnectionPort port1 = this, port2 = port;
                UndoPro.UndoProManager.RecordOperation(
                    () => NodeEditorUndoActions.DeleteConnection(port1, port2),
                    () => NodeEditorUndoActions.CreateConnection(port1, port2),
                    "Delete Connection");
            }
#endif

            if (port == null)
            {
                Debug.LogWarning("Cannot delete null port!");
                //connections.RemoveAll (p => p != null);
                return;
            }

            if (!silent)
            {
                NodeEditorCallbacks.IssueOnRemoveConnection(this, port);
            }
            port.connections.Remove(this);
            connections.Remove(port);

            if (!silent)
            {
                body.canvas.OnNodeChange(body);
            }
        }
예제 #2
0
        [EventHandlerAttribute(EventType.MouseDown, -2)]          // Absolute second to call!
        private static void HandleSelecting(NodeEditorInputInfo inputInfo)
        {
            if (inputInfo.inputEvent.button == 0 && inputInfo.editorState.focusedNode != inputInfo.editorState.selectedNode)
            {             // Select focussed Node
                unfocusControlsForState            = inputInfo.editorState;
                inputInfo.editorState.selectedNode = inputInfo.editorState.focusedNode;
#if UNITY_EDITOR
                NodeEditorState state = inputInfo.editorState;
                Node            prevSelection = state.selectedNode, newSelection = state.focusedNode;
                UndoPro.UndoProManager.RecordOperation(
                    () => NodeEditorUndoActions.SetNodeSelection(state, newSelection),
                    () => NodeEditorUndoActions.SetNodeSelection(state, prevSelection),
                    "Node Selection", false, true);
#endif
            }
#if UNITY_EDITOR
            if (inputInfo.editorState.selectedNode != null)
            {
                UnityEditor.Selection.activeObject = inputInfo.editorState.selectedNode;
            }
            else if (UnityEditor.Selection.activeObject is Node)
            {
                UnityEditor.Selection.activeObject = inputInfo.editorState.canvas;
            }
#endif
        }
        [EventHandlerAttribute(EventType.MouseDown, -2)]          // Absolute second to call!
        private static void HandleSelecting(NodeEditorInputInfo inputInfo)
        {
            if (inputInfo.inputEvent.button == 0 && inputInfo.editorState.focusedNode != inputInfo.editorState.selectedNode)
            {             // Select focussed Node
                inputInfo.editorState.selectedNode = inputInfo.editorState.focusedNode;
#if UNITY_EDITOR
                NodeEditorState state = inputInfo.editorState;
                Node            prevSelection = state.selectedNode, newSelection = state.focusedNode;
                UndoPro.UndoProManager.RecordOperation(
                    () => NodeEditorUndoActions.SetNodeSelection(state, newSelection),
                    () => NodeEditorUndoActions.SetNodeSelection(state, prevSelection),
                    "Node Selection", false, true);
#endif
                // Make sure previous controls get unfocussed later, but except if control is in newly selected node
                unfocusControlsForState = inputInfo.editorState;
                unfocusControlsHot      = GUIUtility.hotControl;
                unfocusControlsKeyboard = GUIUtility.keyboardControl;
            }
#if UNITY_EDITOR
            if (inputInfo.editorState.selectedNode != null)
            {
                UnityEditor.Selection.activeObject = inputInfo.editorState.selectedNode;
            }
            else if (UnityEditor.Selection.activeObject is Node)
            {
                UnityEditor.Selection.activeObject = inputInfo.editorState.canvas;
            }
#endif
        }
        private static void HandleNodeDraggingEnd(NodeEditorInputInfo inputInfo)
        {
            if (inputInfo.editorState.dragUserID == "node")
            {
                Vector2 dragStart = inputInfo.editorState.dragObjectStart;
                Vector2 dragEnd   = inputInfo.editorState.EndDrag("node");
                if (inputInfo.editorState.dragNode && inputInfo.editorState.selectedNode)
                {
                    if ((dragStart - dragEnd).magnitude > 10)
                    {
                        inputInfo.editorState.selectedNode.position = dragEnd;
#if UNITY_EDITOR
                        // Important: Copy variables used within anonymous functions within same level (this if block) for correct serialization!
                        float prevX = dragStart.x, prevY = dragStart.y, newX = dragEnd.x, newY = dragEnd.y;
                        Node  draggedNode = inputInfo.editorState.selectedNode;
                        UndoPro.UndoProManager.RecordOperation(
                            () => NodeEditorUndoActions.SetNodePosition(draggedNode, new Vector2(newX, newY)),
                            () => NodeEditorUndoActions.SetNodePosition(draggedNode, new Vector2(prevX, prevY)),
                            "Node Drag", true, false);
#endif
                        NodeEditorCallbacks.IssueOnMoveNode(inputInfo.editorState.selectedNode);
                    }
                    else
                    {
                        inputInfo.editorState.selectedNode.position = dragStart;
                    }
                }
            }
            inputInfo.editorState.dragNode = false;
        }
예제 #5
0
        /// <summary>
        /// Deletes this Node from it's host canvas and the save file
        /// </summary>
        public void Delete(bool silent = false)
        {
            if (!canvas.nodes.Contains(this))
            {
                throw new UnityException("The Node " + name + " does not exist on the Canvas " + canvas.name + "!");
            }
            if (!silent)
            {
                NodeEditorCallbacks.IssueOnDeleteNode(this);
            }

#if UNITY_EDITOR
            if (!silent)
            {
                List <ConnectionPort> connectedPorts = new List <ConnectionPort>();
                foreach (ConnectionPort port in 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 deleteNode = this;
                UndoPro.UndoProManager.RecordOperation(
                    () => NodeEditorUndoActions.RemoveNode(deleteNode),
                    () => NodeEditorUndoActions.ReinstateNode(deleteNode, connectedPorts),
                    "Delete Node");
                // Make sure the deleted node is in the memory dump
                NodeEditorUndoActions.CompleteSOMemoryDump(canvas);
            }
#endif

            canvas.nodes.Remove(this);
            for (int i = 0; i < connectionPorts.Count; i++)
            {
                connectionPorts[i].ClearConnections(true);
            }

            if (!silent)
            {
                canvas.Validate();
            }
        }
예제 #6
0
        /// <summary>
        /// Saves the current canvas to the cache
        /// </summary>
        public void SaveCache(bool crashSafe = true)
        {
#if CACHE
            if (!useCache)
            {
                return;
            }
            if (!nodeCanvas || nodeCanvas.GetType() == typeof(NodeCanvas))
            {
                return;
            }
            UnityEditor.EditorUtility.SetDirty(nodeCanvas);
            if (editorState != null)
            {
                UnityEditor.EditorUtility.SetDirty(editorState);
            }
            lastCacheTime = UnityEditor.EditorApplication.timeSinceStartup;

            nodeCanvas.editorStates = new NodeEditorState[] { editorState };
            if (nodeCanvas.livesInScene || nodeCanvas.allowSceneSaveOnly)
            {
                NodeEditorSaveManager.SaveSceneNodeCanvas("lastSession", ref nodeCanvas, cacheWorkingCopy);
            }
            else if (crashSafe)
            {
                NodeEditorSaveManager.SaveNodeCanvas(lastSessionPath, ref nodeCanvas, cacheWorkingCopy, true);
            }

            if (cacheMemorySODump)
            {             // Functionality for asset saves only
                if (nodeCanvas.livesInScene || nodeCanvas.allowSceneSaveOnly)
                {         // Delete for scene save so that next cache load, correct lastSession is used
                    UnityEditor.AssetDatabase.DeleteAsset(SOMemoryDumpPath);
                }
                else
                {                 // Dump all SOs used in this session (even if deleted) in this file to keep them alive for undo
                    NodeEditorUndoActions.CompleteSOMemoryDump(nodeCanvas);
                    NodeEditorSaveManager.ScriptableObjectReferenceDump(nodeCanvas.SOMemoryDump, SOMemoryDumpPath, false);
                }
            }
#endif
        }
예제 #7
0
        /// <summary>
        /// Applies a connection between between this port and the specified port.
        /// 'CanApplyConnection' has to be checked before to avoid interferences!
        /// </summary>
        public void ApplyConnection(ConnectionPort port, bool silent = false)
        {
            if (port == null)
            {
                return;
            }

            if (maxConnectionCount == ConnectionCount.Single && connections.Count > 0)
            {             // Respect maximum connection count on this port
                RemoveConnection(connections[0], silent);
                connections.Clear();
            }
            connections.Add(port);

            if (port.maxConnectionCount == ConnectionCount.Single && port.connections.Count > 0)
            {             // Respect maximum connection count on the other port
                port.RemoveConnection(port.connections[0], silent);
                port.connections.Clear();
            }
            port.connections.Add(this);

#if UNITY_EDITOR
            if (!silent)
            {             // Create Undo record
                          // Important: Copy variables used within anonymous functions within same level (this if block) for correct serialization!
                ConnectionPort port1 = this, port2 = port;
                UndoPro.UndoProManager.RecordOperation(
                    () => NodeEditorUndoActions.CreateConnection(port1, port2),
                    () => NodeEditorUndoActions.DeleteConnection(port1, port2),
                    "Create Connection");
            }
#endif

            if (!silent)
            {             // Callbacks
                port.body.OnAddConnection(port, this);
                body.OnAddConnection(this, port);
                NodeEditorCallbacks.IssueOnAddConnection(this, port);
                body.canvas.OnNodeChange(direction == Direction.In? port.body : body);
            }
        }
예제 #8
0
        /// <summary>
        /// Loads the mainNodeCanvas and it's associated mainEditorState from an asset at path
        /// </summary>
        public void LoadNodeCanvas(string path)
        {
            // Try to load the NodeCanvas
            if (!File.Exists(path) || (nodeCanvas = NodeEditorSaveManager.LoadNodeCanvas(path, true)) == null)
            {
                NewNodeCanvas();
                return;
            }
            editorState = NodeEditorSaveManager.ExtractEditorState(nodeCanvas, MainEditorStateIdentifier);

            openedCanvasPath = path;
            nodeCanvas.Validate();
            RecreateCache();
            UpdateCanvasInfo();
            nodeCanvas.TraverseAll();
            NodeEditor.RepaintClients();

#if UNITY_EDITOR
            UnityEditor.AssetDatabase.DeleteAsset(SOMemoryDumpPath);
            NodeEditorUndoActions.CompleteSOMemoryDump(nodeCanvas);
#endif
        }
예제 #9
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);
        }