public void RandomTest() { var blackboard = new TestBlackboard(); var node = new Random <TestBlackboard>(); var tree = BehaviorTreeBuilder <TestBlackboard> .Begin() .Sequence() .Decorator(node).Leaf(new TrackingLeaf()) .Build(blackboard); ushort[] result = new ushort[2]; for (var i = 0; i < 100; i++) { this.UpdateAndStep(tree, 0.1f); if (node.Status == BTTaskStatus.Succeeded) { result[1]++; } else { result[0]++; } } // We should get a decently even spread but we can't rely on it, 50% sway should be plenty enough to have a stable result Assert.Greater(result[0], 25); Assert.Greater(result[1], 25); Assert.AreEqual(100, blackboard.GetTracking(TestBlackboard.TrackingExecution)); }
public static BehaviorTreeBuilder ExampleAction(this BehaviorTreeBuilder builder, string name, Action callback) { return(builder.AddNode(new BehaviorTreeBuilderExtensionActionTest.ExtensionAction { Name = name, callback = callback, })); }
[Test] public void TreeA() { MockCondition isSafe = new MockCondition(BehaviorStatus.Failure); MockCondition isFoodNearby = new MockCondition(BehaviorStatus.Success); MockAction run = new MockAction(BehaviorStatus.Running); MockAction eat = new MockAction(BehaviorStatus.Running); BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector()) .Sequence("Run") .Decorator(new Invert()) .Condition(isSafe) .Action(run) .End() .Sequence("Eat") .Condition(isFoodNearby) .Action(eat) .End() .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Running); run.status = BehaviorStatus.Success; Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success); isSafe.status = BehaviorStatus.Success; Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Running); eat.status = BehaviorStatus.Success; Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success); isFoodNearby.status = BehaviorStatus.Failure; Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure); }
[Test] public void Action_Success() { BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector()) .Action(new MockAction(BehaviorStatus.Success)) .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success); }
[Test] public void Condition_Failure() { BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector()) .Condition(new MockCondition(BehaviorStatus.Failure)) .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure); }
[Test] public void Sequence_BothChildrenFailure() { BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Sequence()) .Condition(new MockCondition(BehaviorStatus.Failure)) .Condition(new MockCondition(BehaviorStatus.Failure)) .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure); }
[Test] public void Sequence_FirstChildFailureAndNextChildSuccess() { BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Sequence()) .Condition(new MockCondition(BehaviorStatus.Failure)) .Condition(new MockCondition(BehaviorStatus.Success)) .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure); }
[Test] public void Selector_BothChildrenSuccess() { BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector()) .Condition(new MockCondition(BehaviorStatus.Success)) .Condition(new MockCondition(BehaviorStatus.Success)) .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success); }
[Test] public void Decorator_Invert_ChildFailure() { BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector()) .Decorator(new Invert()) .Condition(new MockCondition(BehaviorStatus.Failure)) .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success); }
[Test] public void Decorator_Repeat_ChildFailure() { Repeat repeat = new Repeat(10); BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector()) .Decorator(repeat) .Condition(new MockCondition(BehaviorStatus.Failure)) .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure); Assert.IsTrue(repeat.repetitionCount == 0); }
private void bulidSelfAbortTree() { var builder = BehaviorTreeBuilder <SlimeBehaviorTree> .begin(this); builder.selector(AbortTypes.Self); builder.conditionalDecorator(m => { return(m.slime.actorProperty.HP <= 0); }, false); builder.sequence() .logAction("-- dead! --") .action(m => m.slime.dead()) .endComposite(); builder.conditionalDecorator(m => { return(m.slime.startLostTarget); }); builder.sequence() .logAction("-- lostTarget!--") .action(m => m.slime.lostTarget()) .endComposite(); builder.conditionalDecorator( m => m.slime.isLostTarget, false ); builder.sequence() .logAction("--back! --") .action(m => m.slime.back()) .endComposite(); builder.conditionalDecorator( m => m.slime.isFindTarget, false ); builder.sequence() .logAction("--chase! --") .action(m => m.slime.chase()) .endComposite(); builder.sequence() .logAction("--idle --") //.action(m => m.slime.idle()) .waitAction(2f) .action(m => m.slime.patrol()) .endComposite() ; builder.endComposite(); tree = builder.build(1f / 60); }
protected override IBehaviorTreeNode createBehaviorTree() { BehaviorTreeBuilder builder = new BehaviorTreeBuilder(); return(AIExtensions.WithFightingAI( builder .Sequence() .End() .Build(), Entity )); }
static BehaviorTreeDesc BuildTreeDesc() { var builder = new BehaviorTreeBuilder(); builder.Composite <SequenceTaskDesc>() .AppendChild(builder.Leaf <LogTaskDesc>( d => d.Message = "Start")) .AppendChild(builder.Leaf <WaitTimerTaskDesc>( d => d.Time = new VariableDesc(VariableType.UInteger, VariableSource.LiteralConstant, "3000"))) .AppendChild(builder.Leaf <LogTaskDesc>(d => d.Message = "End")); return(builder.Build()); }
public void It_should_run_the_custom_action() { var result = false; var tree = new BehaviorTreeBuilder(null) .Sequence() .ExampleAction("test", () => result = true) .End() .Build(); tree.Tick(); Assert.IsTrue(result); }
protected override IBehaviorTreeNode createBehaviorTree() { BehaviorTreeBuilder builder = new BehaviorTreeBuilder(); return(AIExtensions.WithFightingAI( builder .Sequence() .LongRunningResultCached(() => new WaitTask(Entity, TimeSpan.FromMilliseconds(1000))) .LongRunningResultCached(() => new WanderTask(Entity, BlockStartPosition, BlockRadius)) .End() .Build(), Entity )); }
[Test] public void Sequence_FirstChildRunningAndNextChildSuccess() { MockAction mockActionA = new MockAction(BehaviorStatus.Running); BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Sequence()) .Action(mockActionA) .Condition(new MockCondition(BehaviorStatus.Success)) .Build(); Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Running); mockActionA.status = BehaviorStatus.Failure; Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure); }
protected override IBehaviorTreeNode createBehaviorTree() { BehaviorTreeBuilder builder = new BehaviorTreeBuilder(); return(AIExtensions.WithFightingAI( builder .Sequence() .LongRunningResultCached(() => new WaitTask(Entity, TimeSpan.FromMilliseconds(200))) .LongRunningResultCached(() => new FollowTask(Entity, targetID, tillDistance, teleportDistance)) .End() .Build(), Entity )); }
public void InvertTest() { var blackboard = new TestBlackboard(); var node = new Invert <TestBlackboard>(); var tree = BehaviorTreeBuilder <TestBlackboard> .Begin() .Sequence() .Decorator(node).Leaf(new TrackingLeaf()) .Build(blackboard); this.UpdateAndStep(tree, 0.1f); Assert.AreEqual(BTTaskStatus.Failed, node.Status); Assert.AreEqual(1, blackboard.GetTracking(TestBlackboard.TrackingExecution)); }
public void It_should_run_the_custom_action() { var result = false; var tree = new BehaviorTreeBuilder(null) .CustomSequence("test") .Do(() => { result = true; return(TaskStatus.Success); }) .End() .Build(); tree.Tick(); Assert.IsTrue(result); }
void Start() { BehaviorTreeBuilder builder = new BehaviorTreeBuilder(); builder.Sequence("sequence1"); builder.Action("action1", Action01); builder.Action("action2", Action02); builder.Sequence("sequence02"); builder.Action("action03", Action03); builder.Action("action04", Action04); builder.End(); builder.Action("Action05", Action05); builder.Action("Action06", Action06); builder.End(); tree = builder.Build(); }
public void It_should_not_fail_when_aborting_a_built_condition() { var treeAlt = new BehaviorTreeBuilder(null) .Sequence() .Condition(() => false) .End() .Build(); var tree = _builder .Parallel() .Splice(treeAlt) .Build(); Assert.DoesNotThrow(() => { tree.Tick(); }); }
protected override IBehaviorTreeNode createBehaviorTree() { BehaviorTreeBuilder builder = new BehaviorTreeBuilder(); return(AIExtensions.WithFightingAI( builder .Sequence() .LongRunningResultCached(() => new GoToTask(Entity, BlockGuardPosition)) .SingleStep((GameTime gameTime) => { Entity.Direction = LookDirection; return BehaviourTreeStatus.Success; }) .End() .Build(), Entity )); }
public static BehaviorTree <BehaviorTreeMinerState> BuildSelfAbortTree() { var builder = BehaviorTreeBuilder <BehaviorTreeMinerState> .Begin(new BehaviorTreeMinerState()); builder.Selector(AbortTypes.Self); // sleep is most important builder.ConditionalDecorator(m => m.MinerState.Fatigue >= MinerState.MAX_FATIGUE, false); builder.Sequence() .LogAction("--- Tired! Gotta go home") .Action(m => m.GoToLocation(MinerState.Location.Home)) .LogAction("--- Prep me my bed!") .Action(m => m.Sleep()) .EndComposite(); // thirst is next most important builder.ConditionalDecorator(m => m.MinerState.Thirst >= MinerState.MAX_THIRST, false); builder.Sequence() .LogAction("--- Thirsty! Time for a drink") .Action(m => m.GoToLocation(MinerState.Location.Saloon)) .LogAction("--- Get me a drink!") .Action(m => m.Drink()) .EndComposite(); // dropping off gold is next builder.ConditionalDecorator(m => m.MinerState.Gold >= MinerState.MAX_GOLD, false); builder.Sequence() .LogAction("--- Bags are full! Gotta drop this off at the bank.") .Action(m => m.GoToLocation(MinerState.Location.Bank)) .LogAction("--- Take me gold!") .Action(m => m.DepositGold()) .EndComposite(); // fetching gold is last builder.Sequence() .Action(m => m.GoToLocation(MinerState.Location.Mine)) .LogAction("--- Time to get me some gold!") .Action(m => m.DigForGold()) .EndComposite(); builder.EndComposite(); return(builder.Build()); }
// the same tree is here, once with LowerPriority aborts and once with Self aborts and ConditionalDecorators public void buildLowerPriorityAbortTree() { var builder = BehaviorTreeBuilder <BehaviorTreeMiner> .begin(this); builder.selector(); // sleep is most important builder.sequence(AbortTypes.LowerPriority) .conditional(m => m.minerState.fatigue >= MinerState.MAX_FATIGUE) .logAction("--- tired! gotta go home") .action(m => m.goToLocation(MinerState.Location.Home)) .logAction("--- prep me my bed!") .action(m => m.sleep()) .endComposite(); // thirst is next most important builder.sequence(AbortTypes.LowerPriority) .conditional(m => m.minerState.thirst >= MinerState.MAX_THIRST) .logAction("--- thirsty! time for a drink") .action(m => m.goToLocation(MinerState.Location.Saloon)) .logAction("--- get me a drink!") .action(m => m.drink()) .endComposite(); // dropping off gold is next builder.sequence(AbortTypes.LowerPriority) .conditional(m => m.minerState.gold >= MinerState.MAX_GOLD) .logAction("--- bags are full! gotta drop this off at the bank.") .action(m => m.goToLocation(MinerState.Location.Bank)) .logAction("--- take me gold!") .action(m => m.depositGold()) .endComposite(); // fetching gold is last builder.sequence() .action(m => m.goToLocation(MinerState.Location.Mine)) .logAction("--- time to get me some gold!") .action(m => m.digForGold()) .endComposite(); builder.endComposite(); _tree = builder.build(); }
// the same tree is here, once with LowerPriority aborts and once with Self aborts and ConditionalDecorators public void BuildLowerPriorityAbortTree() { var builder = BehaviorTreeBuilder <BehaviorTreeMiner> .Begin(this); builder.Selector(); // sleep is most important builder.Sequence(AbortTypes.LowerPriority) .Conditional(m => m.MinerState.Fatigue >= MinerState.MaxFatigue) .LogAction("--- tired! gotta go home") .Action(m => m.GoToLocation(MinerState.Location.Home)) .LogAction("--- prep me my bed!") .Action(m => m.Sleep()) .EndComposite(); // thirst is next most important builder.Sequence(AbortTypes.LowerPriority) .Conditional(m => m.MinerState.Thirst >= MinerState.MaxThirst) .LogAction("--- thirsty! time for a drink") .Action(m => m.GoToLocation(MinerState.Location.Saloon)) .LogAction("--- get me a drink!") .Action(m => m.Drink()) .EndComposite(); // dropping off gold is next builder.Sequence(AbortTypes.LowerPriority) .Conditional(m => m.MinerState.Gold >= MinerState.MaxGold) .LogAction("--- bags are full! gotta drop this off at the bank.") .Action(m => m.GoToLocation(MinerState.Location.Bank)) .LogAction("--- take me gold!") .Action(m => m.DepositGold()) .EndComposite(); // fetching gold is last builder.Sequence() .Action(m => m.GoToLocation(MinerState.Location.Mine)) .LogAction("--- time to get me some gold!") .Action(m => m.DigForGold()) .EndComposite(); builder.EndComposite(); _tree = builder.Build(); }
public static IBehaviorTreeNode WithFightingAI(IBehaviorTreeNode tree, MovingEntity entity) { BehaviorTreeBuilder builder = new BehaviorTreeBuilder(((RootNode)tree).TickFrequency); return(builder .Selector() .LongRunning(() => new FightTask(entity)) .Sequence() .SingleStepResultCached((GameTime gameTime) => { entity.StopWalking(); return BehaviourTreeStatus.Success; }) .Splice(tree) .End() .End() .Build()); }
public void FluentTreeBuilderTest() { var behaviorBuilder = new BehaviorTreeBuilder <AIContext>(); var tree = behaviorBuilder .Selector .Behavior(context => BehaviorResult.Success) .Sequence .Behavior(context => BehaviorResult.Success) .End .Sequence .Decorate(DecorateFor.AlwaysSucceeding) .Behavior(context => BehaviorResult.Success) .Sequence .Behavior(context => BehaviorResult.Success) .End .Question(context => 1 == 1) .End .End .Tree; }
public void IntervalTest() { var blackboard = new TestBlackboard(); var tree = BehaviorTreeBuilder <TestBlackboard> .Begin() .Sequence() .Interval().Leaf(new TrackingLeaf()) .Build(blackboard); for (var n = 0; n < 10; n++) { for (var i = 0; i < 9; i++) { this.UpdateAndStep(tree, 0.1f); } Assert.AreEqual(n, blackboard.GetTracking(TestBlackboard.TrackingExecution)); this.UpdateAndStep(tree, 0.1f); Assert.AreEqual(n + 1, blackboard.GetTracking(TestBlackboard.TrackingExecution)); } }
private void buildBehaviorTree() { //Initialize pathfinding _origin = (entity.position / Game1.TILE_SIZE).ToPoint(); _waypoints = _grid.search(new Point(_origin.X, _origin.Y), new Point(_origin.X + 5, _origin.Y)); BehaviorTreeBuilder <EnemyController> _behaviorTreeBuilder = BehaviorTreeBuilder <EnemyController> .begin(this); _behaviorTreeBuilder.untilSuccess(); //Creates a method with input of EnemyController and output of TaskStatus Func <EnemyController, TaskStatus> chasePlayer = delegate(EnemyController context) { if (target == null) { return(TaskStatus.Failure); } Point currentNode = (entity.position / Game1.TILE_SIZE).ToPoint(); Point targetNode = (target.position / Game1.TILE_SIZE).ToPoint(); _waypoints = _grid.search(currentNode, targetNode); _currentWaypointIndex = 0; //Check to see if path exists if (_waypoints == null) { return(TaskStatus.Failure); } return(TaskStatus.Running); }; _behaviorTreeBuilder.action(chasePlayer); _behaviorTree = _behaviorTreeBuilder.build(); }
public override void Init() { base.Init(); _boss.SetMaxHealth(MAX_HEALTH); #region behavior tree _tree = new BehaviorTreeBuilder(gameObject) .Selector() .Condition(() => _boss.IsDead) .Condition(() => _boss.IsInvincible) .Sequence() .Selector("Attack") .Sequence("Drone") .Condition(() => _attackType == AttackType.DRONE) .Do("Drone Attack", () => { DroneAttack(); return(TaskStatus.Success); }) .WaitTime(0.8f) .End() .Sequence("Shotgun") .Condition(() => _attackType == AttackType.SHOTGUN) .Do("Fire Shotgun", () => { FireShotgun(); return(TaskStatus.Success); }) .WaitTime(1.5f) .End() .Sequence("Laser") .Condition(() => _attackType == AttackType.LASER) .Do("Fire Laser", () => { Laser(Vector2.right); return(TaskStatus.Success); }) .WaitTime(3f) .End() .Sequence("ExplosionCore") .Condition(() => _attackType == AttackType.EXPLOSION_CORE) .Do("Fire Explosion Core", () => { FireExplosionCore(); return(TaskStatus.Success); }) .WaitTime(0.8f) .End() .Sequence("Smash") .Condition(() => _attackType == AttackType.SMASH) .Do("Smash Player", () => { Smash(); return(TaskStatus.Success); }) .WaitTime(3f) .End() .End() .Do("Choose Random Attack Type", () => { // _attackType = BS.Utils.Random.RandomEnum<AttackType>(); _attackType = AttackType.SMASH; return(TaskStatus.Success); }) .End() .Build(); #endregion }