public static Task <AIResult> Exec(GameObject gameObject, AITreeNode tree, Dictionary <string, object> arguments, AITreeAsset asset = null) { if (gameObject.GetComponent <BaseAIBehaviours>() == null) { gameObject.AddComponent <BaseAIBehaviours>(); } TaskCompletionSource <AIResult> result = new TaskCompletionSource <AIResult>(); var executor = gameObject.AddComponent <AIExecutor>(); executor.result = result; executor.asset = asset; executor.arguments = arguments; executor.executionTree = tree .Call( new AIExecutionContext( gameObject, executor.Log, null, new TreeArguments( executor.arguments, gameObject.GetComponent <AIMemory>()))) .GetEnumerator(); return(result.Task); }
private IEnumerable <AIResult> ProcessIfThenChild(AITreeNode node, AIExecutionContext context) { if (node == null) { yield return(AIResult.Failure); } bool breakLoop = false; foreach (var result in node.Call(context)) { switch (result) { case AIResult.Success: yield return(AIResult.Success); breakLoop = true; break; case AIResult.Failure: yield return(AIResult.Failure); breakLoop = true; break; case AIResult.Running: yield return(AIResult.Running); break; } if (breakLoop) { break; } } }
public IEnumerable <AIResult> IfElse(AIExecutionContext context) { GameObject gameObject = context.gameObject; AITreeNode[] children = context.children; AIExecutionLog log = context.log; IReadOnlyDictionary <object, object> memoryMap = context.memoryMap; AITreeNode ifChild = null, thenChild = null, elseChild = null; if (children.Length >= 1) { ifChild = children[0]; } if (children.Length >= 2) { thenChild = children[1]; } if (children.Length >= 3) { elseChild = children[2]; } bool?success = false; if (ifChild != null) { bool breakIfElseLoop = false; foreach (var result in ifChild.Call(context)) { switch (result) { case AIResult.Success: success = true; breakIfElseLoop = true; break; case AIResult.Failure: success = false; breakIfElseLoop = true; break; case AIResult.Running: break; } if (breakIfElseLoop) { break; } } } if (success == null) { yield return(AIResult.Failure); } else { foreach (var result in ProcessIfThenChild(success.Value ? thenChild : elseChild, context)) { // Process if then child method will ensure appropriate returns yield return(result); } } }