public override void OnCompositeParentExit() { // Propogate composite parent exit through decorator chain only. // No need to call for composite children since composite nodes handle that. if (child && child.IsDecorator()) { child.OnCompositeParentExit(); } }
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); } }
/// <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); }