// Adds the tree to the database and saves the nodes to the database. private void SaveNewTree(string path, TreeMetaData meta, BonsaiCanvas canvas) { // Save tree and black board assets AssetDatabase.CreateAsset(canvas.Tree, path); AssetDatabase.AddObjectToAsset(canvas.Tree.Blackboard, canvas.Tree); // Save nodes. SaveTree(meta, canvas); }
private void SaveTreeMetaData(TreeMetaData meta, BonsaiCanvas canvas) { foreach (var editorNode in canvas.Nodes) { editorNode.Behaviour.bonsaiNodePosition = editorNode.Position; } canvas.Tree.panPosition = meta.pan; canvas.Tree.zoomPosition = meta.zoom; }
// Saves the current tree and nodes. private void SaveTree(TreeMetaData meta, BonsaiCanvas canvas) { // If the blackboard is not yet in the database, then add. AddBlackboardIfMissing(canvas.Tree); var treeBehaviours = canvas.Tree.AllNodes; var canvasBehaviours = canvas.Nodes.Select(n => n.Behaviour); // New nodes that need to be added to the database. foreach (BehaviourNode newNodes in canvasBehaviours.Except(treeBehaviours)) { newNodes.name = newNodes.GetType().Name; newNodes.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(newNodes, canvas.Tree); } // Clear all parent-child connections. These will be reconstructed to match the connection in the BonsaiNodes. canvas.Tree.ClearStructure(); // Sort the canvas. // Only consider nodes with 2 or more children for sorting. foreach (BonsaiNode node in canvas.Nodes.Where(node => node.ChildCount() > 1)) { node.SortChildren(); } // Set parent-child connections matching those in the canvas. Only consider decorators and composites. foreach (BonsaiNode node in canvas.Nodes.Where(node => node.ChildCount() > 0)) { foreach (BonsaiNode child in node.Children) { node.Behaviour.AddChild(child.Behaviour); } } // Re-add nodes to tree. foreach (BonsaiNode node in canvas.Nodes) { node.Behaviour.Tree = canvas.Tree; } if (canvas.Root != null) { canvas.Tree.Root = canvas.Root.Behaviour; } // Sort the nodes in pre order so it is easier to clone the tree. canvas.Tree.SortNodes(); SaveTreeMetaData(meta, canvas); AssetDatabase.SaveAssets(); }
/// <summary> /// Saves the behaviour tree from the canvas. /// If the tree is unsaved (new) then it prompts the user to specify a file to save. /// </summary> /// <param name="canvas"></param> public void SaveCanvas(BonsaiCanvas canvas, TreeMetaData meta) { // Tree is new, need to save to asset database. if (!AssetDatabase.Contains(canvas.Tree)) { GetSaveFilePath() .OnSuccess(savePath => { SaveNewTree(savePath, meta, canvas); OnTreeSaved(); }) .OnFailure(OnInvalidPathError); } // Tree is already saved. Save nodes and tree data. else { SaveTree(meta, canvas); OnTreeSaved(); } }
// Saves the current tree and nodes. private void SaveTree(TreeMetaData meta, BonsaiCanvas canvas) { // If the blackboard is not yet in the database, then add. AddBlackboardIfMissing(canvas.Tree); var canvasBehaviours = canvas.Nodes.Select(n => n.Behaviour); AddNewNodeAssets(canvas.Tree, canvasBehaviours); // Clear all parent-child connections. These will be reconstructed to match the connection in the BonsaiNodes. canvas.Tree.ClearStructure(); // Sort the canvas. // Only consider nodes with 2 or more children for sorting. foreach (BonsaiNode node in canvas.Nodes.Where(node => node.ChildCount() > 1)) { node.SortChildren(); } // Set parent-child connections matching those in the canvas. Only consider decorators and composites. SetCompositeChildren(canvas); SetDecoratorChildren(canvas); // Re-add nodes to tree. if (canvas.Root != null) { canvas.Tree.SetNodes(canvas.Root.Behaviour); } // Nodes not connected to he root will have an unset pre-order index. // Tree.ClearStructure unsets the index and is only set in Tree.SetNodes // for nodes under the root. canvas.Tree.unusedNodes = canvasBehaviours.Where( b => b.PreOrderIndex == BTNode.kInvalidOrder).ToList(); SaveTreeMetaData(meta, canvas); AssetDatabase.SaveAssets(); }