// 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;
 }
Exemple #3
0
        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);
            }
        }
Exemple #7
0
        /// <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();
        }