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