Exemple #1
0
        /// <summary>
        /// Saves the current canvas to the cache
        /// </summary>
        public void SaveCache()
        {
#if CACHE
            if (!useCache)
            {
                return;
            }
            if (!nodeCanvas || nodeCanvas.GetType() == typeof(NodeCanvas))
            {
                return;
            }
            UnityEditor.EditorUtility.SetDirty(nodeCanvas);
            if (editorState != null)
            {
                UnityEditor.EditorUtility.SetDirty(editorState);
            }
            lastCacheTime = UnityEditor.EditorApplication.timeSinceStartup;

            nodeCanvas.editorStates = new NodeEditorState[] { editorState };
            if (nodeCanvas.livesInScene || nodeCanvas.allowSceneSaveOnly)
            {
                NodeEditorSaveManager.SaveSceneNodeCanvas("lastSession", ref nodeCanvas, cacheWorkingCopy);
            }
            else
            {
                NodeEditorSaveManager.SaveNodeCanvas(lastSessionPath, ref nodeCanvas, cacheWorkingCopy, true);
            }
#endif
        }
Exemple #2
0
        /// <summary>
        /// Creates a new cache save file for the currently loaded canvas
        /// Only called when a new canvas is created or loaded
        /// </summary>
        public void SaveCache()
        {
                        #if UNITY_EDITOR
            if (!useCache)
            {
                return;
            }
            if (!nodeCanvas || nodeCanvas.GetType() == typeof(NodeCanvas))
            {
                return;
            }
            UnityEditor.EditorUtility.SetDirty(nodeCanvas);
            if (editorState != null)
            {
                UnityEditor.EditorUtility.SetDirty(editorState);
            }
                        #if !EDITOR_CACHE_ASSET
            lastCacheTime = UnityEditor.EditorApplication.timeSinceStartup;
                        #endif
            nodeCanvas.editorStates = new NodeEditorState[] { editorState };
            if (nodeCanvas.livesInScene)
            {
                NodeEditorSaveManager.SaveSceneNodeCanvas("lastSession", ref nodeCanvas, cacheWorkingCopy);
            }
            else
            {
                NodeEditorSaveManager.SaveNodeCanvas(lastSessionPath, nodeCanvas, cacheWorkingCopy, true);
            }

            CheckCurrentCache();
                        #endif
        }
        public static NodeCanvasTypeData getCanvasTypeData(NodeCanvas canvas)
        {
            NodeCanvasTypeData data;

            CanvasTypes.TryGetValue(canvas.GetType(), out data);
            return(data);
        }
        /// <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);
        }
Exemple #5
0
        /// <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);
        }
 private static void DeCafList(ref List <Node> displayedNodes, NodeCanvas canvas)
 {
     for (int i = 0; i < displayedNodes.Count; i++)
     {
         if (!NodeTypes.nodes[displayedNodes[i]].typeOfNodeCanvas.Contains(canvas.GetType()))
         {
             displayedNodes.RemoveAt(i);
             i--;
         }
     }
 }
        /// <summary>
        /// Converts the type of the canvas to the specified type.
        /// </summary>
        public static NodeCanvas ConvertCanvasType(NodeCanvas canvas, Type newType)
        {
            NodeCanvas convertedCanvas = canvas;

            if (canvas.GetType() != newType && newType != typeof(NodeCanvas) && newType.IsSubclassOf(typeof(NodeCanvas)))
            {
                canvas                       = NodeEditorSaveManager.CreateWorkingCopy(canvas, true);
                convertedCanvas              = NodeCanvas.CreateCanvas(newType);
                convertedCanvas.nodes        = canvas.nodes;
                convertedCanvas.editorStates = canvas.editorStates;
                convertedCanvas.Validate();
            }
            return(convertedCanvas);
        }
Exemple #8
0
 /// <summary>
 /// Overwrites canvas with the contents of canvasData, so that all references to canvas will be remained, but both canvases are still seperate.
 /// Only works in the editor!
 /// </summary>
 public static void OverwriteCanvas(ref NodeCanvas targetCanvas, NodeCanvas canvasData)
 {
         #if UNITY_EDITOR
     if (canvasData == null)
     {
         throw new System.ArgumentNullException("Cannot overwrite canvas as data is null!");
     }
     if (targetCanvas == null)
     {
         targetCanvas = NodeCanvas.CreateCanvas(canvasData.GetType());
     }
     UnityEditor.EditorUtility.CopySerialized(canvasData, targetCanvas);
     targetCanvas.name = canvasData.name;
         #else
     throw new System.NotSupportedException("Cannot overwrite canvas in player!");
         #endif
 }
        /// <summary>
        /// Saves the current canvas to the cache
        /// </summary>
        public void SaveCache(bool crashSafe = true)
        {
#if CACHE
            if (!useCache)
            {
                return;
            }
            if (!nodeCanvas || nodeCanvas.GetType() == typeof(NodeCanvas))
            {
                return;
            }
            UnityEditor.EditorUtility.SetDirty(nodeCanvas);
            if (editorState != null)
            {
                UnityEditor.EditorUtility.SetDirty(editorState);
            }
            lastCacheTime = UnityEditor.EditorApplication.timeSinceStartup;

            nodeCanvas.editorStates = new NodeEditorState[] { editorState };
            if (nodeCanvas.livesInScene || nodeCanvas.allowSceneSaveOnly)
            {
                NodeEditorSaveManager.SaveSceneNodeCanvas("lastSession", ref nodeCanvas, cacheWorkingCopy);
            }
            else if (crashSafe)
            {
                NodeEditorSaveManager.SaveNodeCanvas(lastSessionPath, ref nodeCanvas, cacheWorkingCopy, true);
            }

            if (cacheMemorySODump)
            {             // Functionality for asset saves only
                if (nodeCanvas.livesInScene || nodeCanvas.allowSceneSaveOnly)
                {         // Delete for scene save so that next cache load, correct lastSession is used
                    UnityEditor.AssetDatabase.DeleteAsset(SOMemoryDumpPath);
                }
                else
                {                 // Dump all SOs used in this session (even if deleted) in this file to keep them alive for undo
                    NodeEditorUndoActions.CompleteSOMemoryDump(nodeCanvas);
                    NodeEditorSaveManager.ScriptableObjectReferenceDump(nodeCanvas.SOMemoryDump, SOMemoryDumpPath, false);
                }
            }
#endif
        }
Exemple #10
0
        /// <summary>
        /// Converts the given canvas to the specified type
        /// </summary>
        public static NodeCanvas ConvertCanvasType(NodeCanvas canvas, Type newType)
        {
            NodeCanvas convertedCanvas = canvas;

            if (canvas.GetType() != newType && newType.IsSubclassOf(typeof(NodeCanvas)))
            {
                canvas.Validate();
                canvas                       = NodeEditorSaveManager.CreateWorkingCopy(canvas);
                convertedCanvas              = NodeCanvas.CreateCanvas(newType);
                convertedCanvas.nodes        = canvas.nodes;
                convertedCanvas.groups       = canvas.groups;
                convertedCanvas.editorStates = canvas.editorStates;
                for (int i = 0; i < convertedCanvas.nodes.Count; i++)
                {
                    if (!CheckCanvasCompability(convertedCanvas.nodes[i].GetID, newType))
                    {                     // Check if nodes is even compatible with the canvas, if not delete it
                        convertedCanvas.nodes[i].Delete();
                        i--;
                    }
                }
                convertedCanvas.Validate();
            }
            return(convertedCanvas);
        }
Exemple #11
0
        /// <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 = false, 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!");
            }
            if (nodeCanvas.allowSceneSaveOnly)
            {
                throw new System.InvalidOperationException("Cannot save NodeCanvas: NodeCanvas is marked to contain scene data and cannot be saved as an asset!");
            }

            nodeCanvas.Validate();

            if (nodeCanvas.livesInScene)
            {
                Debug.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)
            {
                Debug.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 = ResourceManager.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 = ResourceManager.LoadResource <NodeCanvas> (path)) != null && prevSave.GetType() == canvasSave.GetType())
            {             // OVERWRITE: Delete contents of old save
                Object[] subAssets = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(path);
                for (int i = 0; i < subAssets.Length; i++)
                {                 // Delete all subassets except the main canvas to preserve references
                    if (subAssets[i] != prevSave)
                    {
                        Object.DestroyImmediate(subAssets[i], true);
                    }
                }
                // Overwrite main canvas
                OverwriteCanvas(ref prevSave, processedCanvas);
                canvasSave = prevSave;
            }
            else
            {             // Write main canvas
                UnityEditor.AssetDatabase.DeleteAsset(path);
                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);
                }
            }

            XProfile.Begin("-");
            UnityEditor.AssetDatabase.SaveAssets();
            UnityEditor.AssetDatabase.Refresh();
            XProfile.End(true);

            NodeEditorCallbacks.IssueOnSaveCanvas(canvasSave);
        #endif
        }
Exemple #12
0
        /// <summary>
        /// Saves the nodeCanvas in the current scene under the specified name, optionally as a working copy and overwriting any existing save at path
        /// If the specified canvas is stored as an asset, the saved canvas will loose the reference to the asset
        /// </summary>
        public static void SaveSceneNodeCanvas(string saveName, ref NodeCanvas nodeCanvas, bool createWorkingCopy, bool safeOverwrite = true)
        {
            if (string.IsNullOrEmpty(saveName))
            {
                throw new System.ArgumentNullException("Cannot save Canvas to scene: No save name specified!");
            }
            if (nodeCanvas == null)
            {
                throw new System.ArgumentNullException("Cannot save NodeCanvas: The specified NodeCanvas that should be saved as '" + saveName + "' 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!");
            }

            if (saveName.StartsWith("SCENE/"))
            {
                saveName = saveName.Substring(6);
            }

            nodeCanvas.Validate();

            if (!nodeCanvas.livesInScene
                #if UNITY_EDITOR // Make sure the canvas has no reference to an asset
                || UnityEditor.AssetDatabase.Contains(nodeCanvas)
                #endif
                )
            {
                Debug.LogWarning("Creating scene save '" + nodeCanvas.name + "' for canvas saved as an asset! Forcing creation of working copy!");
                nodeCanvas = CreateWorkingCopy(nodeCanvas);
            }

            // Update the source of the canvas
            nodeCanvas.UpdateSource("SCENE/" + saveName);

            // Preprocess the canvas
            NodeCanvas processedCanvas = nodeCanvas;
            processedCanvas.OnBeforeSavingCanvas();
            if (createWorkingCopy)
            {
                processedCanvas = CreateWorkingCopy(processedCanvas);
            }

            // Get the saveHolder and store the canvas
            NodeCanvas          savedCanvas = processedCanvas;
            NodeCanvasSceneSave sceneSave   = FindSceneSave(saveName, true);

#if UNITY_EDITOR
            if (sceneSave.savedNodeCanvas != null && safeOverwrite && sceneSave.savedNodeCanvas.GetType() == savedCanvas.GetType())             // OVERWRITE
            {
                OverwriteCanvas(ref sceneSave.savedNodeCanvas, savedCanvas);
            }

            if (!Application.isPlaying)
            {             // Set Dirty
                UnityEditor.EditorUtility.SetDirty(sceneSave.gameObject);
#if UNITY_5_3_OR_NEWER || UNITY_5_3
                UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(sceneSave.gameObject.scene);
#else
                UnityEditor.EditorApplication.MarkSceneDirty();
                        #endif
            }
#endif
            sceneSave.savedNodeCanvas = savedCanvas;

            NodeEditorCallbacks.IssueOnSaveCanvas(savedCanvas);
        }
Exemple #13
0
        /// <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.canvas   = hostCanvas;
            node.name     = node.Title;
            node.autoSize = node.DefaultSize;
            node.position = pos;
            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, true))
                    {
                        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();
            }

#if UNITY_EDITOR
            if (!silent)
            {
                List <ConnectionPort> connectedPorts = new List <ConnectionPort>();
                foreach (ConnectionPort port in node.connectionPorts)
                {                 // 'Encode' connected ports in one list (double level cannot be serialized)
                    foreach (ConnectionPort conn in port.connections)
                    {
                        connectedPorts.Add(conn);
                    }
                    connectedPorts.Add(null);
                }
                Node createdNode = node;
                UndoPro.UndoProManager.RecordOperation(
                    () => NodeEditorUndoActions.ReinstateNode(createdNode, connectedPorts),
                    () => NodeEditorUndoActions.RemoveNode(createdNode),
                    "Create Node");
                // Make sure the new node is in the memory dump
                NodeEditorUndoActions.CompleteSOMemoryDump(hostCanvas);
            }
#endif

            return(node);
        }
Exemple #14
0
        /// <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 safeOverwrite = true)
        {
                #if !UNITY_EDITOR
            throw new System.NotImplementedException();
                #endif

            if (string.IsNullOrEmpty(path) || !path.StartsWith("Assets"))
            {
                throw new UnityException("Cannot save NodeCanvas: Invalid path specified: '" + path + "'!");
            }
            if (nodeCanvas == null)
            {
                throw new UnityException("Cannot save NodeCanvas: The specified NodeCanvas that should be saved to path " + path + " is null!");
            }
            if (nodeCanvas.GetType() == typeof(NodeCanvas))
            {
                throw new UnityException("Cannot save NodeCanvas: The NodeCanvas has no explicit type: '" + nodeCanvas.GetType().ToString() + "'. Please convert it to a valid type!");
            }
            if (nodeCanvas.livesInScene)
            {
                Debug.LogWarning("Attempting to save scene canvas " + nodeCanvas.name + " to an asset, scene object references may 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

            path = ResourceManager.PreparePath(path);

            nodeCanvas.OnBeforeSavingCanvas();

            NodeCanvas canvasSave = nodeCanvas;

                #if UNITY_EDITOR
            nodeCanvas.UpdateSource(path);

            // Preprocess the canvas
            ProcessCanvas(ref nodeCanvas, createWorkingCopy);
            nodeCanvas.livesInScene = false;

            canvasSave = nodeCanvas;
            NodeCanvas prevSave;
            if (safeOverwrite && (prevSave = ResourceManager.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];
                    for (int knobCnt = 0; knobCnt < node.nodeKnobs.Count; knobCnt++)
                    {
                        if (node.nodeKnobs[knobCnt] != null)
                        {
                            Object.DestroyImmediate(node.nodeKnobs[knobCnt], 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, nodeCanvas);
                canvasSave = prevSave;
            }
            else
            {             // Write main canvas
                UnityEditor.AssetDatabase.CreateAsset(nodeCanvas, path);
            }

            // Write editorStates
            AddSubAssets(nodeCanvas.editorStates, canvasSave);

            // Write nodes + contents
            foreach (Node node in nodeCanvas.nodes)
            {             // Write node and additional scriptable objects
                AddSubAsset(node, canvasSave);
                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(canvasSave);
        }
Exemple #15
0
        /// <summary>
        /// Saves the nodeCanvas in the current scene under the specified name along with the specified editorStates or, if specified, their working copies
        /// If also stored as an asset, it will loose the reference to the asset first
        /// </summary>
        public static void SaveSceneNodeCanvas(string saveName, ref NodeCanvas nodeCanvas, bool createWorkingCopy, bool safeOverwrite = true)
        {
            if (string.IsNullOrEmpty(saveName))
            {
                Debug.LogError("Cannot save Canvas to scene: No save name specified!");
                return;
            }

            if (nodeCanvas.GetType() == typeof(NodeCanvas))
            {
                throw new UnityException("Cannot save NodeCanvas: The NodeCanvas has no explicit type: '" + nodeCanvas.GetType().ToString() + "'. Please convert it to a valid type!");
            }

            if (!nodeCanvas.livesInScene
                #if UNITY_EDITOR // Make sure the canvas has no reference to an asset
                || UnityEditor.AssetDatabase.Contains(nodeCanvas)
                #endif
                )
            {
                //Debug.LogWarning ("Forced to create working copy of '" + saveName + "' when saving to scene because it already exists as an asset!");
                nodeCanvas = CreateWorkingCopy(nodeCanvas, true);
            }
            else
            {
                nodeCanvas.Validate(true);
            }

            nodeCanvas.livesInScene = true;
            nodeCanvas.name         = saveName;

            nodeCanvas.OnBeforeSavingCanvas();

            nodeCanvas.UpdateSource("SCENE/" + saveName);

            NodeCanvas savedCanvas = nodeCanvas;
            // Preprocess canvas
            ProcessCanvas(ref savedCanvas, createWorkingCopy);

            // Get the saveHolder and store the canvas
            NodeCanvasSceneSave sceneSave;
                #if UNITY_EDITOR
            if ((sceneSave = FindSceneSave(saveName)) != null && safeOverwrite)              // OVERWRITE
            {
                OverwriteCanvas(ref sceneSave.savedNodeCanvas, savedCanvas);
            }
            else
            {
                if (sceneSave == null)
                {
                    sceneSave = CreateSceneSave(saveName);
                }
                sceneSave.savedNodeCanvas = savedCanvas;
            }
            if (!Application.isPlaying)
            {
                        #if UNITY_5_3_OR_NEWER
                UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
                        #else
                UnityEditor.EditorApplication.MarkSceneDirty();
                        #endif
            }
                #else
            sceneSave = FindOrCreateSceneSave(saveName);
            sceneSave.savedNodeCanvas = savedCanvas;
                #endif

                #if UNITY_EDITOR
            UnityEditor.EditorUtility.SetDirty(sceneSaveHolder);
                #endif
        }
Exemple #16
0
        /// <summary>
        /// Creates a copy of the specified node at pos on the specified canvas, optionally auto-connecting the specified output to a matching input
        /// silent disables any events
        /// </summary>
        public static Node CreateCopy(Node toCopy, Vector2 pos, NodeCanvas hostCanvas, ConnectionPort connectingPort = null, bool silent = false)
        {
            if (toCopy == null || hostCanvas == null)
            {
                throw new ArgumentException();
            }
            if (!NodeCanvasManager.CheckCanvasCompability(toCopy.GetID, hostCanvas.GetType()))
            {
                throw new UnityException("Cannot create Node with ID '" + toCopy.GetID + "' as it is not compatible with the current canvas type (" + hostCanvas.GetType().ToString() + ")!");
            }
            if (!hostCanvas.CanAddNode(toCopy.GetID))
            {
                throw new UnityException("Cannot create Node with ID '" + toCopy.GetID + "' on the current canvas of type (" + hostCanvas.GetType().ToString() + ")!");
            }
            Node node = ScriptableObject.Instantiate(toCopy);

            //Clone static connection ports
            foreach (ConnectionPortDeclaration portDecl in ConnectionPortManager.GetPortDeclarationEnumerator(node, true))
            {
                ConnectionPort port = (ConnectionPort)portDecl.portField.GetValue(node);
                port = portDecl.portInfo.CreateNew(node);
                portDecl.portField.SetValue(node, port);
            }
            //Clone dynamic connection ports
            for (int i = 0; i < node.dynamicConnectionPorts.Count; ++i)
            {
                node.dynamicConnectionPorts[i]      = ScriptableObject.Instantiate(node.dynamicConnectionPorts[i]);
                node.dynamicConnectionPorts[i].body = node;
                node.dynamicConnectionPorts[i].ClearConnections();
            }
            ConnectionPortManager.UpdateRepresentativePortLists(node);
            //Clone child SOs
            System.Func <ScriptableObject, ScriptableObject> copySOs = (ScriptableObject so) => ScriptableObject.Instantiate(so);;
            node.CopyScriptableObjects(copySOs);
            if (node == null)
            {
                return(null);
            }

            // Init node state
            node.name     = node.Title;
            node.autoSize = node.DefaultSize;
            node.position = pos;
            ConnectionPortManager.UpdateConnectionPorts(node);

            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);
        }
        /// <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();

            // TODO: Node Editor: Need to implement ingame-saving (Resources, AsssetBundles, ... won't work)
                #endif

            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!");
            }

            if (nodeCanvas.livesInScene)
            {
                Debug.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 UNITY_EDITOR
            if (UnityEditor.AssetDatabase.Contains(nodeCanvas) && UnityEditor.AssetDatabase.GetAssetPath(nodeCanvas) != path)
            {
                Debug.LogWarning("Trying to create a duplicate save file for '" + nodeCanvas.name + "'! Forcing creation of working copy!");
                ProcessCanvas(ref nodeCanvas, true);
            }
                #endif

                #if UNITY_EDITOR
            // Prepare and update source path of the canvas
            path = ResourceManager.PreparePath(path);
            nodeCanvas.UpdateSource(path);

            // Preprocess the canvas
            NodeCanvas processedCanvas = nodeCanvas;
            processedCanvas.OnBeforeSavingCanvas();
            ProcessCanvas(ref processedCanvas, createWorkingCopy);

            // 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 = ResourceManager.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];
                    for (int knobCnt = 0; knobCnt < node.nodeKnobs.Count; knobCnt++)
                    {
                        if (node.nodeKnobs[knobCnt] != null)
                        {
                            Object.DestroyImmediate(node.nodeKnobs[knobCnt], 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);
                foreach (NodeKnob knob in node.nodeKnobs)
                {
                    AddSubAsset(knob, node);
                }
            }

            //UnityEditor.AssetDatabase.SaveAssets ();
            //UnityEditor.AssetDatabase.Refresh ();

            NodeEditorCallbacks.IssueOnSaveCanvas(canvasSave);
                #endif
        }
        public static bool CheckCanvasCompability(string nodeID, NodeCanvas canvas)
        {
            NodeData data = NodeTypes.getNodeData(nodeID);

            return(data.limitToCanvasTypes == null || data.limitToCanvasTypes.Length == 0 || data.limitToCanvasTypes.Contains(canvas.GetType()));
        }