/// <summary> /// Create the a Node of the type specified by the nodeID at position /// Auto-connects the passed connectingOutput if not null to the first compatible input /// </summary> public static Node Create(string nodeID, Vector2 position, NodeOutput connectingOutput) { Node node = NodeTypes.getDefaultNode(nodeID); if (node == null) { throw new UnityException("Cannot create Node with id " + nodeID + " as no such Node type is registered!"); } node = node.Create(position); node.InitBase(); if (connectingOutput != null) { // Handle auto-connection and link the output to the first compatible input foreach (NodeInput input in node.Inputs) { if (input.TryApplyConnection(connectingOutput)) { break; } } } NodeEditorCallbacks.IssueOnAddNode(node); return(node); }
/// <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); } }
/// <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); } // DestroyImmediate(this, true); this.canvas.nodesForDelete.Add(this); canvas.nodes.Remove(this); for (int i = 0; i < connectionPorts.Count; i++) { connectionPorts[i].ClearConnections(silent); //DestroyImmediate(connectionPorts[i], true); } if (!silent) { canvas.Validate(); } }
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 != null && (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; }
/// <summary> /// Deletes this Transition from the Nodes /// </summary> public void Delete() { NodeEditorCallbacks.IssueOnRemoveTransition(this); startNode.transitions.Remove(this); endNode.transitions.Remove(this); UnityEngine.Object.DestroyImmediate(this, true); }
/// <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 (!silent) { // Callbacks port.body.OnAddConnection(port, this); body.OnAddConnection(this, port); NodeEditorCallbacks.IssueOnAddConnection(this, port); NodeEditor.curNodeCanvas.OnNodeChange(direction == Direction.In? port.body : body); } }
/// <summary> /// Loads the NodeCanvas from the asset file at path and optionally creates a working copy of it before returning /// </summary> public static NodeCanvas LoadNodeCanvas(string path, bool createWorkingCopy) { if (!File.Exists(path)) { throw new UnityException("Cannot Load NodeCanvas: File '" + path + "' deos not exist!"); } // Load only the NodeCanvas from the save file NodeCanvas nodeCanvas = ResourceManager.LoadResource <NodeCanvas> (path); if (nodeCanvas == null) { throw new UnityException("Cannot Load NodeCanvas: The file at the specified path '" + path + "' is no valid save file as it does not contain a NodeCanvas!"); } #if UNITY_EDITOR if (!Application.isPlaying && (nodeCanvas.editorStates == null || nodeCanvas.editorStates.Length == 0)) { // Try to load any contained editorStates, possibly old format that did not references the states in the canvas nodeCanvas.editorStates = ResourceManager.LoadResources <NodeEditorState> (path); } #endif // Postprocess the loaded canvas ProcessCanvas(ref nodeCanvas, createWorkingCopy); #if UNITY_EDITOR UnityEditor.AssetDatabase.Refresh(); #endif NodeEditorCallbacks.IssueOnLoadCanvas(nodeCanvas); return(nodeCanvas); }
/// <summary> /// Saves the the specified NodeCanvas as a new asset at path, optionally as a working copy and overwriting any existing save at path /// </summary> public static void SaveNodeCanvas(string path, ref NodeCanvas nodeCanvas) { if (string.IsNullOrEmpty(path)) { throw new System.ArgumentNullException("Cannot save NodeCanvas: No path specified!"); } if (nodeCanvas == null) { throw new System.ArgumentNullException("Cannot save NodeCanvas: The specified NodeCanvas that should be saved to path '" + path + "' is null!"); } if (nodeCanvas.GetType() == typeof(NodeCanvas)) { throw new System.ArgumentException( "Cannot save NodeCanvas: The NodeCanvas has no explicit type! Please convert it to a valid sub-type of NodeCanvas!"); } nodeCanvas.Validate(); if (!UnityEditor.AssetDatabase.Contains(nodeCanvas)) { UnityEditor.AssetDatabase.CreateAsset(nodeCanvas, path); } PurifyCanvas(path); UnityEditor.AssetDatabase.SaveAssets(); UnityEditor.AssetDatabase.Refresh(); NodeEditorCallbacks.IssueOnSaveCanvas(nodeCanvas); }
/// <summary> /// Deletes this Node from curNodeCanvas and the save file /// </summary> public void Delete() { if (!NodeEditor.curNodeCanvas.nodes.Contains(this)) { throw new UnityException("The Node " + name + " does not exist on the Canvas " + NodeEditor.curNodeCanvas.name + "!"); } NodeEditorCallbacks.IssueOnDeleteNode(this); NodeEditor.curNodeCanvas.nodes.Remove(this); for (int outCnt = 0; outCnt < Outputs.Count; outCnt++) { NodeOutput output = Outputs [outCnt]; while (output.connections.Count != 0) { output.connections[0].RemoveConnection(); } DestroyImmediate(output, true); } for (int inCnt = 0; inCnt < Inputs.Count; inCnt++) { NodeInput input = Inputs [inCnt]; if (input.connection != null) { input.connection.connections.Remove(input); } DestroyImmediate(input, true); } for (int knobCnt = 0; knobCnt < nodeKnobs.Count; knobCnt++) { // Inputs/Outputs need specific treatment, unfortunately if (nodeKnobs[knobCnt] != null) { DestroyImmediate(nodeKnobs[knobCnt], true); } } DestroyImmediate(this, true); }
/// <summary> /// Applies a connection between the passed NodeOutput and this NodeInput. 'CanApplyConnection' has to be checked before to avoid interferences! /// </summary> public void ApplyConnection(NodeOutput output) { if (output == null) { return; } if (connection != null) { NodeEditorCallbacks.IssueOnRemoveConnection(this); connection.connections.Remove(this); } connection = output; output.connections.Add(this); if (!output.body.calculated) { NodeEditor.RecalculateFrom(output.body); } else { NodeEditor.RecalculateFrom(body); } output.body.OnAddOutputConnection(output); body.OnAddInputConnection(this); NodeEditorCallbacks.IssueOnAddConnection(this); }
/// <summary> /// Setup of the base framework. Enough to manage and calculate canvases. /// </summary> private static void setupBaseFramework() { CheckEditorPath(); // Init Resource system. Can be called anywhere else, too, if it's needed before. ResourceManager.SetDefaultResourcePath(editorPath + "Resources/"); // Run fetching algorithms searching the script assemblies for Custom Nodes / Connection Types / NodeCanvas Types ConnectionPortStyles.FetchConnectionPortStyles(); NodeTypes.FetchNodeTypes(); NodeCanvasManager.FetchCanvasTypes(); ConnectionPortManager.FetchNodeConnectionDeclarations(); ImportExportManager.FetchIOFormats(); // Setup Callback system NodeEditorCallbacks.SetupReceivers(); NodeEditorCallbacks.IssueOnEditorStartUp(); // Init input NodeEditorInputSystem.SetupInput(); #if UNITY_EDITOR UnityEditor.EditorApplication.update -= Update; UnityEditor.EditorApplication.update += Update; #endif initiatedBase = true; }
/// <summary> /// Deletes this Node from curNodeCanvas. Depends on that. /// </summary> public void Delete() { NodeEditor.curNodeCanvas.nodes.Remove(this); for (int outCnt = 0; outCnt < Outputs.Count; outCnt++) { NodeOutput output = Outputs [outCnt]; for (int conCnt = 0; conCnt < output.connections.Count; conCnt++) { output.connections [outCnt].connection = null; } DestroyImmediate(output, true); } for (int inCnt = 0; inCnt < Inputs.Count; inCnt++) { NodeInput input = Inputs [inCnt]; if (input.connection != null) { input.connection.connections.Remove(input); } DestroyImmediate(input, true); } DestroyImmediate(this, true); #if UNITY_EDITOR if (!String.IsNullOrEmpty(UnityEditor.AssetDatabase.GetAssetPath(NodeEditor.curNodeCanvas))) { UnityEditor.AssetDatabase.ImportAsset(UnityEditor.AssetDatabase.GetAssetPath(NodeEditor.curNodeCanvas)); } #endif NodeEditorCallbacks.IssueOnDeleteNode(this); }
/// <summary> /// Removes the connection from NodeInput. /// </summary> public static void RemoveConnection(NodeInput input) { NodeEditorCallbacks.IssueOnRemoveConnection(input); input.connection.connections.Remove(input); input.connection = null; NodeEditor.RecalculateFrom(input.body); }
/// <summary> /// Saves the the given NodeCanvas along with the given NodeEditorStates if specified as a new asset, optionally as working copies /// </summary> public static void SaveNodeCanvas(string path, NodeCanvas nodeCanvas, bool createWorkingCopy) { #if !UNITY_EDITOR throw new System.NotImplementedException(); #endif if (string.IsNullOrEmpty(path)) { throw new UnityException("Cannot save NodeCanvas: No spath specified to save the NodeCanvas " + (nodeCanvas != null? nodeCanvas.name : "") + " to!"); } if (nodeCanvas == null) { throw new UnityException("Cannot save NodeCanvas: The specified NodeCanvas that should be saved to path " + path + " is null!"); } if (nodeCanvas.livesInScene) { Debug.LogWarning("Attempting to save scene canvas " + nodeCanvas.name + " to an asset, scene object references will be broken!" + (!createWorkingCopy? " No workingCopy is going to be created, so your scene save is broken, too!" : "")); } #if UNITY_EDITOR if (!createWorkingCopy && UnityEditor.AssetDatabase.Contains(nodeCanvas) && UnityEditor.AssetDatabase.GetAssetPath(nodeCanvas) != path) { Debug.LogError("Trying to create a duplicate save file for '" + nodeCanvas.name + "'! Forcing to create a working copy!"); createWorkingCopy = true; } #endif nodeCanvas.livesInScene = false; nodeCanvas.Validate(); #if UNITY_EDITOR // Preprocess the canvas if (createWorkingCopy) { nodeCanvas = CreateWorkingCopy(nodeCanvas, true); Compress(ref nodeCanvas); } // Write canvas and editorStates UnityEditor.AssetDatabase.CreateAsset(nodeCanvas, path); AddSubAssets(nodeCanvas.editorStates, nodeCanvas); // Write nodes + contents foreach (Node node in nodeCanvas.nodes) { // Write node and additional scriptable objects AddSubAsset(node, nodeCanvas); AddSubAssets(node.GetScriptableObjects(), node); foreach (NodeKnob knob in node.nodeKnobs) { // Write knobs and their additional scriptable objects AddSubAsset(knob, node); AddSubAssets(knob.GetScriptableObjects(), knob); } } UnityEditor.AssetDatabase.SaveAssets(); UnityEditor.AssetDatabase.Refresh(); #else // TODO: Node Editor: Need to implement ingame-saving (Resources, AsssetBundles, ... won't work) #endif NodeEditorCallbacks.IssueOnSaveCanvas(nodeCanvas); }
private static void HandleNodeDragging(NodeEditorInputInfo inputInfo) { NodeEditorState state = inputInfo.editorState; if (state.dragNode) { // If conditions apply, drag the selected node, else disable dragging if (state.selectedNode != null && GUIUtility.hotControl == 0) { // Calculate new position for the dragged object state.dragOffset = inputInfo.inputPos - state.dragStart; Vector2 delta = (state.dragPos + state.dragOffset * state.zoom) - state.selectedNode.rect.position; state.selectedNode.rect.position = state.dragPos + state.dragOffset * state.zoom; if (inputInfo.inputEvent.alt) { Dictionary <Node, int> d = new Dictionary <Node, int>(); d[state.selectedNode] = 1; MoveChildren(ref d, state.selectedNode, delta); } NodeEditorCallbacks.IssueOnMoveNode(state.selectedNode); NodeEditor.RepaintClients(); } else { state.dragNode = false; } } }
/// <summary> /// Re-Inits the NodeCanvas regardless of whetehr it was initiated before /// </summary> public static void ReInit(bool GUIFunction) { CheckEditorPath(); // Init Resource system. Can be called anywhere else, too, if it's needed before. ResourceManager.SetDefaultResourcePath(editorPath + "Resources/"); // Init NE GUI. I may throw an error if a texture was not found. if (!NodeEditorGUI.Init(GUIFunction)) { InitiationError = true; return; } // Run fetching algorithms searching the script assemblies for Custom Nodes / Connection Types ConnectionTypes.FetchTypes(); NodeTypes.FetchNodes(); // Setup Callback system NodeEditorCallbacks.SetupReceivers(); NodeEditorCallbacks.IssueOnEditorStartUp(); // Init GUIScaleUtility. This fetches reflected calls and my throw a message notifying about incompability. GUIScaleUtility.CheckInit(); #if UNITY_EDITOR UnityEditor.EditorApplication.update -= Update; UnityEditor.EditorApplication.update += Update; RepaintClients(); #endif initiated = true; }
/// <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); }
public void RemoveConnection() { if (!((UnityEngine.Object)connection == (UnityEngine.Object)null)) { NodeEditorCallbacks.IssueOnRemoveConnection(this); connection.connections.Remove(this); connection = null; NodeEditor.RecalculateFrom(body); } }
/// <summary> /// Creates a transition from node to node /// </summary> public static void CreateTransition(Node fromNode, Node toNode) { Transition trans = Transition.Create(fromNode, toNode); if (trans != null) { fromNode.OnAddTransition(trans); toNode.OnAddTransition(trans); NodeEditorCallbacks.IssueOnAddTransition(trans); } }
/// <summary> /// Removes the connection from this NodeInput /// </summary> public void RemoveConnection() { if (connection == null) { return; } NodeEditorCallbacks.IssueOnRemoveConnection(this); connection.connections.Remove(this); connection = null; NodeEditor.curNodeCanvas.OnNodeChange(body); }
private static void HandleNodeDraggingEnd(NodeEditorInputInfo inputInfo) { if (inputInfo.editorState.dragUserID == "node") { Vector2 totalDrag = inputInfo.editorState.EndDrag("node"); if (inputInfo.editorState.dragNode && inputInfo.editorState.selectedNode != null) { inputInfo.editorState.selectedNode.position = totalDrag; NodeEditorCallbacks.IssueOnMoveNode(inputInfo.editorState.selectedNode); } } inputInfo.editorState.dragNode = false; }
/// <summary> /// Removes the connection from this NodeInput /// </summary> public void RemoveConnection() { if (connection == null) { return; } NodeEditorCallbacks.IssueOnRemoveConnection(this); connection.connections.Remove(this); connection = null; NodeEditor.RecalculateFrom(body); }
public static void checkInit() { if (!initiated && !InitiationError) { #if UNITY_EDITOR Object script = UnityEditor.AssetDatabase.LoadAssetAtPath(editorPath + "Framework/NodeEditor.cs", typeof(Object)); if (script == null) { Debug.LogError("Node Editor: Not installed in default directory '" + editorPath + "'! Please modify the editorPath variable in the source!"); InitiationError = true; return; } #endif Background = LoadTexture("Textures/background.png"); AALineTex = LoadTexture("Textures/AALine.png"); if (!Background || !AALineTex) { InitiationError = true; return; } ConnectionTypes.FetchTypes(); NodeTypes.FetchNodes(); NodeEditorCallbacks.SetupReceivers(); NodeEditorCallbacks.IssueOnEditorStartUp(); // Styles nodeBox = new GUIStyle(GUI.skin.box); #if UNITY_EDITOR nodeBox.normal.background = ColorToTex(UnityEditor.EditorGUIUtility.isProSkin? new Color(0.5f, 0.5f, 0.5f) : new Color(0.2f, 0.2f, 0.2f)); #else nodeBox.normal.background = ColorToTex(new Color(0.2f, 0.2f, 0.2f)); #endif nodeBox.normal.textColor = new Color(0.7f, 0.7f, 0.7f); nodeButton = new GUIStyle(GUI.skin.button); nodeLabel = new GUIStyle(GUI.skin.label); nodeLabel.normal.textColor = new Color(0.7f, 0.7f, 0.7f); nodeLabelBold = new GUIStyle(nodeLabel); nodeLabelBold.fontStyle = FontStyle.Bold; nodeLabelBold.wordWrap = false; initiated = true; } return; }
static void MoveChildren(ref Dictionary <Node, int> _dic, Node _n, Vector2 _delta) { foreach (var input in _n.Inputs) { Node cn = input.connection.body; if (!_dic.ContainsKey(cn)) { cn.rect.position += _delta; NodeEditorCallbacks.IssueOnMoveNode(cn); MoveChildren(ref _dic, cn, _delta); _dic[cn] = 1; } } }
/// <summary> /// Loads the editorStates found in the nodeCanvas asset file at path /// </summary> public static List <NodeEditorState> LoadEditorStates(string path) { if (String.IsNullOrEmpty(path)) { return(new List <NodeEditorState> ()); } #if UNITY_EDITOR Object[] objects = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(path); #else Object[] objects = Resources.LoadAll(path); #endif if (objects.Length == 0) { return(new List <NodeEditorState> ()); } // Obtain the editorStates in that asset file List <NodeEditorState> editorStates = new List <NodeEditorState> (); NodeCanvas nodeCanvas = null; for (int cnt = 0; cnt < objects.Length; cnt++) { Object obj = objects [cnt]; if (obj.GetType() == typeof(NodeEditorState)) { NodeEditorState editorState = obj as NodeEditorState; editorStates.Add(editorState); NodeEditorCallbacks.IssueOnLoadEditorState(editorState); } else if (obj.GetType() == typeof(NodeCanvas)) { nodeCanvas = obj as NodeCanvas; } } if (nodeCanvas == null) { return(new List <NodeEditorState> ()); } for (int stateCnt = 0; stateCnt < editorStates.Count; stateCnt++) { editorStates[stateCnt] = GetWorkingCopy(editorStates[stateCnt], nodeCanvas); } #if UNITY_EDITOR UnityEditor.AssetDatabase.Refresh(); #endif return(editorStates); }
/// <summary> /// Saves the current node canvas as a new asset and links optional editorStates with it /// </summary> public static void SaveNodeCanvas(NodeCanvas nodeCanvas, string path, params NodeEditorState[] editorStates) { if (String.IsNullOrEmpty(path)) { return; } nodeCanvas = GetWorkingCopy(nodeCanvas); for (int stateCnt = 0; stateCnt < editorStates.Length; stateCnt++) { editorStates[stateCnt] = GetWorkingCopy(editorStates[stateCnt], nodeCanvas); } #if UNITY_EDITOR UnityEditor.AssetDatabase.CreateAsset(nodeCanvas, path); foreach (NodeEditorState editorState in editorStates) { UnityEditor.AssetDatabase.AddObjectToAsset(editorState, nodeCanvas); editorState.hideFlags = HideFlags.HideInHierarchy; } for (int nodeCnt = 0; nodeCnt < nodeCanvas.nodes.Count; nodeCnt++) { // Add every node and every of it's inputs/outputs into the file. // Results in a big mess but there's no other way (like a hierarchy) Node node = nodeCanvas.nodes [nodeCnt]; UnityEditor.AssetDatabase.AddObjectToAsset(node, nodeCanvas); node.hideFlags = HideFlags.HideInHierarchy; for (int inCnt = 0; inCnt < node.Inputs.Count; inCnt++) { UnityEditor.AssetDatabase.AddObjectToAsset(node.Inputs [inCnt], node); node.Inputs [inCnt].hideFlags = HideFlags.HideInHierarchy; } for (int outCnt = 0; outCnt < node.Outputs.Count; outCnt++) { UnityEditor.AssetDatabase.AddObjectToAsset(node.Outputs [outCnt], node); node.Outputs [outCnt].hideFlags = HideFlags.HideInHierarchy; } for (int transCnt = 0; transCnt < node.transitions.Count; transCnt++) { UnityEditor.AssetDatabase.AddObjectToAsset(node.transitions [transCnt], node); node.transitions [transCnt].hideFlags = HideFlags.HideInHierarchy; } } UnityEditor.AssetDatabase.SaveAssets(); UnityEditor.AssetDatabase.Refresh(); #else // TODO: Node Editor: Need to implement ingame-saving (Resources, AsssetBundles, ... won't work) #endif NodeEditorCallbacks.IssueOnSaveCanvas(nodeCanvas); }
public static Node Create(string nodeID, Vector2 position) { Node node = NodeTypes.getDefaultNode(nodeID); if (node == null) { throw new UnityException("Cannot create Node with id " + nodeID + " as no such Node type is registered!"); } node = node.Create(position); node.InitBase(); NodeEditorCallbacks.IssueOnAddNode(node); return(node); }
/// <summary> /// Applies a connection between output and input. 'CanApplyConnection' has to be checked before /// </summary> public static void ApplyConnection(NodeOutput output, NodeInput input) { if (input != null && output != null) { if (input.connection != null) { input.connection.connections.Remove(input); } input.connection = output; output.connections.Add(input); NodeEditor.RecalculateFrom(input.body); NodeEditorCallbacks.IssueOnAddConnection(input); } }
protected static void ReassignOutputType(ref NodeOutput output, Type newOutputType) { Node body = output.body; string name = output.name; IEnumerable <NodeInput> enumerable = from connection in output.connections where connection.typeData.Type.IsAssignableFrom(newOutputType) select connection; output.Delete(); NodeEditorCallbacks.IssueOnAddNodeKnob(NodeOutput.Create(body, name, newOutputType.AssemblyQualifiedName)); output = body.Outputs[body.Outputs.Count - 1]; foreach (NodeInput item in enumerable) { item.ApplyConnection(output); } }
/// <summary> /// Removes the connection of this port to the specified port if existant /// </summary> public void RemoveConnection(ConnectionPort port, bool silent = false) { Undo.RecordObjects(new [] { this, port }, "NodeEditor_连接移除保存"); if (port == null) { connections.RemoveAll(p => p != null); return; } if (!silent) { NodeEditorCallbacks.IssueOnRemoveConnection(this, port); } port.connections.Remove(this); connections.Remove(port); }