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; } }
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); }
/// <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)); } }