private void SaveNewNodeKnob(NodeKnob knob) { if (!useCache) { return; } CheckCurrentCache(); if (nodeCanvas.livesInScene) { return; } if (!nodeCanvas.nodes.Contains(knob.body)) { return; } NodeEditorSaveManager.AddSubAsset(knob, knob.body); foreach (ScriptableObject so in knob.GetScriptableObjects()) { NodeEditorSaveManager.AddSubAsset(so, knob); } UpdateCacheFile(); }
/// <summary> /// CreateWorkingCopy a working copy of the canvas and each editorState. This will break the link to the canvas asset and thus all changes made to the working copy have to be explicitly saved. /// Check compressed if the copy is not intended for useage but for storage, this will leave the Inputs and Outputs list of Node empty /// </summary> public static void CreateWorkingCopy(ref NodeCanvas nodeCanvas, NodeEditorState[] editorStates, bool compressed) { nodeCanvas = Clone(nodeCanvas); // Take each SO, make a clone of it and store both versions in the respective list // This will only iterate over the 'source instances' List <ScriptableObject> allSOs = new List <ScriptableObject> (); List <ScriptableObject> clonedSOs = new List <ScriptableObject> (); foreach (Node node in nodeCanvas.nodes) { node.CheckNodeKnobMigration(); Node clonedNode = AddClonedSO(allSOs, clonedSOs, node); foreach (NodeKnob knob in clonedNode.nodeKnobs) { // Clone NodeKnobs NodeKnob clonedKnob = AddClonedSO(allSOs, clonedSOs, knob); // Clone additional scriptableObjects ScriptableObject[] additionalKnobSOs = clonedKnob.GetScriptableObjects(); foreach (ScriptableObject so in additionalKnobSOs) { AddClonedSO(allSOs, clonedSOs, so); } } // Clone additional scriptableObjects ScriptableObject[] additionalNodeSOs = clonedNode.GetScriptableObjects(); foreach (ScriptableObject so in additionalNodeSOs) { AddClonedSO(allSOs, clonedSOs, so); } } // Replace every reference to any of the initial SOs of the first list with the respective clones of the second list for (int nodeCnt = 0; nodeCnt < nodeCanvas.nodes.Count; nodeCnt++) { // Clone Nodes, structural content and additional scriptableObjects Node clonedNode = nodeCanvas.nodes[nodeCnt] = ReplaceSO(allSOs, clonedSOs, nodeCanvas.nodes[nodeCnt]); // We're going to restore these from NodeKnobs if desired (!compressed) clonedNode.Inputs = new List <NodeInput> (); clonedNode.Outputs = new List <NodeOutput> (); for (int knobCnt = 0; knobCnt < clonedNode.nodeKnobs.Count; knobCnt++) { // Clone generic NodeKnobs NodeKnob clonedKnob = clonedNode.nodeKnobs[knobCnt] = ReplaceSO(allSOs, clonedSOs, clonedNode.nodeKnobs[knobCnt]); clonedKnob.body = clonedNode; if (!compressed) { // Add NodeInputs and NodeOutputs to the apropriate lists in Node if desired (!compressed) if (clonedKnob is NodeInput) { clonedNode.Inputs.Add(clonedKnob as NodeInput); } else if (clonedKnob is NodeOutput) { clonedNode.Outputs.Add(clonedKnob as NodeOutput); } } // Replace additional scriptableObjects in the NodeKnob clonedKnob.CopyScriptableObjects((ScriptableObject so) => ReplaceSO(allSOs, clonedSOs, so)); } // Replace additional scriptableObjects in the Node clonedNode.CopyScriptableObjects((ScriptableObject so) => ReplaceSO(allSOs, clonedSOs, so)); } // Also create working copies for specified editorStates, if any // Needs to be in the same function as the EditorState references nodes from the NodeCanvas if (editorStates != null) { for (int stateCnt = 0; stateCnt < editorStates.Length; stateCnt++) { if (editorStates[stateCnt] == null) { continue; } NodeEditorState clonedState = editorStates[stateCnt] = Clone(editorStates[stateCnt]); clonedState.canvas = nodeCanvas; clonedState.focusedNode = null; clonedState.selectedNode = clonedState.selectedNode != null?ReplaceSO(allSOs, clonedSOs, clonedState.selectedNode) : null; clonedState.makeTransition = null; clonedState.connectOutput = null; } } }