// 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); }
public void SetBehaviourTree(BehaviorTree tree) { NodeSelection.ClearSelection(); Canvas = new BonsaiCanvas(tree); Viewer.Canvas = Canvas; Viewer.NodeSelection = NodeSelection; Viewer.zoom = tree.zoomPosition; Viewer.panOffset = tree.panPosition; }
public static BonsaiNode DuplicateSingle(BonsaiCanvas canvas, BonsaiNode original) { BonsaiNode duplicate = canvas.CreateNode(original.Behaviour.GetType()); // Duplicate nodes are placed offset from the original. duplicate.Position = original.Position + Vector2.one * 40f; return(duplicate); }
private void SaveTreeMetaData(TreeMetaData meta, BonsaiCanvas canvas) { foreach (var editorNode in canvas.Nodes) { editorNode.Behaviour.nodePosition = editorNode.Position; } canvas.Tree.panPosition = meta.pan; canvas.Tree.zoomPosition = meta.zoom; }
private void SetCompositeChildren(BonsaiCanvas canvas) { IEnumerable <BonsaiNode> compositeNodes = canvas.Nodes.Where(n => n.Behaviour.IsComposite()); foreach (BonsaiNode node in compositeNodes) { var compositeBehaviour = node.Behaviour as BTComposite; compositeBehaviour.SetChildren(node.Children.Select(ch => ch.Behaviour).ToArray()); } }
private void SetDecoratorChildren(BonsaiCanvas canvas) { IEnumerable <BonsaiNode> decoratorNodes = canvas.Nodes .Where(n => n.Behaviour.IsDecorator() && n.ChildCount() == 1); foreach (BonsaiNode node in decoratorNodes) { //Debug.LogError(node.Behaviour.name); var auxNode = node.Behaviour as BTAuxiliary; auxNode.SetChild(node.GetChildAt(0).Behaviour); } }
/// <summary> /// Duplicate multiple nodes and preserve the connections between parent and child nodes. /// </summary> /// <param name="canvas"></param> /// <param name="tree"></param> /// <param name="originals"></param> /// <returns></returns> public static List <BonsaiNode> DuplicateMultiple(BonsaiCanvas canvas, IEnumerable <BonsaiNode> originals) { var duplicateMap = originals.ToDictionary(og => og, og => DuplicateSingle(canvas, og)); // Reconstruct connection in clone nodes. foreach (BonsaiNode original in originals) { for (int i = 0; i < original.ChildCount(); i++) { // Only consider children if they were also cloned. if (duplicateMap.TryGetValue(original.GetChildAt(i), out BonsaiNode cloneChild)) { BonsaiNode cloneParent = duplicateMap[original]; cloneChild.SetParent(cloneParent); } } } return(duplicateMap.Values.ToList()); }
/// <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(); }