I am currently using this Node Editor to define connections between level nodes for game worlds.
What is annoying is that after loading and editing a node canvas then saving the file (replacing/"updating" it's existing NodeCanvas.asset file) all scripts in the project referencing that NodeCanvas.asset file loose their reference to it.
/// <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, bool overwrite = false)
{
#if !UNITY_EDITOR
throw new System.NotImplementedException ();
#else
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
#if UNITY_EDITOR
nodeCanvas.BeforeSavingCanvas();
// Preprocess the canvas
ProcessCanvas (ref nodeCanvas, createWorkingCopy);
nodeCanvas.livesInScene = false;
/////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////// NEW ///////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
var canvasFile = UnityEditor.AssetDatabase.LoadMainAssetAtPath(path) as NodeCanvas;
if (overwrite && canvasFile != null)
{
// Overwrite existing NodeCanvas to not break references to existing file.
Object[] allAssets = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(path);
for (int i = allAssets.Length-1; i >= 0; i--)
{
// Clear content of existing asset file
if (allAssets[i] != canvasFile)
{
// If not the main asset, delete it. The main asset is replaced below (CopySerialized). These sub assets are re-added below also (AddSubAsset calls).
Object.DestroyImmediate(allAssets[i], true);
}
}
UnityEditor.EditorUtility.CopySerialized(nodeCanvas, canvasFile);
nodeCanvas = canvasFile;
}
else
{
// Write canvas and editorStates
UnityEditor.AssetDatabase.CreateAsset(nodeCanvas, path);
}
AddSubAssets(nodeCanvas.editorStates, nodeCanvas);
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// END NEW /////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// 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);
#endif
}
We call our updated from NodeEditorUserCache.cs line 259 with NodeEditorSaveManager.SaveNodeCanvas (path, nodeCanvas, true, true);.
The optional argument bool overwrite = false is because we only care about overwriting when saving over our existing NodeCanvas.asset file (pressing the save button from the NodeEditor GUI). Doing the overwrite with LastSession/NodeEditorUserCache saves is causing errors:
"UnityException: Cache system error: Current Canvas is not saved as the temporary cache!" from NodeEditorUserCache.CheckCurrentCache().
"Source and Destination Types do not match" from EditorUtility:CopySerialized(Object, Object).
Posting to see opinions/advice and if anyone else has run into this problem also.
Completely open to feedback and suggestions!
Hello!
I am currently using this Node Editor to define connections between level nodes for game worlds.
What is annoying is that after loading and editing a node canvas then saving the file (replacing/"updating" it's existing NodeCanvas.asset file) all scripts in the project referencing that NodeCanvas.asset file loose their reference to it.
This is due to
UnityEditor.AssetDatabase.CreateAsset(nodeCanvas, path);
in NodeEditorSaveManager.cs. The method's documentation states "...If an asset already exists at path it will be deleted prior to creating a new asset...".A messy attempt to fix this:
We call our updated from NodeEditorUserCache.cs line 259 with
NodeEditorSaveManager.SaveNodeCanvas (path, nodeCanvas, true, true);
.The optional argument
bool overwrite = false
is because we only care about overwriting when saving over our existing NodeCanvas.asset file (pressing the save button from the NodeEditor GUI). Doing the overwrite with LastSession/NodeEditorUserCache saves is causing errors:Posting to see opinions/advice and if anyone else has run into this problem also. Completely open to feedback and suggestions!
This project has been a big help btw. Cheers.