Install-Package BehaviourTree
https://www.youtube.com/watch?v=OeVo2l-O0vU
- Generic context
- Extensible
- Fluent Builder
- Basic node types included
- Tree visualizer (Coming soon)
var behaviourTree = FluentBuilder.Create<MyContext>()
.Sequence("root")
.Do("walk to door", WalkToDoorFunc)
.Selector("open door sequence")
.Do("open door", OpenDoorFunc)
.Sequence("locked door sequence")
.Do("unlock door", UnlockDoorFunc)
.Do("open door", OpenDoorFunc)
.End()
.Do("smash door", SmashDoorFunc)
.End()
.Do("walk through door", WalkThroughDoorFunc)
.Do("close door", CloseDoorFunc)
.End()
.Build();
builder.Do("my-action", context => BehaviourStatus.Succeeded)
builder.Wait("my-wait", 3000) // 3 seconds
builder.Condition("my-condition", context => true)
builder.Sequence("my-sequence")
.Do("action1", context => BehaviourStatus.Succeeded)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
builder.Selector("my-selector")
.Do("action1", context => BehaviourStatus.Failed)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
builder.RandomSequence("my-random-sequence")
.Do("action1", context => BehaviourStatus.Succeeded)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
builder.RandomSelector("my-random-selector")
.Do("action1", context => BehaviourStatus.Failed)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
builder.PrioritySequence("my-priority-sequence")
.Do("action1", context => BehaviourStatus.Succeeded)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
builder.PrioritySelector("my-priority-selector")
.Do("action1", context => BehaviourStatus.Failed)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
public enum SimpleParallelPolicy
{
BothMustSucceed,
OnlyOneMustSucceed
}
var policy = SimpleParallelPolicy.BothMustSucceed;
builder.SimpleParallel("my-parallel", policy)
.Do("action1", context => BehaviourStatus.Running)
.Do("action2", context => BehaviourStatus.Running)
.End()
builder.Cooldown("my-cooldown", 4000) // 4 seconds
.Do("action1", context => BehaviourStatus.Failed)
.End()
builder.AlwaysFail("my-failer")
.Do("action1", context => BehaviourStatus.Succeeded)
.End()
builder.AlwaysSucceed("my-succeeder")
.Do("action1", context => BehaviourStatus.Failed)
.End()
builder.Invert("my-inverter")
.Do("action1", context => BehaviourStatus.Failed)
.End()
builder.LimitCallRate("my-rate-limiter", 1000) // 1 second
.Do("action1", context => BehaviourStatus.Failed)
.End()
builder.Repeat("my-repeater", 5)
.Do("action1", context => BehaviourStatus.Failed)
.End()
builder.TimeLimit("my-time-limit", 5000) // has 5 seconds to complete or will fail
.Do("action1", context => BehaviourStatus.Running)
.End()
builder.UntilSuccess("my-until-success")
.Do("action1", context => BehaviourStatus.Failed)
.End()
builder.UntilFailed("my-until-failed")
.Do("action1", context => BehaviourStatus.Succeeded)
.End()
builder.Random("my-random", 0.6) // will call child 60% of the time
.Do("action1", context => BehaviourStatus.Succeeded)
.End()
builder.SubTree("my-sub-tree", otherBehaviourTree)