Пример #1
0
        /// <summary>
        /// Creates a working copy of the specified nodeCanvas, and optionally also of it's associated editorStates.
        /// This breaks the link of this object to any stored assets and references. That means, that all changes to this object will have to be explicitly saved.
        /// </summary>
        public static NodeCanvas CreateWorkingCopy(NodeCanvas nodeCanvas, bool editorStates)
        {
            nodeCanvas.Validate();
            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> ();

            for (int nodeCnt = 0; nodeCnt < nodeCanvas.nodes.Count; nodeCnt++)
            {
                Node node = nodeCanvas.nodes[nodeCnt];
                node.CheckNodeKnobMigration();

                // Clone Node and additional scriptableObjects
                Node clonedNode = AddClonedSO(allSOs, clonedSOs, node);
                AddClonedSOs(allSOs, clonedSOs, clonedNode.GetScriptableObjects());

                foreach (NodeKnob knob in clonedNode.nodeKnobs)
                {                 // Clone NodeKnobs and additional scriptableObjects
                    AddClonedSO(allSOs, clonedSOs, knob);
                    AddClonedSOs(allSOs, clonedSOs, knob.GetScriptableObjects());
                }
            }

            // 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 node = nodeCanvas.nodes[nodeCnt];
                // Replace node and additional ScriptableObjects
                Node clonedNode = nodeCanvas.nodes[nodeCnt] = ReplaceSO(allSOs, clonedSOs, node);
                clonedNode.CopyScriptableObjects((ScriptableObject so) => ReplaceSO(allSOs, clonedSOs, so));

                // 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 knob = clonedNode.nodeKnobs[knobCnt] = ReplaceSO(allSOs, clonedSOs, clonedNode.nodeKnobs[knobCnt]);
                    knob.body = clonedNode;
                    // Replace additional scriptableObjects in the NodeKnob
                    knob.CopyScriptableObjects((ScriptableObject so) => ReplaceSO(allSOs, clonedSOs, so));
                }
                for (int knobCnt = 0; knobCnt < clonedNode.Inputs.Count; knobCnt++)
                {                 // Clone generic NodeKnobs
                    NodeInput knob = clonedNode.Inputs[knobCnt] = ReplaceSO(allSOs, clonedSOs, clonedNode.Inputs[knobCnt]);
                    knob.body = clonedNode;
                }
                for (int knobCnt = 0; knobCnt < clonedNode.Outputs.Count; knobCnt++)
                {                 // Clone generic NodeKnobs
                    NodeOutput knob = clonedNode.Outputs[knobCnt] = ReplaceSO(allSOs, clonedSOs, clonedNode.Outputs[knobCnt]);
                    knob.body = clonedNode;
                }
            }

            if (editorStates)
            {
                nodeCanvas.editorStates = CreateWorkingCopy(nodeCanvas.editorStates, nodeCanvas);
                foreach (NodeEditorState state in nodeCanvas.editorStates)
                {
                    state.selectedNode = ReplaceSO(allSOs, clonedSOs, state.selectedNode);
                }
            }
            else
            {
                foreach (NodeEditorState state in nodeCanvas.editorStates)
                {
                    state.selectedNode = null;
                }
            }

            return(nodeCanvas);
        }
Пример #2
0
        public static NodeCanvas CreateWorkingCopy(NodeCanvas nodeCanvas, bool editorStates)
        {
            nodeCanvas.Validate();
            nodeCanvas = Clone(nodeCanvas);
            List <ScriptableObject> allSOs    = new List <ScriptableObject>();
            List <ScriptableObject> clonedSOs = new List <ScriptableObject>();

            for (int i = 0; i < nodeCanvas.nodes.Count; i++)
            {
                Node node = nodeCanvas.nodes[i];
                node.CheckNodeKnobMigration();
                Node node2 = AddClonedSO(allSOs, clonedSOs, node);
                AddClonedSOs(allSOs, clonedSOs, node2.GetScriptableObjects());
                foreach (NodeKnob nodeKnob3 in node2.nodeKnobs)
                {
                    AddClonedSO(allSOs, clonedSOs, nodeKnob3);
                    AddClonedSOs(allSOs, clonedSOs, nodeKnob3.GetScriptableObjects());
                }
            }
            for (int j = 0; j < nodeCanvas.nodes.Count; j++)
            {
                Node initialSO = nodeCanvas.nodes[j];
                Node node3     = ReplaceSO(allSOs, clonedSOs, initialSO);
                nodeCanvas.nodes[j] = node3;
                Node node4 = node3;
                node4.CopyScriptableObjects((ScriptableObject so) => ReplaceSO(allSOs, clonedSOs, so));
                for (int k = 0; k < node4.nodeKnobs.Count; k++)
                {
                    NodeKnob nodeKnob = ReplaceSO(allSOs, clonedSOs, node4.nodeKnobs[k]);
                    node4.nodeKnobs[k] = nodeKnob;
                    NodeKnob nodeKnob2 = nodeKnob;
                    nodeKnob2.body = node4;
                    nodeKnob2.CopyScriptableObjects((ScriptableObject so) => ReplaceSO(allSOs, clonedSOs, so));
                }
                for (int l = 0; l < node4.Inputs.Count; l++)
                {
                    NodeInput nodeInput = ReplaceSO(allSOs, clonedSOs, node4.Inputs[l]);
                    node4.Inputs[l] = nodeInput;
                    NodeInput nodeInput2 = nodeInput;
                    nodeInput2.body = node4;
                }
                for (int m = 0; m < node4.Outputs.Count; m++)
                {
                    NodeOutput nodeOutput = ReplaceSO(allSOs, clonedSOs, node4.Outputs[m]);
                    node4.Outputs[m] = nodeOutput;
                    NodeOutput nodeOutput2 = nodeOutput;
                    nodeOutput2.body = node4;
                }
            }
            if (editorStates)
            {
                nodeCanvas.editorStates = CreateWorkingCopy(nodeCanvas.editorStates, nodeCanvas);
                NodeEditorState[] editorStates2 = nodeCanvas.editorStates;
                foreach (NodeEditorState nodeEditorState in editorStates2)
                {
                    nodeEditorState.selectedNode = ReplaceSO(allSOs, clonedSOs, nodeEditorState.selectedNode);
                }
            }
            else
            {
                NodeEditorState[] editorStates3 = nodeCanvas.editorStates;
                foreach (NodeEditorState nodeEditorState2 in editorStates3)
                {
                    nodeEditorState2.selectedNode = null;
                }
            }
            return(nodeCanvas);
        }
Пример #3
0
        /// <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> ();

            for (int nodeCnt = 0; nodeCnt < nodeCanvas.nodes.Count; nodeCnt++)
            {
                Node node = nodeCanvas.nodes[nodeCnt];
                node.CheckNodeKnobMigration();
                Node clonedNode = (Node)AddClonedSO(allSOs, clonedSOs, node);
                for (int knobCnt = 0; knobCnt < clonedNode.nodeKnobs.Count; knobCnt++)
                {                 // Clone NodeKnobs
//					Debug.Log ("Cloned " + knobCnt + " " + (clonedNode.nodeKnobs[knobCnt] == null? "null" : clonedNode.nodeKnobs[knobCnt].name) + " on node " + node.name);
                    AddClonedSO(allSOs, clonedSOs, clonedNode.nodeKnobs[knobCnt]);
                    // Clone additional scriptableObjects
                    ScriptableObject[] additionalKnobSOs = clonedNode.nodeKnobs[knobCnt].GetScriptableObjects();
                    foreach (ScriptableObject so in additionalKnobSOs)
                    {
                        AddClonedSO(allSOs, clonedSOs, so);
                    }
                }
                for (int transCnt = 0; transCnt < clonedNode.transitions.Count; transCnt++)
                {                 // Clone Transitions
                    Transition trans = clonedNode.transitions[transCnt];
                    if (trans.startNode == node)
                    {
                        AddClonedSO(allSOs, clonedSOs, trans);
//						Debug.Log ("Did copy Transition " + trans.name + " because its Node " + clonedNode.name + " is the start node!");
                    }
                    else
                    {
//						Debug.Log ("Did NOT copy Transition " + trans.name + " because its Node " + clonedNode.name + " is NOT the start node (" + trans.startNode.name + ")!");
                        clonedNode.transitions.RemoveAt(transCnt);
                        transCnt--;
                    }
                }
                // 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

            nodeCanvas.currentNode       = ReplaceSO(allSOs, clonedSOs, nodeCanvas.currentNode);
            nodeCanvas.currentTransition = ReplaceSO(allSOs, clonedSOs, nodeCanvas.currentTransition);
            for (int nodeCnt = 0; nodeCnt < nodeCanvas.nodes.Count; nodeCnt++)
            {             // Clone Nodes, structural content and additional scriptableObjects
                Node node       = nodeCanvas.nodes[nodeCnt];
                Node clonedNode = nodeCanvas.nodes[nodeCnt] = ReplaceSO(allSOs, clonedSOs, node);
                // 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 knob = clonedNode.nodeKnobs[knobCnt] = ReplaceSO(allSOs, clonedSOs, clonedNode.nodeKnobs[knobCnt]);
                    knob.body = clonedNode;
                    // Replace additional scriptableObjects in the NodeKnob
                    knob.CopyScriptableObjects((ScriptableObject so) => ReplaceSO(allSOs, clonedSOs, so));
                    if (!compressed)
                    {                     // Add NodeInputs and NodeOutputs to the apropriate lists in Node if desired (!compressed)
                        if (knob is NodeInput)
                        {
                            clonedNode.Inputs.Add(knob as NodeInput);
                        }
                        else if (knob is NodeOutput)
                        {
                            clonedNode.Outputs.Add(knob as NodeOutput);
                        }
                    }
                }
                for (int transCnt = 0; transCnt < clonedNode.transitions.Count; transCnt++)
                {                 // Clone transitions
                    Transition trans = clonedNode.transitions[transCnt];
                    if (trans.startNode != node)
                    {
                        continue;
                    }
                    trans = clonedNode.transitions[transCnt] = ReplaceSO(allSOs, clonedSOs, trans);
                    if (trans == null)
                    {
                        Debug.LogError("Could not copy transition number " + transCnt + " of Node " + clonedNode.name + "!");
                        continue;
                    }

//					Debug.Log ("Did replace contents of Transition " + trans.name + " because its Node " + clonedNode.name + " is the start node!");
                    trans.startNode = ReplaceSO(allSOs, clonedSOs, trans.startNode);
                    trans.endNode   = ReplaceSO(allSOs, clonedSOs, trans.endNode);

                    if (!compressed)
                    {
                        trans.endNode.transitions.Add(trans);
                    }
                }
                // Replace additional scriptableObjects in the Node
                node.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 state = editorStates[stateCnt] = Clone(editorStates[stateCnt]);
                    state.canvas       = nodeCanvas;
                    state.focusedNode  = null;
                    state.selectedNode = state.selectedNode != null?ReplaceSO(allSOs, clonedSOs, state.selectedNode) : null;

                    state.makeTransition = null;
                    state.connectOutput  = null;
                }
            }
        }
        /// <summary>
        /// Creates a working copy of the specified nodeCanvas, and optionally also of it's associated editorStates.
        /// This breaks the link of this object to any stored assets and references. That means, that all changes to this object will have to be explicitly saved.
        /// </summary>
        public static NodeCanvas CreateWorkingCopy(NodeCanvas nodeCanvas, bool editorStates)
        {
            nodeCanvas.Validate(true);

            // Lists holding initial and cloned version of each ScriptableObject for later replacement of references
            List <ScriptableObject> allSOs    = new List <ScriptableObject> ();
            List <ScriptableObject> clonedSOs = new List <ScriptableObject> ();

            System.Func <ScriptableObject, ScriptableObject> copySOs = (ScriptableObject so) => ReplaceSO(allSOs, clonedSOs, so);

            // Clone and enter the canvas object and it's referenced SOs
            nodeCanvas = AddClonedSO(allSOs, clonedSOs, nodeCanvas);
            AddClonedSOs(allSOs, clonedSOs, nodeCanvas.GetScriptableObjects());

            // Iterate over the core ScriptableObjects in the canvas and clone them
            for (int nodeCnt = 0; nodeCnt < nodeCanvas.nodes.Count; nodeCnt++)
            {
                Node node = nodeCanvas.nodes[nodeCnt];
                node.CheckNodeKnobMigration();

                // Clone Node and additional scriptableObjects
                Node clonedNode = AddClonedSO(allSOs, clonedSOs, node);
                AddClonedSOs(allSOs, clonedSOs, clonedNode.GetScriptableObjects());

                // Clone NodeKnobs
                foreach (NodeKnob knob in clonedNode.nodeKnobs)
                {
                    AddClonedSO(allSOs, clonedSOs, knob);
                }
            }

            // Replace every reference to any of the initial SOs of the first list with the respective clones of the second list
            nodeCanvas.CopyScriptableObjects(copySOs);

            for (int nodeCnt = 0; nodeCnt < nodeCanvas.nodes.Count; nodeCnt++)
            {             // Replace SOs in all Nodes
                Node node = nodeCanvas.nodes[nodeCnt];

                // Replace node and additional ScriptableObjects with their copies
                Node clonedNode = nodeCanvas.nodes[nodeCnt] = ReplaceSO(allSOs, clonedSOs, node);
                clonedNode.CopyScriptableObjects(copySOs);

                // Replace NodeKnobs and restore Inputs/Outputs by NodeKnob type
                clonedNode.Inputs  = new List <NodeInput> ();
                clonedNode.Outputs = new List <NodeOutput> ();
                for (int knobCnt = 0; knobCnt < clonedNode.nodeKnobs.Count; knobCnt++)
                {                 // Clone generic NodeKnobs
                    NodeKnob knob = clonedNode.nodeKnobs[knobCnt] = ReplaceSO(allSOs, clonedSOs, clonedNode.nodeKnobs[knobCnt]);
                    knob.body = clonedNode;
                    knob.CopyScriptableObjects(copySOs);
                    // Add inputs/outputs to their lists again
                    if (knob is NodeInput)
                    {
                        clonedNode.Inputs.Add(knob as NodeInput);
                    }
                    else if (knob is NodeOutput)
                    {
                        clonedNode.Outputs.Add(knob as NodeOutput);
                    }
                }
            }

            if (editorStates)             // Clone the editorStates
            {
                nodeCanvas.editorStates = CreateWorkingCopy(nodeCanvas.editorStates, nodeCanvas);
            }
            // Fix references in editorStates to Nodes in the canvas
            foreach (NodeEditorState state in nodeCanvas.editorStates)
            {
                state.selectedNode = ReplaceSO(allSOs, clonedSOs, state.selectedNode);
            }

            return(nodeCanvas);
        }
Пример #5
0
        /// <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;
                }
            }
        }