/// <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 !UNITY_EDITOR throw new System.NotImplementedException(); #else if (string.IsNullOrEmpty(path)) { throw new System.ArgumentNullException("Cannot load Canvas: No path specified!"); } path = NodeResourceManager.PreparePath(path); // Load only the NodeCanvas from the save file NodeCanvas nodeCanvas = NodeResourceManager.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 (!Application.isPlaying && (nodeCanvas.editorStates == null || nodeCanvas.editorStates.Length == 0)) { // Try to load any contained editorStates, as the canvas did not reference any nodeCanvas.editorStates = NodeResourceManager.LoadResources <NodeEditorState> (path); } // Set the path as the new source of the canvas nodeCanvas.UpdateSource(path); // Postprocess the loaded canvas nodeCanvas.Validate(); if (createWorkingCopy) { nodeCanvas = CreateWorkingCopy(nodeCanvas); } NodeEditorCallbacks.IssueOnLoadCanvas(nodeCanvas); return(nodeCanvas); #endif }
/// <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, bool createWorkingCopy, bool safeOverwrite = true) { #if !UNITY_EDITOR throw new System.NotImplementedException(); #else 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 (nodeCanvas.livesInScene) { LogMgr.LogWarning("Attempting to save scene canvas '" + nodeCanvas.name + "' to an asset, references to scene object may be broken!" + (!createWorkingCopy? " Forcing creation of working copy!" : "")); createWorkingCopy = true; } if (UnityEditor.AssetDatabase.Contains(nodeCanvas) && UnityEditor.AssetDatabase.GetAssetPath(nodeCanvas) != path) { LogMgr.LogWarning("Trying to create a duplicate save file for '" + nodeCanvas.name + "'! Forcing creation of working copy!"); nodeCanvas = CreateWorkingCopy(nodeCanvas); } // Prepare and update source path of the canvas path = NodeResourceManager.PreparePath(path); nodeCanvas.UpdateSource(path); // Preprocess the canvas NodeCanvas processedCanvas = nodeCanvas; processedCanvas.OnBeforeSavingCanvas(); if (createWorkingCopy) { processedCanvas = CreateWorkingCopy(processedCanvas); } // Differenciate canvasSave as the canvas asset and nodeCanvas as the source incase an existing save has been overwritten NodeCanvas canvasSave = processedCanvas; NodeCanvas prevSave; if (safeOverwrite && (prevSave = NodeResourceManager.LoadResource <NodeCanvas> (path)) != null && prevSave.GetType() == canvasSave.GetType()) { // OVERWRITE: Delete contents of old save for (int nodeCnt = 0; nodeCnt < prevSave.nodes.Count; nodeCnt++) { Node node = prevSave.nodes[nodeCnt]; // Make sure all node ports are included in the representative connectionPorts list ConnectionPortManager.UpdatePortLists(node); for (int k = 0; k < node.connectionPorts.Count; k++) { Object.DestroyImmediate(node.connectionPorts[k], true); } Object.DestroyImmediate(node, true); } for (int i = 0; i < prevSave.editorStates.Length; i++) { if (prevSave.editorStates[i] != null) { Object.DestroyImmediate(prevSave.editorStates[i], true); } } // Overwrite main canvas OverwriteCanvas(ref prevSave, processedCanvas); canvasSave = prevSave; } else { // Write main canvas UnityEditor.AssetDatabase.CreateAsset(processedCanvas, path); } // Write editorStates AddSubAssets(processedCanvas.editorStates, canvasSave); // Write nodes + contents foreach (Node node in processedCanvas.nodes) { // Write node and additional scriptable objects AddSubAsset(node, canvasSave); AddSubAssets(node.GetScriptableObjects(), node); // Make sure all node ports are included in the representative connectionPorts list ConnectionPortManager.UpdatePortLists(node); foreach (ConnectionPort port in node.connectionPorts) { AddSubAsset(port, node); } } UnityEditor.AssetDatabase.SaveAssets(); UnityEditor.AssetDatabase.Refresh(); NodeEditorCallbacks.IssueOnSaveCanvas(canvasSave); #endif }