Skip to content

Commit 41fd957

Browse files
committed
Added BT builder with sequences and tasks
1 parent 260d694 commit 41fd957

File tree

9 files changed

+201
-3
lines changed

9 files changed

+201
-3
lines changed

Assets/FluidBehaviorTree/Scripts/BehaviorTree/BehaviorTree.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ public BehaviorTree (GameObject owner) {
1515
SyncNodes(Root);
1616
}
1717

18-
public void Tick () {
19-
if (Root.Update() != TaskStatus.Continue) {
18+
public TaskStatus Tick () {
19+
var status = Root.Update();
20+
if (status != TaskStatus.Continue) {
2021
TickCount++;
2122
}
23+
24+
return status;
2225
}
2326

2427
public void Reset () {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Adnc.FluidBT.TaskParents;
4+
using Adnc.FluidBT.TaskParents.Composites;
5+
using Adnc.FluidBT.Tasks;
6+
using Adnc.FluidBT.Tasks.Actions;
7+
using UnityEngine;
8+
9+
namespace Adnc.FluidBT.Trees {
10+
public class BehaviorTreeBuilder {
11+
private readonly BehaviorTree _tree;
12+
private readonly List<ITaskParent> _pointer = new List<ITaskParent>();
13+
14+
private ITaskParent Pointer {
15+
get {
16+
if (_pointer.Count == 0) return null;
17+
return _pointer[_pointer.Count - 1];
18+
}
19+
}
20+
21+
public BehaviorTreeBuilder (GameObject owner) {
22+
_tree = new BehaviorTree(owner);
23+
_pointer.Add(_tree.Root);
24+
}
25+
26+
public BehaviorTreeBuilder Sequence (string name) {
27+
var sequence = new Sequence { Name = name };
28+
_tree.AddNode(Pointer, sequence);
29+
_pointer.Add(sequence);
30+
31+
return this;
32+
}
33+
34+
public BehaviorTreeBuilder Do (string name, Func<TaskStatus> action) {
35+
_tree.AddNode(Pointer, new ActionGeneric {
36+
Name = name,
37+
updateLogic = action
38+
});
39+
40+
return this;
41+
}
42+
43+
public BehaviorTreeBuilder End () {
44+
_pointer.RemoveAt(_pointer.Count - 1);
45+
46+
return this;
47+
}
48+
49+
public BehaviorTree Build () {
50+
return _tree;
51+
}
52+
}
53+
}

Assets/FluidBehaviorTree/Scripts/BehaviorTree/BehaviorTreeBuilder.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
using Adnc.FluidBT.TaskParents.Composites;
2+
using Adnc.FluidBT.Tasks;
3+
using NUnit.Framework;
4+
5+
namespace Adnc.FluidBT.Trees.Testing {
6+
public class BehaviorTreeBuilderTest {
7+
public class SequenceMethod {
8+
private int _invokeCount;
9+
private BehaviorTreeBuilder _builder;
10+
11+
[SetUp]
12+
public void BeforeEach () {
13+
_invokeCount = 0;
14+
_builder = new BehaviorTreeBuilder(null);
15+
}
16+
17+
[Test]
18+
public void Create_a_sequence () {
19+
var tree = _builder
20+
.Sequence("sequence")
21+
.Do("action", () => {
22+
_invokeCount++;
23+
return TaskStatus.Success;
24+
})
25+
.Build();
26+
27+
var sequence = tree.Root.Children[0] as Sequence;
28+
29+
Assert.AreEqual(tree.Root.Children.Count, 1);
30+
Assert.AreEqual(sequence.Children.Count, 1);
31+
Assert.AreEqual(TaskStatus.Success, tree.Tick());
32+
Assert.AreEqual(1, _invokeCount);
33+
}
34+
35+
[Test]
36+
public void Create_a_nested_sequence () {
37+
var tree = _builder
38+
.Sequence("sequence")
39+
.Do("action", () => {
40+
_invokeCount++;
41+
return TaskStatus.Success;
42+
})
43+
.Sequence("nested")
44+
.Do("actionNested", () => {
45+
_invokeCount++;
46+
return TaskStatus.Success;
47+
})
48+
.Build();
49+
50+
var sequence = tree.Root.Children[0] as Sequence;
51+
Assert.AreEqual(2, sequence.Children.Count);
52+
53+
var nested = sequence.Children[1] as Sequence;
54+
Assert.AreEqual(nested.Children.Count, 1);
55+
Assert.AreEqual(TaskStatus.Success, tree.Tick());
56+
Assert.AreEqual(2, _invokeCount);
57+
}
58+
59+
[Test]
60+
public void Create_a_nested_sequence_then_add_an_action_to_the_parent () {
61+
var tree = _builder
62+
.Sequence("sequence")
63+
.Do("action", () => {
64+
_invokeCount++;
65+
return TaskStatus.Success;
66+
})
67+
.Sequence("nested")
68+
.Do("actionNested", () => {
69+
_invokeCount++;
70+
return TaskStatus.Success;
71+
})
72+
.End()
73+
.Do("lastAction", () => {
74+
_invokeCount++;
75+
return TaskStatus.Success;
76+
})
77+
.Build();
78+
79+
var sequence = tree.Root.Children[0] as Sequence;
80+
Assert.AreEqual(3, sequence.Children.Count);
81+
82+
var nested = sequence.Children[1] as Sequence;
83+
Assert.AreEqual(nested.Children.Count, 1);
84+
Assert.AreEqual(TaskStatus.Success, tree.Tick());
85+
Assert.AreEqual(3, _invokeCount);
86+
}
87+
88+
[Test]
89+
public void Create_two_nested_sequences_with_actions () {
90+
var tree = _builder
91+
.Sequence("sequence")
92+
.Sequence("nested")
93+
.Do("actionNested", () => {
94+
_invokeCount++;
95+
return TaskStatus.Success;
96+
})
97+
.End()
98+
.Sequence("nested")
99+
.Do("actionNested", () => {
100+
_invokeCount++;
101+
return TaskStatus.Success;
102+
})
103+
.Build();
104+
105+
var sequence = tree.Root.Children[0] as Sequence;
106+
Assert.AreEqual(2, sequence.Children.Count);
107+
108+
var nested = sequence.Children[0] as Sequence;
109+
Assert.AreEqual(nested.Children.Count, 1);
110+
111+
var nestedAlt = sequence.Children[1] as Sequence;
112+
Assert.AreEqual(nestedAlt.Children.Count, 1);
113+
114+
Assert.AreEqual(TaskStatus.Success, tree.Tick());
115+
Assert.AreEqual(2, _invokeCount);
116+
}
117+
}
118+
}
119+
}

Assets/FluidBehaviorTree/Scripts/BehaviorTree/Editor/BehaviorTreeBuilderTest.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/FluidBehaviorTree/Scripts/Decorators/DecoratorBase.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ public abstract class DecoratorBase : ITask {
77
public ITask child;
88

99
private bool _enabled = true;
10+
public string Name { get; set; }
11+
1012
public bool Enabled {
1113
get { return child != null && child.Enabled && _enabled; }
1214
set { _enabled = value; }

Assets/FluidBehaviorTree/Scripts/TaskParents/TaskParentBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public abstract class TaskParentBase : ITaskParent {
88
public BehaviorTree ParentTree { get; set; }
99
public TaskStatus LastStatus { get; private set; }
1010

11+
public string Name { get; set; }
1112
public bool Enabled { get; set; } = true;
1213

1314
public List<ITask> Children { get; } = new List<ITask>();

Assets/FluidBehaviorTree/Scripts/Tasks/ITask.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
namespace Adnc.FluidBT.Tasks {
55
public interface ITask {
6+
/// <summary>
7+
/// Used for debugging and identification purposes
8+
/// </summary>
9+
string Name { get; set; }
10+
611
/// <summary>
712
/// Is this task enabled or not? Disabled tasks are excluded from the runtime
813
/// </summary>

Assets/FluidBehaviorTree/Scripts/Tasks/TaskBase.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ public abstract class TaskBase : ITask {
77
private bool _start;
88
private bool _exit;
99
private int _lastTickCount;
10-
10+
11+
public string Name { get; set; }
1112
public bool Enabled { get; set; } = true;
1213
public GameObject Owner { get; set; }
1314
public BehaviorTree ParentTree { get; set; }

0 commit comments

Comments
 (0)