Skip to content

Commit 1729dc5

Browse files
committed
Wrote a tutorial on creating custom nodes
1 parent 1e4acf6 commit 1729dc5

File tree

2 files changed

+144
-8
lines changed

2 files changed

+144
-8
lines changed

Assets/FluidBehaviorTree/Scripts/Tasks/TaskBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private void Init () {
7878
}
7979

8080
/// <summary>
81-
/// Run the first time this node is run or after a hard reset
81+
/// Triggers the first time this node is run or after a hard reset
8282
/// </summary>
8383
protected virtual void OnInit () {
8484
}

README.md

Lines changed: 143 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# fluid-behavior-tree
22

3+
@TODO Make sure copy / paste examples work correctly (custom node tutorial, quick start snippet).
4+
35
A pure code behavior tree micro-framework built for Unity3D projects.
46
Granting developers the power to dictate their GUI presentation.
57
Inspired by Fluent Behavior Tree.
@@ -28,6 +30,9 @@ Grab the latest `*.unitypackage` from the [releases page](https://github.com/ash
2830
When creating trees you'll need to store them in a variable to properly cache all the necessary data.
2931

3032
```C#
33+
using Adnc.FluidBT.Trees;
34+
using UnityEngine;
35+
3136
public class MyCustomAi : MonoBehaviour {
3237
private BehaviorTree _tree;
3338

@@ -137,6 +142,9 @@ Randomly evaluate a node as true or false based upon the passed chance.
137142

138143
Runs each child node in order and expects a *Success* status to tick the next node. If *Failure* is returned, the sequence will stop executing child nodes and return *Failure* to the parent.
139144

145+
**NOTE** It's important that every composite is followed by a `.End()` statement. This makes sure that your nodes
146+
are properly nested when the tree is built.
147+
140148
```C#
141149
.Sequence()
142150
.Do(() => { return TaskStatus.Success; })
@@ -187,7 +195,8 @@ extremely powerful and a great compliment to actions, conditions, and composites
187195

188196
You can wrap any node with your own custom decorator code. This allows you to customize re-usable functionality.
189197

190-
**NOTE**: You must manually call `Update()` on the child node or it will not fire.
198+
**NOTE**: You must manually call `Update()` on the child node or it will not fire. Also every decorator must be followed
199+
by a `.End()` statement. Otherwise the tree will not build correctly.
191200

192201
```C#
193202
.Sequence()
@@ -240,20 +249,147 @@ Does not change `TaskStatus.Continue`.
240249
.End()
241250
```
242251

243-
## Creating custom re-usable nodes
252+
## Creating Reusable Behavior Trees
244253

245-
### Actions
254+
@TODO Document splicing with an example
246255

247-
### Conditions
256+
## Creating Custom Reusable Nodes
248257

249-
### Composites
258+
What makes Fluid Behavior Tree so powerful is the ability to write your own nodes and extend the tree builder to inject custom parameters. For example we can write a new tree builder method like this that sets the target of your AI system.
250259

251-
### Decorators
260+
```C#
261+
var tree = new TreeBuilderCustom(gameObject)
262+
.Sequence()
263+
.AgentDestination("Find Enemy", target)
264+
.Do(() => {
265+
// Activate chase enemy code
266+
return TaskStatus.Success;
267+
})
268+
.End()
269+
.Build();
270+
```
271+
272+
We'll cover how to build this in the next section **Actions**. It should take about 10 minutes to setup your first custom
273+
action and extend the pre-existing Behavior Tree Builder.
274+
275+
### Your First Custom Node and Tree
276+
277+
Creating the custom action code is quite simple. Below you'll find a complete overview of additional
278+
methods supported by a custom action.
279+
280+
```C#
281+
using Adnc.FluidBT.Tasks;
282+
using UnityEngine;
283+
using UnityEngine.AI;
284+
285+
public class AgentDestination : ActionBase {
286+
public NavMeshAgent agent;
287+
public Transform target;
288+
289+
protected override void OnInit () {
290+
agent = Owner.GetComponent<NavMeshAgent>();
291+
}
292+
293+
protected override TaskStatus OnUpdate () {
294+
agent.SetDestination(target.position);
295+
return TaskStatus.Success;
296+
}
297+
}
298+
```
299+
300+
New method added to the builder script. This is pretty simple and easy to customize since most of the overhead is
301+
abstracted away.
302+
303+
```C#
304+
using Adnc.FluidBT.Trees;
305+
306+
public class TreeBuilderCustom : BehaviorTreeBuilderBase<TreeBuilderCustom> {
307+
// This is always required for class extension reasons (will error without)
308+
public TreeBuilderCustom (GameObject owner) : base(owner) {
309+
}
310+
311+
public TreeBuilderCustom AgentDestination (Transform target) {
312+
_tree.AddNode(Pointer, new AgentDestination {
313+
Name = "Agent Destination",
314+
target = target
315+
});
316+
317+
return this;
318+
}
319+
}
320+
```
321+
322+
Be sure when you create trees that you use your new `TreeBuilderCustom` class. For example:
323+
324+
```C#
325+
_tree = new TreeBuilderCustom(gameObject)
326+
.Sequence()
327+
.AgentDestination("Find Target", target)
328+
...
329+
.End()
330+
.Build();
331+
```
332+
333+
And you're done! You've now created a custom action and extendable Behavior Tree Builder. The following examples
334+
will be more of the same. But each covers a different node type.
335+
336+
### Custom Actions
337+
338+
Custom action example template.
339+
340+
```C#
341+
using UnityEngine;
342+
using Adnc.FluidBT.Tasks;
343+
344+
public class CustomAction : ActionBase {
345+
// Triggers only the first time this node is run (great for caching data)
346+
protected override void OnInit () {
347+
}
348+
349+
// Triggers every time this node starts running. Does not trigger if TaskStatus.Continue was last returned by this node
350+
protected override void OnStart () {
351+
}
352+
353+
// Triggers every time `Tick()` is called on the tree and this node is run
354+
protected override TaskStatus OnUpdate () {
355+
// Points to the GameObject of whoever owns the Behavior Tree
356+
Debug.Log(Owner.name);
357+
return TaskStatus.Success;
358+
}
359+
360+
// Triggers whenever this node exits after running
361+
protected override void OnExit () {
362+
}
363+
}
364+
```
365+
366+
Code required to modify your tree builder.
367+
368+
```C#
369+
using Adnc.FluidBT.Trees;
370+
371+
public class TreeBuilderCustom : BehaviorTreeBuilderBase<TreeBuilderCustom> {
372+
...
373+
public TreeBuilderCustom CustomAction (string name) {
374+
_tree.AddNode(Pointer, new CustomAction {
375+
Name = name
376+
});
377+
378+
return this;
379+
}
380+
}
381+
```
382+
383+
### Custom Conditions
384+
385+
### Custom Composites
386+
387+
### Custom Decorators
252388

253389
## Submitting your own actions, conditions, ect
254390

255391
Please fill out the following details if you'd like to contribute new code to this project.
256392

257393
1. Clone this project for the core code with tests
258394
2. Make sure your new code is reasonably tested to demonstrate it works (see `*Test.cs` files)
259-
3. Submit a PR
395+
3. Submit a pull request to the `develop` branch

0 commit comments

Comments
 (0)