protected override void OnDestroy() { base.OnDestroy(); DeselectCurrentGraphOrAnyOfItsNodes(); WindowSettings.SetDirty(true); Undo.ClearAll(); }
private void DeselectAll(bool recordUndo) { if (recordUndo) { RecordUndo(GraphAction.DeselectAll.ToString()); } WindowSettings.SelectedNodes.Clear(); UpdateNodesSelectedState(WindowSettings.SelectedNodes); Selection.activeObject = CurrentGraph; WindowSettings.SetDirty(false); }
private void SelectAll(bool recordUndo) { if (recordUndo) { RecordUndo(GraphAction.SelectAll.ToString()); } WindowSettings.SelectedNodes.Clear(); WindowSettings.SelectedNodes.AddRange(CurrentGraph.Nodes); UpdateNodesSelectedState(WindowSettings.SelectedNodes); DGUI.Utility.SelectObjectsInInspector(WindowSettings.SelectedNodes.ToArray()); WindowSettings.SetDirty(false); }
private void SoftDeleteNode(Node node, bool recordUndo, bool saveAssets) { if (!node.CanBeDeleted) { return; } switch (node.NodeType) { case NodeType.Start: case NodeType.Enter: case NodeType.Exit: return; } if (recordUndo) { RecordUndo("Delete Node"); } foreach (VirtualConnection connection in ConnectionsDatabase.Values) { if (connection.InputNode == node) { connection.OutputSocket.DisconnectFromNode(node.Id); EditorUtility.SetDirty(connection.OutputNode); } if (connection.OutputNode == node) { connection.InputSocket.DisconnectFromNode(node.Id); EditorUtility.SetDirty(connection.InputNode); } } WindowSettings.DeletedNodes.Add(node); CurrentGraph.Nodes.Remove(node); if (WindowSettings.SelectedNodes.Contains(node)) { WindowSettings.SelectedNodes.Remove(node); } CurrentGraph.SetDirty(saveAssets); WindowSettings.SetDirty(false); ConstructGraphGUI(); }
private void CreateNodeInTheOpenedGraph(Type type, Vector2 worldPosition, bool recordUndo, bool saveAssets = false) { Node node = GraphUtils.CreateNode(CurrentGraph, type, worldPosition); if (recordUndo) { RecordUndo("Create " + type.Name); //record undo for the creation of this node } CurrentGraph.Nodes.Add(node); //add the new node reference to the graph's nodes list if (!EditorUtility.IsPersistent(node)) { AssetDatabase.AddObjectToAsset(node, CurrentGraph); //if the node does not have an asset file -> crete it and nest it under the graph asset file } switch (node.NodeType) { case NodeType.General: case NodeType.SubGraph: //AUTO CONNECT the new node TO either the START or ENTER node - if the start or enter nodes are not connected Node startOrEnterNode = CurrentGraph.GetStartOrEnterNode(); if (startOrEnterNode != null && //if we have a start or enter node !startOrEnterNode.OutputSockets[0].IsConnected && //that is NOT connected node.InputSockets != null && //and its inputSockets list is NOT null (sanity check) node.InputSockets.Count > 0) //and it has at least one input socket (again... sanity check) { ConnectSockets(startOrEnterNode.OutputSockets[0], node.InputSockets[0]); //connect the new created node with the Start or Enter node } break; } EditorUtility.SetDirty(node); //mark the new node as dirty CurrentGraph.SetDirty(saveAssets); //set the graph dirty if (recordUndo) { GraphEvent.Send(GraphEvent.EventType.EVENT_NODE_CREATED); //notify the system the a node has been created } SelectNodes(new List <Node> { node }, false, false); //select the newly created node WindowSettings.SetDirty(false); }
private static void CopyNodes(List <Node> nodes) { if (nodes == null) { return; } WindowSettings.CopiedNodes.Clear(); WindowSettings.SetDirty(false); foreach (Node node in nodes) { switch (node.NodeType) { case NodeType.Start: case NodeType.Enter: case NodeType.Exit: continue; } WindowSettings.CopiedNodes.Add(node); } }
private static void DeleteUnreferencedAssetNodes() { if (CurrentGraph == null) { return; //check that the graph is not null } Object[] objects = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(CurrentGraph)); //load all of the graph sub assets if (objects == null) { return; //make sure they are not null } List <Node> foundNodes = objects.OfType <Node>().ToList(); //create a temp list of all the found sub assets node if (CurrentGraph.Nodes == null) { CurrentGraph.Nodes = new List <Node>(); //sanity check } bool saveGraph = false; //mark true if any sub asset was destroyed foreach (Node node in foundNodes) { if (CurrentGraph.Nodes.Contains(node)) { continue; //node reference was FOUND in the Nodes list -> continue } DestroyImmediate(node, true); //node reference was NOT FOUND in the Nodes list -> destroy the asset (it was probably soft deleted) saveGraph = true; //mark true in order to set the graph dirty and save it } WindowSettings.DeletedNodes.Clear(); if (!saveGraph) { return; //if no sub asset was destroyed -> stop here } WindowSettings.SetDirty(false); CurrentGraph.SetDirty(true); //save the graph }
private void SoftDeleteNodes(List <Node> nodes, bool recordUndo, bool saveAssets) { if (nodes == null || nodes.Count == 0) { return; } nodes = nodes.Where(n => n != null).ToList(); if (recordUndo) { RecordUndo("Delete Nodes"); } //disconnect all the nodes that need to be deleted foreach (Node node in nodes) { if (!CanDeleteNode(node)) { continue; } foreach (VirtualConnection connection in ConnectionsDatabase.Values) { if (node == null || connection == null) { continue; } if (connection.InputNode == node && connection.OutputSocket != null) { connection.OutputSocket.DisconnectFromNode(node.Id); EditorUtility.SetDirty(connection.OutputNode); } if (connection.OutputNode == node && connection.InputSocket != null) { connection.InputSocket.DisconnectFromNode(node.Id); EditorUtility.SetDirty(connection.InputNode); } } } //at this point the nodes have been disconnected //'delete' the nodes by adding them the the DeletedNodes list foreach (Node node in nodes) { if (node == null) { continue; } if (!CanDeleteNode(node)) { continue; } WindowSettings.DeletedNodes.Add(node); CurrentGraph.Nodes.Remove(node); } DeselectAll(false); //deselect any selected nodes CurrentGraph.SetDirty(saveAssets); //mark the graph as dirty WindowSettings.SetDirty(false); //mark the editor settings as dirty ConstructGraphGUI(); //invalidate all the databases and reconstruct the GUI }
private void PasteNodes() { if (!WindowSettings.CanPasteNodes) { return; //paste operation cannot work if no nodes have been added to the 'virtual clipboard' } for (int i = WindowSettings.CopiedNodes.Count - 1; i >= 0; i--) //remove any null nodes { if (WindowSettings.CopiedNodes[i] == null) { WindowSettings.CopiedNodes.RemoveAt(i); } } if (!WindowSettings.CanPasteNodes) { return; //paste operation cannot work if no not null nodes are left to be copied } //create current nodes list var copyNodes = new List <Node>(); //get the first node to the left Node firstNodeToTheLeft = null; Vector2 firstNodePosition = Vector2.zero; foreach (Node node in WindowSettings.CopiedNodes) { if (node == null) { continue; } if (firstNodeToTheLeft == null) { firstNodeToTheLeft = node; firstNodePosition = node.GetPosition(); } if (!(node.GetX() < firstNodePosition.x)) { continue; } firstNodeToTheLeft = node; firstNodePosition = node.GetPosition(); } foreach (Node node in WindowSettings.CopiedNodes) { Node original = node; if (original == null) { continue; } Node copy = CreateNodeCopy(original); copy.hideFlags = original.hideFlags; Vector2 offsetFromFirstNodePosition = Vector2.zero; if (original != firstNodeToTheLeft) { offsetFromFirstNodePosition = firstNodePosition - copy.GetPosition(); } copy.SetPosition(WorldToGridPosition(CurrentMousePosition)); copy.SetPosition(copy.GetPosition() - new Vector2(copy.GetWidth() / 2, NodySettings.Instance.NodeHeaderHeight / 2)); copy.SetPosition(copy.GetPosition() - offsetFromFirstNodePosition); copyNodes.Add(copy); if (!EditorUtility.IsPersistent(copy)) { AssetDatabase.AddObjectToAsset(copy, CurrentGraph); } CurrentGraph.SetDirty(false); } //create current sockets list var copySockets = new List <Socket>(); foreach (Node copyNode in copyNodes) { copySockets.AddRange(copyNode.InputSockets); copySockets.AddRange(copyNode.OutputSockets); } //create current connections list var copyConnections = new List <Connection>(); foreach (Socket copySocket in copySockets) { foreach (Connection copyConnection in copySocket.Connections) { copyConnections.Add(copyConnection); } } //generate new connection ids foreach (Connection copyConnection in copyConnections) { string oldConnectionId = copyConnection.Id; //save previous connection id string newConnectionId = copyConnection.GenerateNewId(); //save new conenction id foreach (Socket socket in copySockets) //go through each socket { foreach (Connection socketConnection in socket.Connections) //go through each socket's connections { if (socketConnection.Id == oldConnectionId) { socketConnection.Id = newConnectionId; //update the connection id } } } } //generate new socket ids foreach (Socket copySocket in copySockets) { string oldSocketId = copySocket.Id; //save previous socket id string newSocketId = copySocket.GenerateNewId(); //save new socket id foreach (Connection connection in copyConnections) //update all the connection socket ids { if (connection.InputSocketId == oldSocketId) { connection.InputSocketId = newSocketId; } if (connection.OutputSocketId == oldSocketId) { connection.OutputSocketId = newSocketId; } } } //generate new node ids foreach (Node copyNode in copyNodes) { string oldNodeId = copyNode.Id; //save previous node id string newNodeId = copyNode.GenerateNewId(); //save new node id foreach (Socket copySocket in copySockets) //go through all the sockets { if (copySocket.NodeId == oldNodeId) //check that the current node id is equal the the old node id { copySocket.NodeId = newNodeId; //update the node id } foreach (Connection copyConnection in copySocket.Connections) //update all the connection node ids { if (copyConnection.OutputNodeId == oldNodeId) { copyConnection.OutputNodeId = newNodeId; } if (copyConnection.InputNodeId == oldNodeId) { copyConnection.InputNodeId = newNodeId; } } } } //a list of all the copied nodes ids is needed in order to be able to keep the connections between the copied nodes and remove any 'outside' connections var copiedNodesIds = new List <string>(); //create a list of all the copied nodes ids (list contains the newly generated ids) foreach (Node copyNode in copyNodes) { copiedNodesIds.Add(copyNode.Id); } foreach (Socket copySocket in copySockets) { for (int i = copySocket.Connections.Count - 1; i >= 0; i--) { Connection c = copySocket.Connections[i]; //remove any connection that is made with a node outside the copied nodes list //keep the connections between the copied nodes and remove any 'outside' connections if (copiedNodesIds.Contains(c.InputNodeId) && copiedNodesIds.Contains(c.OutputNodeId)) { continue; } copySocket.Connections.RemoveAt(i); } } //record undo for paste RecordUndo("Paste Nodes"); //add the references of the pasted nodes to the graph's nodes list //do it in reverse order in order to be sorted on top of all the other nodes var nodesList = new List <Node>(copyNodes); nodesList.AddRange(CurrentGraph.Nodes); CurrentGraph.Nodes = nodesList; //add the node asset files under the graph asset foreach (Node copiedNode in copyNodes) { if (!EditorUtility.IsPersistent(copiedNode)) { AssetDatabase.AddObjectToAsset(copiedNode, CurrentGraph); } EditorUtility.SetDirty(copiedNode); } //mark the graph as dirty in order to be able to save the changes CurrentGraph.SetDirty(false); //reconstruct the databases in order to draw ConstructGraphGUI(); RecalculateAllPointRects(); //Select the pasted nodes SelectNodes(copyNodes, false, false); //Paste completed -> clear clipboard WindowSettings.CopiedNodes.Clear(); WindowSettings.SetDirty(false); }
public void CloseCurrentGraph(bool clearGraphTabs = true, bool recordUndo = true) { if (CurrentGraph == null) { return; } if (recordUndo) { RecordUndo("Close Graph"); } if (Selection.activeObject == CurrentGraph) //check if the graph asset is selected in the Inspector -> if it is -> deselect the graph { Selection.activeObject = null; } else { foreach (Node node in CurrentGraph.Nodes) //the graph was not selected in the Inspector -> check each node { if (Selection.activeObject != node) { continue; } Selection.activeObject = null; //one of the graph's nodes was selected in the Inspector -> deselect the node break; } } // int undoGroupIndex = Undo.GetCurrentGroup() - 1; // if (undoGroupIndex < 0) undoGroupIndex = 0; // Undo.CollapseUndoOperations(undoGroupIndex); ResetZoom(); ResetPanOffset(); WindowSettings.SelectedNodes.Clear(); for (int i = CurrentGraph.Nodes.Count - 1; i >= 0; i--) { Node node = CurrentGraph.Nodes[i]; if (WindowSettings.DeletedNodes.Contains(node)) { CurrentGraph.Nodes.RemoveAt(i); } } WindowSettings.DeletedNodes.Clear(); DeleteUnreferencedAssetNodes(); CurrentGraph = null; SetView(View.General); InvalidateDatabases(); if (!clearGraphTabs) { return; } WindowSettings.GraphTabs.Clear(); WindowSettings.SetDirty(false); }