private void ClearChildrenStructure(BehaviourNode node)
        {
            if (node.IsComposite())
            {
                var composite = node as Composite;
                composite.SetChildren(new BehaviourNode[] { });
            }

            else if (node.IsDecorator())
            {
                var decorator = node as Decorator;
                decorator.SetChild(null);
            }
        }
        private static void GetCompositeParent(
            BehaviourNode child,
            out BehaviourNode compositeParent,
            out int branchIndex)
        {
            compositeParent = child.Parent;
            branchIndex     = child.indexOrder;

            while (compositeParent && !compositeParent.IsComposite())
            {
                branchIndex     = compositeParent.indexOrder;
                compositeParent = compositeParent.Parent;
            }
        }
Exemplo n.º 3
0
        private BehaviourNode PopNode()
        {
            int           index = traversal.Pop();
            BehaviourNode node  = tree.Nodes[index];

            if (node.IsComposite())
            {
                for (int i = 0; i < node.ChildCount(); i++)
                {
                    node.GetChildAt(i).OnCompositeParentExit();
                }
            }

            node.OnExit();
            return(node);
        }
        /// <summary>
        /// Deep copies the tree.
        /// </summary>
        /// <param name="sourceTree">The source tree to clone.</param>
        /// <returns>The cloned tree.</returns>
        public static BehaviourTree Clone(BehaviourTree sourceTree)
        {
            // The tree clone will be blank to start. We will duplicate blackboard and nodes.
            var cloneBt = CreateInstance <BehaviourTree>();

            cloneBt.name = sourceTree.name;

            if (sourceTree.blackboard)
            {
                cloneBt.blackboard = Instantiate(sourceTree.blackboard);
            }

            // Source tree nodes should already be in pre-order.
            cloneBt.SetNodes(sourceTree.Nodes.Select(n => Instantiate(n)));

            // Relink children and parents for the cloned nodes.
            int maxCloneNodeCount = cloneBt.allNodes.Length;

            for (int i = 0; i < maxCloneNodeCount; ++i)
            {
                BehaviourNode nodeSource = sourceTree.allNodes[i];
                BehaviourNode copyNode   = GetInstanceVersion(cloneBt, nodeSource);

                if (copyNode.IsComposite())
                {
                    var copyComposite = copyNode as Composite;
                    copyComposite.SetChildren(
                        Enumerable.Range(0, nodeSource.ChildCount())
                        .Select(childIndex => GetInstanceVersion(cloneBt, nodeSource.GetChildAt(childIndex)))
                        .ToArray());
                }

                else if (copyNode.IsDecorator() && nodeSource.ChildCount() == 1)
                {
                    var copyDecorator = copyNode as Decorator;
                    copyDecorator.SetChild(GetInstanceVersion(cloneBt, nodeSource.GetChildAt(0)));;
                }
            }

            foreach (BehaviourNode node in cloneBt.allNodes)
            {
                node.OnCopy();
            }

            return(cloneBt);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Tells the iterator to abort the current running branch and jump to the aborter.
        /// </summary>
        /// <param name="parent">The parent that will abort is running branch.</param>
        /// <param name="abortBranchIndex">The child branch that caused the abort.</param>
        public void AbortRunningChildBranch(BehaviourNode parent, int abortBranchIndex)
        {
            // If the iterator is inactive, ignore.
            if (IsRunning && parent)
            {
                int terminatingIndex = parent.preOrderIndex;

                while (traversal.Count != 0 && traversal.Peek() != terminatingIndex)
                {
                    StepBackAbort();
                }

                // Only composite nodes need to worry about which of their subtrees fired an abort.
                if (parent.IsComposite())
                {
                    parent.OnAbort(abortBranchIndex);
                }

                // Any requested traversals are cancelled on abort.
                requestedTraversals.Clear();

                Traverse(parent.GetChildAt(abortBranchIndex));
            }
        }