public override void OnProcess(Event e) { if (m_menu != null) { m_menu.ShowAsContext(); m_menu = null; } if (e.IsMouseDown(MouseButton.Right) && e.IsMouseInsideRect(canvas.unscaledRect)) { for (int i = 0; i < canvas.nodes.Length; i++) { Node currentNode = canvas.nodes[i]; if (currentNode.isHidden) { continue; } if (currentNode.rect.Contains(canvas.mousePosition)) { for (int j = 0; j < currentNode.ports.Length; j++) { if (currentNode.ports[j].rect.Contains(canvas.mousePosition)) { return; } } m_menu = new GenericMenu(); // save variables Node node = currentNode; AIController controller = graph.controller; NodeRestoreData restoreData = Serializer.CreateNodeRestoreData(node); // Add remove item if its not entry or any state. // Else add disabled remove item. if (node.IsEntryState() || node.IsAnyState()) { m_menu.AddDisabledItem(new GUIContent("Delete"), false); } else { m_menu.AddItem(new GUIContent("Delete"), false, () => { GraphUndo.RecordAndPerform("Delete node [" + node.name + "]", () => { Serializer.RemoveNodeFromController(controller, node, false); }, () => { Serializer.RestoreNodeToController(controller, node, restoreData); }); }); } // Add remove all connections item if the node has connections. // Else add disabled remove all connections item. // calculate connection count and save old connections. int connectionsCount = 0; Dictionary <ConnectionPort, ConnectionPort[]> oldConnections = new Dictionary <ConnectionPort, ConnectionPort[]> (); foreach (ConnectionPort port in node.ports) { connectionsCount += port.connectionCount; oldConnections.Add(port, port.connectedPorts); } string itemName = connectionsCount > 1 ? "Remove all connections" : "Remove connection"; if (connectionsCount == 0) { m_menu.AddDisabledItem(new GUIContent(itemName), false); } else { m_menu.AddItem(new GUIContent(itemName), false, () => { GraphUndo.RecordAndPerform(itemName + " from node [" + node.name + "]", () => { Serializer.DisconnectAllPorts(node); }, () => { foreach (ConnectionPort fromPort in oldConnections.Keys) { foreach (ConnectionPort toPort in oldConnections[fromPort]) { Serializer.ConnectPorts(fromPort, toPort); } } }); }); } e.Use(); } } } }
/// <summary> /// Remove the given node from the given controller. /// </summary> /// <param name="destroyImmediate">If it's set to true, the node and all of its scriptableObject-Assets will be removed immediate. A re-add </param> public static NodeRestoreData RemoveNodeFromController(AIController controller, Node node, bool destroyImmediate = false, bool autoSave = true) { NodeRestoreData nodeRestoreData = null; if (!destroyImmediate) { nodeRestoreData = CreateNodeRestoreData(node); } // unbind exposed parameters. foreach (ExposedParameter exposedParameter in controller.exposedParameters) { if (exposedParameter.ContainsBoundedNode(node)) { exposedParameter.Unbind(node); #if SERIALIZER_DEBUG Debug.Log("Unbind [" + node.name + " from the exposed parameter [" + exposedParameter.name + "]"); #endif } } // unbind node parameters. foreach (NodeParameter nodeParameter in controller.nodeParameters) { if (nodeParameter.ContainsBoundedNode(node)) { nodeParameter.Unbind(node); #if SERIALIZER_DEBUG Debug.Log("Unbind [" + node.name + " from the node parameter [" + nodeParameter.name + "]"); #endif } } // disconnect all ports Serializer.DisconnectAllPorts(node, false); // remove from controller. controller.RemoveNode(node); node.controller = null; #if SERIALIZER_DEBUG Debug.Log("Node [" + node.name + "] removed from the controller [" + controller.name + "]"); #endif if (destroyImmediate) { foreach (ScriptableObject scriptableObject in node.GetScriptableObjects()) { if (scriptableObject != null) { #if SERIALIZER_DEBUG Debug.Log(scriptableObject.GetType().Name + " [" + scriptableObject.name + "] destroyed"); #endif Object.DestroyImmediate(scriptableObject, true); } else { #if SERIALIZER_DEBUG Debug.Log(scriptableObject + " is null"); #endif Object.DestroyImmediate(scriptableObject, true); } } #if SERIALIZER_DEBUG Debug.Log("Node [" + node.name + "] destroyed"); #endif Object.DestroyImmediate(node, true); Save(); return(null); } if (autoSave) { Save(); } controller.isDirty = true; return(nodeRestoreData); }
/// <summary> /// Creates a restore data object of the given node. /// </summary> public static NodeRestoreData CreateNodeRestoreData(Node node) { return(NodeRestoreData.Create(node)); }
/// <summary> /// Add the given node to the given controller. /// Can only be used, if the node was already in the given controller. /// </summary> public static void RestoreNodeToController(AIController controller, Node node, NodeRestoreData nodeRestoreData, bool autoSave = true) { if (!node.IsSubAssetOf(controller)) { Debug.LogError("The node [" + node.name + "] was never in the given controller [" + controller.name + "]"); return; } foreach (ScriptableObject scriptableObject in node.GetScriptableObjects()) { if (!scriptableObject.IsSubAssetOf(controller)) { Debug.LogError("The node [" + node.name + "] that should re-add has ScriptableObjects that are no sub assets of the given controller [" + controller.name + "]"); return; } } controller.AddNode(node); node.controller = controller; if (nodeRestoreData != null) { if (nodeRestoreData.restoredNode == node) { #if SERIALIZER_DEBUG Debug.Log("Restore exposed parameter"); #endif foreach (NodeRestoreData.ExposedParameterRestoreData restoreData in nodeRestoreData.exposedParameters) { if (restoreData.parameterReference.type == restoreData.type) { restoreData.parameterReference.Bind(node, restoreData.parameterReference.type); } else { #if SERIALIZER_DEBUG Debug.Log("The Exposed Parameter [" + restoreData.parameterReference.name + "] has now a different bound type now: [" + restoreData.parameterReference.type + "] before: [" + restoreData.type + "]"); #endif } } #if SERIALIZER_DEBUG Debug.Log("Restore node parameter"); #endif foreach (NodeRestoreData.NodeParameterRestoreData restoreData in nodeRestoreData.nodeParameters) { if (restoreData.parameterReference.type == restoreData.type) { restoreData.parameterReference.Bind(node, restoreData.parameterReference.type); } else { #if SERIALIZER_DEBUG Debug.Log("The Node Parameter [" + restoreData.parameterReference.name + "] has now a different bound type now: [" + restoreData.parameterReference.type + "] before: [" + restoreData.type + "]"); #endif } } #if SERIALIZER_DEBUG Debug.Log("Restore connections"); #endif foreach (ConnectionPort fromPort in nodeRestoreData.ports) { ConnectionPort[] lastConnectedPorts = nodeRestoreData.GetConnectedPorts(fromPort); foreach (ConnectionPort toPort in lastConnectedPorts) { ConnectPorts(fromPort, toPort, false); } } } else { Debug.LogWarning("The given NodeRestoreData is not compatible with the given node [" + node.name + "]"); } } #if SERIALIZER_DEBUG Debug.Log("Node [" + node.name + " added again to the given controller [" + controller.name + "]"); #endif if (autoSave) { Save(); } controller.isDirty = true; }