/// <summary> /// Behave /// </summary> /// <param name="status">Status of BehaviorTree</param> /// <returns>Result</returns> protected override BehaviorResult Behave(BehaviorTreeStatus status) { if (Priority == PriorityType.HighestPriority || RunningChildIndex < 0) { RunningChildIndex = 0; } BehaviorResult result = BehaviorResult.Failure; for (int i = RunningChildIndex; i < ChildCount; i++) { if (status.IsInterrupted) { break; } BehaviorContainer node = this[i]; status.Parameters = node.Parameters; node.Execute(status); result = node.Result; if (result == BehaviorResult.Running) { RunningChildIndex = i; break; } else { RunningChildIndex = -1; } if (result == BehaviorResult.Success) { ResetNext(i, status); break; } } return(result); }
/// <summary> /// Set child of decorator /// </summary> /// <param name="child">Child behavior</param> /// <param name="parameters">Optional parameters for child behavior at this position of tree</param> public virtual void SetChild(Behavior child, BehaviorParameterCollection parameters = null) { if (child != null) { Child = new BehaviorContainer(this, child, parameters); } }
private void ResetNext(int index, BehaviorTreeStatus status) { for (int i = index + 1; i < ChildCount; i++) { BehaviorContainer node = this[i]; node.Behavior.ResetBehavior(status); } }
/// <summary> /// each behavior before execution call this method to register in execution sequence. /// </summary> /// <param name="container">Behavior to register</param> /// <returns>Return registerd index</returns> /// <remarks> /// we need to keep last execution sequenece to aviod some mistakes in tree /// for example : at LimitAccessDecoratot execution, it must get access to key /// if the result be Running then it hold the key until next update (at least) /// if in next update a branch before that be executed we lost the key and never unlock it /// </remarks> internal void RegisterForExecution(BehaviorContainer container) { _CurrnetExecutionIndex++;// move to next place if (_CurrnetExecutionIndex >= _ExecutionSequence.Length) { throw new IndexOutOfRangeException("ExecutionSequence buffer is low. to avoid this error set higher value to 'BehaviorStatus.MaxSequenceLength'."); } _ExecutionSequence[_CurrnetExecutionIndex] = container; }
/// <summary> /// Behave /// </summary> /// <param name="status">Status of BehaviorTree</param> /// <returns>esult</returns> protected override BehaviorResult Behave(BehaviorTreeStatus status) { BehaviorResult result = BehaviorResult.Failure; if (RunningChildIndex < 0) { RunningChildIndex = 0; } for (int i = RunningChildIndex; i < ChildCount; i++) { if (status.IsInterrupted) { break; } BehaviorContainer node = this[i]; status.Parameters = node.Parameters; node.Execute(status); result = node.Result; if (result == BehaviorResult.Running) { RunningChildIndex = i; break; } else { RunningChildIndex = -1; } if (result == BehaviorResult.Failure) { break; } } if (result == BehaviorResult.Success) // cause loop next update and begin from child 0 { _LoopCounter++; if (LoopCount > 0 && _LoopCounter >= LoopCount) { result = BehaviorResult.Success; _LoopCounter = 0; } else { result = BehaviorResult.Running; } RunningChildIndex = 0; } else if (result == BehaviorResult.Failure) { _LoopCounter = 0; } return(result); }
/// <summary> /// iterate throw children and evaluate conditions /// </summary> /// <param name="status">Status of BehaviorTree</param> /// <returns></returns> private BehaviorResult CheckConditions(BehaviorTreeStatus status) { BehaviorResult result = BehaviorResult.Success; for (int i = 0; i < ChildCount; i++) { BehaviorContainer node = this[i]; status.Parameters = node.Parameters; if (node.Behavior.Type == BehaviorType.Condition) { node.Execute(status); BehaviorResult r = node.Result; if (r == BehaviorResult.Failure) { if (BreakOnConditionFailure && node.Behavior.Type == BehaviorType.Condition) { result = BehaviorResult.Failure; break; } else { _FailureCount++; } } // check failure policity if ((FailurePolicy == AI.FailurePolicy.FailOnOne && _FailureCount > 0) || (FailurePolicy == AI.FailurePolicy.FailOnAll && _FailureCount == ChildCount)) { result = BehaviorResult.Failure; break; } // check success policity if (SuccessPolicy == AI.SuccessPolicy.SucceedOnOne && r == BehaviorResult.Success) { result = BehaviorResult.Success; break; } // diable these lines because : conditions returns success or failure as result // if result of this node is running or result of any previous node is running, set result to running //if (r == BehaviorResult.Running || result != BehaviorResult.Running) //result = r; } } return(result); }
/// <summary> /// Behave /// </summary> /// <param name="status">Status od BehaviorTree</param> /// <returns>Result</returns> protected override BehaviorResult Behave(BehaviorTreeStatus status) { if (RunningChildIndex < 0) { RunningChildIndex = GetRandomIndex();// pick random node } BehaviorResult result = BehaviorResult.Failure; BehaviorContainer node = this[RunningChildIndex]; status.Parameters = node.Parameters; node.Execute(status); result = node.Result; if (result != BehaviorResult.Running) { RunningChildIndex = -1; } return(result); }
/// <summary> /// Behave /// </summary> /// <param name="status">Status od BehaviorTree</param> /// <returns>Result</returns> protected override BehaviorResult Behave(BehaviorTreeStatus status) { BehaviorResult result = BehaviorResult.Failure; if (RunningChildIndex < 0) { RunningChildIndex = 0; } for (int i = RunningChildIndex; i < ChildCount; i++) { if (status.IsInterrupted) { break; } BehaviorContainer node = this[i]; status.Parameters = node.Parameters; node.Execute(status); result = node.Result; if (result == BehaviorResult.Running) { RunningChildIndex = i; break; } else { RunningChildIndex = -1; } if (result == BehaviorResult.Failure) { break; } } if (result != BehaviorResult.Running) { RunningChildIndex = -1; } return(result); }
/// <summary> /// Behave /// </summary> /// <param name="status">status of BehaviorTree</param> /// <returns>Result</returns> protected override BehaviorResult Behave(BehaviorTreeStatus status) { _FailureCount = 0; _SuccessCount = 0; CreateChildrenExecution(); // make sure the _ChildrenResults array is valid BehaviorResult result = BehaviorResult.Running; // by default running // iterate throw children an execute them for (int i = 0; i < ChildCount; i++) { if (status.IsInterrupted) { ResetChildrenExecution(); break; } BehaviorContainer node = this[i]; status.Parameters = node.Parameters; if (_ChildrenExecution[i]) { if (node.Behavior.Concurrency == ConcurrencyMode.UntilFailure && node.Behavior.Result == BehaviorResult.Failure) { _FailureCount++; if ((FailurePolicy == AI.FailurePolicy.FailOnOne && _FailureCount > 0) || (FailurePolicy == AI.FailurePolicy.FailOnAll && _FailureCount == ChildCount)) { result = BehaviorResult.Failure; break; } continue; } else if (node.Behavior.Concurrency == ConcurrencyMode.UntilSuccess && node.Behavior.Result == BehaviorResult.Success) { _SuccessCount++; if (SuccessPolicy == AI.SuccessPolicy.SucceedOnAll) { if (_SuccessCount == ChildCount) { result = BehaviorResult.Success; break; } } continue; } } // if this node executed first ignore it //if (FirstConditions && node.Behavior.Type == BehaviorType.Condition) continue; node.Execute(status);// execute child node BehaviorResult childResult = node.Result; if (childResult == BehaviorResult.Failure) { if (BreakOnConditionFailure && node.Behavior.Type == BehaviorType.Condition) { result = BehaviorResult.Failure; break; } else { _FailureCount++; } } else if (childResult == BehaviorResult.Success) { _SuccessCount++; } // check failure policity if ((FailurePolicy == AI.FailurePolicy.FailOnOne && _FailureCount > 0) || (FailurePolicy == AI.FailurePolicy.FailOnAll && _FailureCount == ChildCount)) { result = BehaviorResult.Failure; break; } // check success policity if (SuccessPolicy == AI.SuccessPolicy.SucceedOnOne) { if (childResult == BehaviorResult.Success) { result = BehaviorResult.Success; break; } } else if (SuccessPolicy == AI.SuccessPolicy.SucceedOnAll) { if (_SuccessCount == ChildCount) { result = BehaviorResult.Success; break; } } //// if result of this node is running or result of any previous node is running, set result to running //if (childResult == BehaviorResult.Running || result != BehaviorResult.Running) // result = childResult; _ChildrenExecution[i] = true; } if (result != BehaviorResult.Running) { ResetChildrenExecution(); } return(result); }