BehaviourTree
BehaviourTree copied to clipboard
BehaviourTree
Installation
Install-Package BehaviourTree
Demo
https://www.youtube.com/watch?v=OeVo2l-O0vU
Features
- Generic context
- Extensible
- Fluent Builder
- Basic node types included
- Tree visualizer (Coming soon)
Usage (FluentBuilder)
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();
Node Types
Leaves
Action
builder.Do("my-action", context => BehaviourStatus.Succeeded)
Wait
builder.Wait("my-wait", 3000) // 3 seconds
Condition
builder.Condition("my-condition", context => true)
Composites
Sequence
builder.Sequence("my-sequence")
.Do("action1", context => BehaviourStatus.Succeeded)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
Selector
builder.Selector("my-selector")
.Do("action1", context => BehaviourStatus.Failed)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
RandomSequence
builder.RandomSequence("my-random-sequence")
.Do("action1", context => BehaviourStatus.Succeeded)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
RandomSelector
builder.RandomSelector("my-random-selector")
.Do("action1", context => BehaviourStatus.Failed)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
PrioritySequence
builder.PrioritySequence("my-priority-sequence")
.Do("action1", context => BehaviourStatus.Succeeded)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
PrioritySelector
builder.PrioritySelector("my-priority-selector")
.Do("action1", context => BehaviourStatus.Failed)
.Do("action2", context => BehaviourStatus.Succeeded)
.Do("action3", context => BehaviourStatus.Succeeded)
...
.End()
SimpleParallel
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()
Decorators
Cooldown
builder.Cooldown("my-cooldown", 4000) // 4 seconds
.Do("action1", context => BehaviourStatus.Failed)
.End()
Failer
builder.AlwaysFail("my-failer")
.Do("action1", context => BehaviourStatus.Succeeded)
.End()
Succeeder
builder.AlwaysSucceed("my-succeeder")
.Do("action1", context => BehaviourStatus.Failed)
.End()
Inverter
builder.Invert("my-inverter")
.Do("action1", context => BehaviourStatus.Failed)
.End()
RateLimiter (Cache)
builder.LimitCallRate("my-rate-limiter", 1000) // 1 second
.Do("action1", context => BehaviourStatus.Failed)
.End()
Repeat
builder.Repeat("my-repeater", 5)
.Do("action1", context => BehaviourStatus.Failed)
.End()
TimeLimit
builder.TimeLimit("my-time-limit", 5000) // has 5 seconds to complete or will fail
.Do("action1", context => BehaviourStatus.Running)
.End()
UntilSuccess
builder.UntilSuccess("my-until-success")
.Do("action1", context => BehaviourStatus.Failed)
.End()
UntilFailed
builder.UntilFailed("my-until-failed")
.Do("action1", context => BehaviourStatus.Succeeded)
.End()
Random
builder.Random("my-random", 0.6) // will call child 60% of the time
.Do("action1", context => BehaviourStatus.Succeeded)
.End()
SubTree
builder.SubTree("my-sub-tree", otherBehaviourTree)