예제 #1
0
    public override BTCoroutine Procedure()
    {
        foreach (BTNode node in subNodes)
        {
            BTCoroutine routine = node.Procedure();

            while (routine.MoveNext())
            {
                BTNodeResult result = routine.Current;

                if (result == BTNodeResult.Success)
                {
                    yield return(BTNodeResult.Success);

                    yield break;
                }
                else
                {
                    yield return(BTNodeResult.NotFinished);

                    if (result == BTNodeResult.Failure)
                    {
                        break;
                    }
                }
            }
        }

        yield return(BTNodeResult.Failure);
    }
예제 #2
0
    public override BTCoroutine Procedure()
    {
        while (true)
        {
            if (GetStopper().shouldStop)
            {
                GetStopper().shouldStop = false;
                yield return(BTNodeResult.Stopped);

                yield break;
            }

            BTCoroutine routine = childNode.Procedure();

            while (routine.MoveNext())
            {
                BTNodeResult result = routine.Current;

                if (result == BTNodeResult.Stopped)
                {
                    GetStopper().shouldStop = false;
                    yield return(BTNodeResult.Stopped);

                    yield break;
                }

                else if (result == BTNodeResult.Success)
                {
                    if (type == BTRepeatTypes.UntilSuccess)
                    {
                        yield return(BTNodeResult.Success);

                        yield break;
                    }
                }
                else if (result == BTNodeResult.Failure)
                {
                    if (type == BTRepeatTypes.UntilFailure)
                    {
                        yield return(BTNodeResult.Failure);

                        yield break;
                    }
                }
                yield return(BTNodeResult.Running);

                if (GetStopper().shouldStop)
                {
                    childNode.Stop();
                }
            }
        }
    }
예제 #3
0
    public override BTCoroutine Procedure()
    {
        foreach (BTNode node in subNodes)
        {
            BTCoroutine routine = node.Procedure();

            while (routine.MoveNext())
            {
                BTNodeResult result = routine.Current;

                if (result == BTNodeResult.Stopped)
                {
                    GetStopper().shouldStop = false;
                    yield return(BTNodeResult.Stopped);

                    yield break;
                }

                if (result == BTNodeResult.Success)
                {
                    yield return(BTNodeResult.Success);

                    yield break;
                }
                else if (result == BTNodeResult.Failure)
                {
                    break;
                }
                else /*if (result == BTNodeResult.Running)*/
                {
                    yield return(BTNodeResult.Running);

                    if (GetStopper().shouldStop)
                    {
                        node.Stop();
                    }
                }
            }
        }

        yield return(BTNodeResult.Failure);

        yield break;
    }
예제 #4
0
    public override BTCoroutine Procedure()
    {
        BTCoroutine routine = childNode.Procedure();

        while (routine.MoveNext())
        {
            BTNodeResult result = routine.Current;

            if (result == BTNodeResult.NotFinished)
            {
                yield return(BTNodeResult.NotFinished);
            }
            else
            {
                yield return(result == BTNodeResult.Failure ? BTNodeResult.Success : BTNodeResult.Failure);

                yield break;
            }
        }
    }
예제 #5
0
    public override BTCoroutine Procedure()
    {
        // First time initialization
        int bestCondition = ScoreConditions();

        if (bestCondition == -1)
        {
            // This shouldn't happen, there should always be a "default" condition that always succeeds at the end
            yield return(BTNodeResult.Failure);

            yield break;
        }

        currentRunningNode = bestCondition;
        BTCoroutine routine = actions[currentRunningNode].Procedure();

        // Routine loop
        while (true)
        {
            frameTicker++;

            if (frameTicker >= evalFrequency)
            {
                bestCondition = ScoreConditions();
                if (bestCondition == -1)
                {
                    // This shouldn't happen, there should always be a "default" condition that always succeeds at the end
                    yield return(BTNodeResult.Failure);

                    yield break;
                }
                frameTicker = 0;
            }

            if (currentRunningNode != bestCondition)
            {
                if (currentRunningNode != -1)
                {
                    actions[currentRunningNode].Stop();
                    routine.MoveNext();
                    if (routine.Current != BTNodeResult.Stopped)
                    {
                        throw new Exception("On stopping current node in decision");
                    }
                }

                routine            = actions[bestCondition].Procedure();
                currentRunningNode = bestCondition;
            }

            routine.MoveNext();
            BTNodeResult result = routine.Current;

            if (result == BTNodeResult.Stopped)
            {
                throw new Exception("Current node got stopped in decision");
            }
            else if (result == BTNodeResult.Success)
            {
                currentRunningNode = -1;
                frameTicker        = evalFrequency;
            }
            else if (result == BTNodeResult.Failure)
            {
                conditions[currentRunningNode].TriggerCooldown();
                currentRunningNode = -1;
                frameTicker        = evalFrequency;
            }

            yield return(BTNodeResult.Running);
        }
    }
예제 #6
0
    private int ScoreConditions()
    {
        float bestScore            = float.MinValue;
        int   bestScoreIndex       = -1;
        float currentScore         = 0;
        float tempCurrentNodeScore = -1f;

        List <float> debugScores = new List <float>();

        if (currentRunningNode != -1)
        {
            BTCoroutine routine = conditions[currentRunningNode].Procedure();
            routine.MoveNext();
            BTNodeResult result = routine.Current;

            if (result == BTNodeResult.Success)
            {
                tempCurrentNodeScore = conditions[currentRunningNode].GetScorer().score;
                debugScores.Add(conditions[currentRunningNode].GetScorer().score);
            }
            else
            {
                debugScores.Add(-1f);
            }
        }

        for (int i = 0; i < conditions.Length; i++)
        {
            if (i == currentRunningNode)
            {
                debugScores.Add(-2f);
                continue;
            }

            BTCoroutine routine = conditions[i].Procedure();
            routine.MoveNext();
            BTNodeResult result = routine.Current;

            if (result == BTNodeResult.Success)
            {
                currentScore = conditions[i].GetScorer().score;
                debugScores.Add(currentScore);
                if (currentScore > bestScore)
                {
                    bestScoreIndex = i;
                    bestScore      = currentScore;
                }
            }
            else
            {
                debugScores.Add(-1f);
            }
        }

        if (bestScore >= tempCurrentNodeScore + switchThreshold)
        {
            return(bestScoreIndex);
        }
        else
        {
            return(currentRunningNode);
        }
    }
예제 #7
0
    public override BTCoroutine Procedure()
    {
        List <BTCoroutine> runningCoroutines = new List <BTCoroutine>();
        List <BTNode>      runningNodes      = new List <BTNode>();

        foreach (BTNode node in subNodes)
        {
            // First do one pass, then only iterate over 'running' nodes if needed
            BTCoroutine routine = node.Procedure();
            routine.MoveNext();
            BTNodeResult result = routine.Current;

            if (result == BTNodeResult.Success)
            {
                if (type == BTParallelTypes.FirstReturn ||
                    type == BTParallelTypes.FirstSuccess)
                {
                    yield return(BTNodeResult.Success);

                    yield break;
                }
            }
            else if (result == BTNodeResult.Failure)
            {
                if (type == BTParallelTypes.FirstReturn ||
                    type == BTParallelTypes.FirstFailure)
                {
                    yield return(BTNodeResult.Failure);

                    yield break;
                }
            }
            else if (result == BTNodeResult.Running)
            {
                runningCoroutines.Add(routine);
                runningNodes.Add(node);
            }
        }

        BTNodeResult returnValue = BTNodeResult.Running;

        while (runningCoroutines.Count() != 0)
        {
            // Keep running as long as there are running child nodes (even if they are supposed to stop)
            yield return(BTNodeResult.Running);

            // On second pass iterate over running nodes
            // It is assumed that nodes that can run over more than one frame will
            // yield Stopped on their next iteration
            if (GetStopper().shouldStop)
            {
                foreach (BTNode node in runningNodes)
                {
                    node.Stop();
                }
            }

            bool[] markedForDelete = new bool[runningCoroutines.Count()];

            for (int i = 0; i < runningCoroutines.Count(); i++)
            {
                runningCoroutines[i].MoveNext();

                if (runningCoroutines[i].Current == BTNodeResult.Success)
                {
                    markedForDelete[i] = true;

                    if (type == BTParallelTypes.FirstReturn ||
                        type == BTParallelTypes.FirstSuccess)
                    {
                        returnValue = BTNodeResult.Success;
                        SendStopToRunning(runningNodes, markedForDelete);
                    }
                }
                else if (runningCoroutines[i].Current == BTNodeResult.Failure)
                {
                    markedForDelete[i] = true;

                    if (type == BTParallelTypes.FirstReturn ||
                        type == BTParallelTypes.FirstFailure)
                    {
                        returnValue = BTNodeResult.Failure;
                        SendStopToRunning(runningNodes, markedForDelete);
                    }
                }
                else if (runningCoroutines[i].Current == BTNodeResult.Stopped)
                {
                    markedForDelete[i] = true;
                }
                else if (runningCoroutines[i].Current == BTNodeResult.Running)
                {
                    // Do noting
                }
            }

            // Do one more pass to let running nodes stop if they were notified to stop
            if (returnValue == BTNodeResult.Failure || returnValue == BTNodeResult.Success)
            {
                for (int i = 0; i < runningCoroutines.Count(); i++)
                {
                    runningCoroutines[i].MoveNext();
                    if (!markedForDelete[i] && runningCoroutines[i].Current == BTNodeResult.Stopped)
                    {
                        markedForDelete[i] = true;
                    }
                }
            }

            for (int i = markedForDelete.Count() - 1; i >= 0; i--)
            {
                if (markedForDelete[i])
                {
                    runningCoroutines.RemoveAt(i);
                    runningNodes.RemoveAt(i);
                }
            }
        }

        // At this point there are no more running nodes
        if (GetStopper().shouldStop)
        {
            GetStopper().shouldStop = false;
            yield return(BTNodeResult.Stopped);

            yield break;
        }
        else
        {
            yield return(returnValue);

            yield break;
        }
    }