// A Selector may be contaminated with other nodes (Condition) or IParentBeahviourTreeNodes over which
        // it's behaviour as a selector is applied. The assumption here is that any item in it's child list
        // should have  selector behaviour applied unless the first one is a condition Action.
        public BehaviourTreeStatus Tick(TimeData time)
        {
            int skipOne = 0;
            // check if this is a conditional action
            IBehaviourTreeNode firstNode = children[0];

            if (firstNode is ConditionNode)
            {
                ConditionNode firstChild = (ConditionNode)firstNode;
                var           status     = firstChild.Tick(time);
                if (status != BehaviourTreeStatus.Success)
                {
                    return(BehaviourTreeStatus.Success);
                }
                ++skipOne;
            }

            List <IBehaviourTreeNode> remainingChildren = children.Skip(skipOne).ToList <IBehaviourTreeNode>();

            if (isRandom)
            {
                remainingChildren = Randomize(remainingChildren);
            }

            foreach (var child in remainingChildren)
            {
                var childStatus = child.Tick(time);
                if (childStatus != BehaviourTreeStatus.Failure)
                {
                    return(childStatus);
                }
            }

            return(BehaviourTreeStatus.Failure);
        }
        /// <summary>
        /// Like an action node... but the function can return true/false and is mapped to success/failure.
        /// </summary>
        public BehaviourTreeBuilder Condition(string name, Func <TimeData, bool> fn)
        {
            if (parentNodeStack.Count <= 0)
            {
                throw new ApplicationException("Can't create an unnested ActionNode, it must be a leaf node.");
            }

            var conditionNode = new ConditionNode(name, fn);

            parentNodeStack.Peek().AddChild(conditionNode);
            return(this);
        }
Beispiel #3
0
        // A Selector may be contaminated with other nodes (Condition) or IParentBeahviourTreeNodes over which
        // it's behaviour as a selector is applied. The assumption here is that any item in it's child list
        // should have  selector behaviour applied unless the first one is a condition Action.
        public IEnumerator <BehaviourTreeStatus> Tick(TimeData time)
        {
            int skipOne = 0;
            // check if this is a conditional action
            IBehaviourTreeNode firstNode = children[0];

            if (firstNode is ConditionNode)
            {
                ConditionNode firstChild = (ConditionNode)firstNode;
                var           status     = firstChild.Tick(time);
                status.MoveNext();

                if (status.Current != BehaviourTreeStatus.Success)
                {
                    // Return Failure and Exit the Node
                    currentStatus = BehaviourTreeStatus.Failure;
                    yield return(currentStatus);

                    yield break;
                }
                else
                {
                    ++skipOne;
                }
            }

            List <IBehaviourTreeNode> remainingChildren = children.Skip(skipOne).ToList <IBehaviourTreeNode>();

            if (isRandom)
            {
                remainingChildren = Randomize(remainingChildren);
            }

            foreach (var child in remainingChildren)
            {
                var childStatus = child.Tick(time);
                childStatus.MoveNext();
                currentStatus = childStatus.Current;
                if (isRunning())
                {
                    // keep looping until we exit running mode or we
                    // run out of enum values.
                    yield return(currentStatus);

                    while (childStatus.MoveNext())
                    {
                        currentStatus = childStatus.Current;
                        if (!isRunning())
                        {
                            break;
                        }
                    }
                }
                // On exit above, status should be success or fail
                // if success, then exit selector
                if (isSuccess())
                {
                    yield return(currentStatus);

                    yield break;
                }
            }

            yield return(currentStatus);
        }